2009-12-22 6 views
0

-je utiliser NetBeans 6.8 et ont MAMP avec cette config sur mon mac:Pourquoi ces instructions préparées ne fonctionnent-elles pas?

Apache 2.0.63 
MySQL 5.1.37 
PHP 4.4.9 & 5.2.10 
APC 3.0.19 & APC 3.1.2 
eAccelerator 0.9.5.3 
XCache 1.2.2 
phpMyAdmin 2.11.9.5 & phpMyAdmin 3.2.0.1 
Zend Optimizer 3.3.3 
SQLiteManager 1.2.0 
Freetype 2.3.9 
t1lib 5.1.2 
curl 7.19.5 
jpeg 7 
libpng-1.2.38 
gd 2.0.34 
libxml 2.7.3 
libxslt 1.1.24 
gettext 0.17 
libidn 1.15 
iconv 1.13 
mcrypt 2.5.8 
YAZ 3.0.47 & PHP/YAZ 1.0.14 

Mon AOP pilote pour MySQL est la version de la bibliothèque cliente 5.1.37

J'essaie d'utiliser des déclarations préparées ici.

Cela fonctionne parfaitement sans instructions préparées:

try { 
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root'); 
    $prepared = $dbh->prepare('SELECT * from sys_navigation_point WHERE name="root"'); 
    //$prepared->bindParam('foo', 'root'); 

    $prepared->execute(); 

    foreach($prepared as $row) { 
     print_r($row); 
    } 
    $dbh = null; 
} catch (PDOException $e) { 
    print "Error!: " . $e->getMessage() . "<br/>"; 
    die(); 
} 

Mais cela ne fonctionne pas du tout avec une déclaration préparée. Obtention d'une page totalement vide en procédant ainsi:

try { 
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root'); 
    $prepared = $dbh->prepare('SELECT * from sys_navigation_point WHERE name=:foo'); 
    $prepared->bindParam('foo', 'root'); 

    $prepared->execute(); 

    foreach($prepared as $row) { 
     print_r($row); 
    } 
    $dbh = null; 
} catch (PDOException $e) { 
    print "Error!: " . $e->getMessage() . "<br/>"; 
    die(); 
} 

foo doit être remplacé par root. Cependant, ce n'est pas le cas. Ok, alors essayons cela, qui ne fonctionne pas du tout:

try { 
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root'); 
    $prepared = $dbh->prepare('SELECT * from sys_navigation_point WHERE name=?'); 
    $prepared->bindParam(1, 'root'); 

    $prepared->execute(); 

    foreach($prepared as $row) { 
     print_r($row); 
    } 
    $dbh = null; 
} catch (PDOException $e) { 
    print "Error!: " . $e->getMessage() . "<br/>"; 
    die(); 
} 

Absolument rien. Je n'ai même pas de message d'erreur. Juste une page blanche. Après ce code, il y a de l'écho avec une sortie HTML standard. Il ne disparaît pas, donc le script s'arrête quelque part près de l'appel à la méthode bindParam.

Encore une fois, celui-ci fonctionne parfaitement bien, sans aucune déclaration préparée:

try { 
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root'); 
    $prepared = $dbh->prepare('SELECT * from sys_navigation_point WHERE name="root"'); 
    //$prepared->bindParam('foo', 'root'); 

    $prepared->execute(); 

    foreach($prepared as $row) { 
     print_r($row); 
    } 
    $dbh = null; 
} catch (PDOException $e) { 
    print "Error!: " . $e->getMessage() . "<br/>"; 
    die(); 
} 

Comme vous pouvez le voir, de toute évidence toutes les versions sont exactement la même requête. Avec PS ne fonctionne pas. Sans PS, c'est le cas. Maintenant, j'ai trouvé un bug brutal dans PHP lui-même?

Est-il possible que les instructions préparées soient désactivées quelque part?

Répondre

2

Le nom de liaison est :foo - pas foo. Et vous ne devriez pas utiliser bindParam, mais bindValue, puisque vous ne donnez pas une variable comme argument. Par exemple. :

$prepared->bindValue(':foo', 'root'); 

En général, je recommande que vous ne utilisation bindParam, car il a une sémantique de référence et peut donc créer quelques erreurs vraiment difficiles à repérer.

+0

+1 La lecture du manuel est sous-estimée. –

+0

En toute équité, le côlon est facile à manquer. – troelskn

+0

J'ai eu la chance de suivre DEUX tutoriels qui n'incluent pas ce deux-points dans la méthode bind. OH MAN! Merci! – openfrog

3

Vous utilisez ce type de code:

$prepared->bindParam('foo', 'root'); 

Mais bindParam attend un comme second paramètre variable :

bool PDOStatement::bindParam (mixed $parameter , 
    mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length 
    [, mixed $driver_options ]]]) 


Ici, vous devriez probablement utiliser bindValue, comme vous seulement vouloir lier une ... valeur ...et non une variable passée par référence à la requête SQL:

bool PDOStatement::bindValue (mixed $parameter , mixed $value 
    [, int $data_type = PDO::PARAM_STR ]) 

Ainsi, votre code ressemblerait à ceci:

$prepared->bindValue(':foo', 'root'); 

(Ne pas oublier le ':' avant le nom param, btw ;-))

+0

Bonne explication. Donc les deux choses étaient fausses. Le deux-points manquant et la mauvaise méthode. – openfrog

+0

Merci :-) Eh bien, deux problèmes résolus en un seul coup; ce n'est pas mauvais pour une seule question, n'est-ce pas? –

Questions connexes