9
votes

Incrément sur "__Tostring"

Je ne suis pas sûr de ce que le titre doit être, mais le code doit l'expliquer mieux: xxx

sortie: xxx tout Idée pourquoi j'ai eu 20 au lieu de 21 ? Même alors le code ci-dessous fonctionne: xxx

je sais groupe est un objet qui implémente __ tostring , je m'attendais à ++ Pour fonctionner avec la chaîne de __ tostring ou au moins lancer une erreur


5 commentaires

PHP offre-t-il un moyen de surcharger les opérateurs incréments? Étant donné que votre classe ne convient pas facilement à un type de numéro, vous devez probablement dire à PHP ce que vous voulez ++.


Si vous déclarez $ Numéro non privé dans la classe de groupe, puis essayez echo ++ $ numéro-> numéro, php_eol; travaux?


Nope .. mais cela était incrémenté sur la chaîne et même si sinon ... je devrais avoir une erreur


Préfixe ops comme ++ travail sur les variables. Mais $ numéro est une expression dans le cas 1, pas une variable`


@Mario, alors il devrait être traité comme un bug ... Je devrais au moins obtenir un avertissement ou un remarquez comme si vous essayez d'utiliser int avec __ tostring


5 Réponses :


9
votes

Pour répondre à votre question avec un peu de code.

$number = new Group();
echo 1 + "$number"; // 21
  • Vous ne pouvez faire aucune opération entière sur un objet, que votre code ne fait pas ce que vous attendez. La méthode __ TOSTRING CODE> sera appelée très tard, lorsque la sortie acutale sera calculée, après avoir essayé sans succès de faire une opération mathématique avec elle. Li>
  • Vous pouvez en mathématiques avec des cordes, car php en interne les convertit à des chiffres li>
  • évidemment, vous pouvez faire des maths avec entier li> ul>

    bonus: strong> p>

    Ceci fonctionnera: p>

    $number = new Group();
    echo gettype($number);
    
    $number = "20";
    echo gettype($number);
    
    $number = 20;
    echo gettype($number);
    


1 commentaires

L'ajout explicitement une à l'expression variable ouvre effectivement la voie à la modification de la quantité ajoutée très facile. Les opérations avant ou après l'incrément doivent être évitées. Vous ne saurez jamais vraiment ce qui va arriver. Douglas Crockford ne les aime pas. - et en php Il est bien plus facile d'utiliser la version courte $ i + = 1 ^ au lieu de $ i ++ - un seul caractère supplémentaire. Et essayez d'incrémenter par 2 ... :)



2
votes

Je pense que cela pourrait être plus clair avec simplement changer les noms des variables comme ceci:

class Group {
    private $number = 20;

    public function __toString() {
        return "$this->number";
    }
}

$group = new Group();
echo $group;//print 20 as per your __toString function

++ $group;


0 commentaires

12
votes

L'ordre dans lequel les opérations sont importantes:

  1. La variable sera extraite en tant qu'objet, elle ne sera pas couplée à un entier (ou autre chose).

  2. Ce ++ Incréments de l'opérateur lval (la valeur longue) du zval , mais ne fait normalement rien d'autre. Le pointeur d'objet reste le même. L'incrément_fonction interne (fast_) sera appelé avec le zval qui a un pointeur sur l'objet, qui vérifie d'abord le type d'abord. Si c'est un objet, cela ne fait rien. Donc, lorsque votre zval est un objet, il est aussi utile qu'une opération de non-opération. Cela ne produira aucun avertissement.

  3. Seulement alors l'instruction ECHO effectue une chaîne de coulée sur ses arguments: la méthode __ tostring est appelée et renvoie 20 . .

  4. 20 sera sorti.


0 commentaires

1
votes

Pourquoi ne faites-vous pas seulement:

class Group {
    private $number = 0;
    public function __construct($number = 0){
        $this->number = intval($number);
    }
    public function __toString() {
        return number_format(++$this->number); // pre-increment
    }
}
$g = new Group();
echo $g; // 1
echo $g; // 2


0 commentaires

0
votes

Ceci est en fait plus réalisable que vous ne le pensez peut-être - il suffit de faire un peu plus de coulée de type, comme suit:

<?php

class Group {
private $number = 20;

    public function __toString() {
        return (string) $this->number; // replace "" w/string cast
    }
}

$number = (int)(string) new Group();
echo $number, PHP_EOL;
echo ++$number, PHP_EOL;


0 commentaires