web-dev-qa-db-fra.com

Conversion de MYSQL vers WordPress $ WPDB

Je suis en train de mettre à jour un site WordPress archaïque de la version 3.7 Certaines requêtes SQL qui ne fonctionnent plus après la version 3.9 ou plus doivent maintenant être connectées à la base de données via $ WPDB ( https://codex.wordpress.org/Class_Reference/wpdb ). J'ai commencé par essayer, mais je suis suspendu à la partie mysql_fetch_array et je ne sais pas si ce que j'ai déjà fait est correct. On dirait que mysql_fetch_array doit utiliser get_results ( https://developer.wordpress.org/reference/classes/wpdb/get_results/ ).

Je suis tout à fait conscient du fait que c’est une façon moins qu’idéale d’aborder cela et que je compte tout moderniser, mais il serait très utile de pouvoir résumer ce long récit au sein de ce vieux paradigme désordonné. .

Ci-joint le code d'origine et ensuite ma tentative (également ajouté une tentative v2) . Merci d'avoir jeté un coup d'oeil.

SQL:

$sql = "SELECT wp_acf_values.value FROM wp_acf_values, wp_acf_fields WHERE wp_acf_fields.post_id = '620' AND wp_acf_fields.id = wp_acf_values.field_id ORDER BY wp_acf_fields.order_no"; 
$result = mysql_query($sql) or die('Content was not loaded. Please refresh your page.'); 
$counter = 0; 
while($post = mysql_fetch_array($result)) { 

    $sqlSecond = "SELECT meta_value FROM wp_postmeta WHERE meta_id = '".$post['value']."'"; 
    $result1 = mysql_query($sqlSecond) or die('Content was not loaded.'); 
    while($post1 = mysql_fetch_array($result1)) { 
        $data[$counter] = $post1['meta_value']; 
        $counter++; 
    } 

} 

// get image 
$sql = "SELECT meta_value FROM wp_postmeta WHERE post_id = '".$data['1']."' AND meta_key = '_wp_attached_file'"; 
$result = mysql_query($sql) or die('Content was not loaded.'); 
$counter = 0; 
while($post = mysql_fetch_array($result)) { 
    $imgURL = $post['meta_value']; 
} 

WPDB v1:

global $wpdb;

$sql = $wpdb->prepare( "SELECT wp_acf_values.value FROM wp_acf_values, wp_acf_fields WHERE wp_acf_fields.post_id = '620' AND wp_acf_fields.id = wp_acf_values.field_id ORDER BY wp_acf_fields.order_no" );
$result = $wpdb->query ( $sql ) or die('Content was not loaded.');
$counter = 0;
while($post = mysql_fetch_array($result)) {

    $sqlSecond = $wpdb->prepare( "SELECT meta_value FROM wp_postmeta WHERE meta_id = %s", $post['value'] );
    $result1 = $wpdb->query ( $sqlSecond ) or die('Content was not loaded.');
    while($post1 = mysql_fetch_array($result1)) {
          $data[$counter] = $post1['meta_value'];
          $counter++;
    }

}

// get image
$sql = $wpdb->prepare( "SELECT meta_value FROM wp_postmeta WHERE post_id = %s AND meta_key = '_wp_attached_file'", $data['1'] );
$result = $wpdb->query ( $sql ) or die('Content was not loaded.');
$counter = 0;
while($post = mysql_fetch_array($result)) {
    $imgURL = $post['meta_value'];
}

WPDB v2:

global $wpdb;

$sql = $wpdb->prepare( "SELECT wp_acf_values.value FROM wp_acf_values, wp_acf_fields WHERE wp_acf_fields.post_id = '620' AND wp_acf_fields.id = wp_acf_values.field_id ORDER BY wp_acf_fields.order_no" );
$result = $wpdb->get_results ( $sql ) or die('Content was not loaded.');
$counter = 0;
foreach ($result as $post ) {
  $sqlSecond = $wpdb->prepare( "SELECT meta_value FROM wp_postmeta WHERE meta_id = %s", $post->value );
  $result1 = $wpdb->get_results ( $sqlTitle ) or die('Content was not loaded.');
  foreach ( $result1 as $post1 ) {
     $data[$counter] = $post1->meta_value;
     $counter++;
  }
}

// get image
$sql = $wpdb->prepare( "SELECT meta_value FROM wp_postmeta WHERE post_id = %s AND meta_key = '_wp_attached_file'", $data['1'] );
$result = $wpdb->get_results ( $sql ) or die('Content was not loaded.');
$counter = 0;
foreach ( $result as $post ) {
  $imgURL = $post->meta_value;
  $counter++;
}
1
chef_3072485

Le problème fondamental est l’hypothèse que WordPress traite de fonctions mysql et d'objets mysql et que la connaissance de ces fonctions est utile.

La vérité est qu’il s’agit d’une API complète en soi et que les hypothèses fournies par la connaissance des fonctions mysql_ ne sont ni utiles ni pertinentes au-delà de la syntaxe de SQL.

Par exemple:

$result = $wpdb->query ( $sql ) or die('Content was not loaded.');
$counter = 0;
while($post = mysql_fetch_array($result)) {

Ici, l'hypothèse est que $wpdb->query renvoie un objet de résultat, mais ce n'est pas vrai.

Si nous regardons ce que query renvoie réellement en consultant les exemples de la documentation, nous pouvons voir:

Cette fonction renvoie un entier indiquant le nombre de lignes affectées/sélectionnées.

Et cela:

Si une erreur MySQL est rencontrée, la fonction retournera FALSE. Notez que, étant donné que 0 et FALSE peuvent être renvoyés pour les requêtes de ligne, vous devez être prudent lors de la vérification de la valeur de retour.

Alors, comment puis-je récupérer des rangées?

Utiliser get_results:

$myrows = $wpdb->get_results( "SELECT id, name FROM mytable" );

N'oubliez pas d'exécuter votre instruction SQL d'abord avec $wpdb->prepare pour éviter les attaques par injection!

Il existe d'autres méthodes qui vous permettent d'extraire une valeur, une ligne ou une colonne singulière, mais ici, $myrows est littéralement un tableau avec les lignes sélectionnées (ou une réponse d'erreur). Il existe un deuxième paramètre à get_results qui détermine le type de retour, par exemple. un tableau associatif, un objet avec des clés, etc.

https://codex.wordpress.org/Class_Reference/wpdb#SELECT_Generic_Results

Le problème de vos deuxième et troisième requêtes

Même si vous corrigez ces requêtes, elles sont fondamentalement une mauvaise pratique, car leur remplacement est plus rapide et trivial:

$value = get_post_meta( $post_id, 'key' );

$value contient maintenant toutes les méta-valeurs de cette publication avec la clé méta key.

Vous pouvez également utiliser WP_Query pour récupérer des publications via leurs clés méta et leurs valeurs (attention, ceci est un péché capital pour les performances, que vous utilisiez l'API ou un code SQL direct)

Il existe probablement une fonction ou une API ACF pouvant remplacer la requête SQL directe au début. Il est très rare que vous ayez besoin de faire une requête SQL directe. Dans mon travail quotidien, j'examine le code des principaux sites Web traitant des milliards de pages vues et des millions de lignes de code, parmi lesquelles j'ai rencontré peu de fois des requêtes SQL directes.

2
Tom J Nowell