instanceof et If

Mammouth du PHP | 684 Messages

08 août 2006, 10:42

Salut.
Je voudrais avoir un avis sur la question suivante et le code :
<?php
class Test
{
    public $unevar;

    public function monTest()
    {
        echo 'Je suis dans monTest()<br />';
    }
}

$myvar = null;

if ($myvar->monTest() && $myvar instanceof Test) {
    echo 'Je suis bien un objet Test.<br />';
}
else {
    echo 'Je ne suis pas un objet Test.<br />';
}
?>
Dans ce cas, le php me retourne bien une erreur qui est la suivante .

Code : Tout sélectionner

Fatal error: Call to a member function monTest() on a non-object in /var/www/html/test/test-instanceof.php on line 14
Ceci me paraît être normal car PHP doit certainement évaluer dans l'ordre les conditions. D'ailleur j'aurais été très surpris si je n'avais pas eut de message d'erreur concernant l'objet non initialisé.

Par contre si on inverse la condition, le message d'erreur disparaît et le test passe dans le "echo 'Je ne suis pas un objet Test.<br />'".
if ($myvar instanceof Test && $myvar->monTest()) {
Je me demande pourquoi l'objet n'est pas évaluer comme n'étant pas créé et qu'il n'y a pas de message d'erreur ?

Quelqu'un pour une petite explication ?
Merci.
Zigz4g

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

08 août 2006, 10:46

En fait, PHP évalue les arguments du if de gauche à droite et stoppe le test dès qu'il est sûr du résultat du test.

Par exemple, dans ton cas, tu as un AND dans ton if. Si le 1er postulat est faux, la condition complete est forcément fausse. PHP ne teste donc pas le 2nd postulat et détermine que le résultat est faux => pas d'erreur ;)

Je me sers énormément de cette facette de PHP lors de mes vérifications de formulaires :
if (isset($_POST['toto']) && $_POST['toto'] == 'on')
De manière similaire, lorsque tu as un OR dans un IF, si le 1er postulat est vrai, l'expression est forcément vrai ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Mammouth du PHP | 684 Messages

08 août 2006, 10:53

En gros tu me dis que pour gagner des lignes de codes, c'est une bonne technique ?
Est-ce identique dans d'autres langages de POO ? Car je ne me rappel pas de cette astuce dans le C++.
Est-ce vraiment sécurisé ?
Si demain PHP change d'avis sur cette façon de tester les postulats, tes codes ne fonctionneront plus (OK faudrait vraiment que demain php veuille mettre un gros bordel dans le monde :lol: ).
Zigz4g

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

08 août 2006, 10:56

Je pense surtout que je gagne en lisibilité dans le code puisque que je diminue les test imbriqués ;)

Et je ne pense pas que PHP se sépare de cette manière de faire, justement parce qu'ils ont toujours fait comme ça et qu'ils risqueraient de perdre pas mal de développeur en changeant de manière de faire.

De plus, il n'est pas très conseillé de changer la version de PHP sur laquelle tourne un script qui tourne parfaitement.

Pour la comparaison entre les langages, chaque langage à ses spécificités mais il me semblait que le C++ le faisait :-k
A vérifier ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Mammouth du PHP | 684 Messages

08 août 2006, 11:03

Merci pour cette explication très détaillée et bien décrite.
Je pense que j'utiliserais cette fonctionnalité par la suite en mettant le doute pour d'autres langages de le faire. Du moins je ferais les tests nécessaires avant, bien sur :).

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

08 août 2006, 11:05

Mais de rien, je suis là pour ça

Est-ce qu'on peut dire que le sujet est [RESOLU] ? Si c'est le cas, pense à tager le sujet ;)

EDIT : j'ai rien dit. Du moins, j'ai posté trop tôt :oops:
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Administrateur PHPfrance
Administrateur PHPfrance | 3131 Messages

08 août 2006, 11:40

C'est vrai dans tous les langages où j'ai eu l'occasion de le tester :
- PHP
- Perl
- Python
- C
- C++
- Java
- Delphi
- Ruby
- Javascript
- dernièrement, Lua ( je me fais des extensions pour intégrer SVN à mon SciTe :langue: )

À partir de là j'en déduis qu'on peut généraliser ce genre de tests ;)

En effet il est vital pour un interpréteur ou un compilateur de générer des applications rapides. Comme VRAI OU ... est toujours VRAI, et que FAUX ET ... est toujours FAUX, aucun interpréteur ne va s'amuser à calculer tous les tests (dont certains peuvent être extrèmement coûteux) mais les effectuer dans l'ordre donné par les opérateurs :)
Un langage dont l'outil de compilation ou d'interprétation ne respecte pas ça ne mérite pas qu'on s'y attarde car ça signifie qu'aucun effort d'optimisation n'a été fait :(

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

08 août 2006, 12:06

Ce qui m'ammene à dire qu'un bon développeur est un développeur qui prend en compte ces détails afin d'optimiser son code ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer