note 108690 deleted from language.operators.comparison by cmb

From: Date: Sun, 11 Aug 2019 11:59:38 +0000
Subject: note 108690 deleted from language.operators.comparison by cmb
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-211849@lists.php.net to get a copy of this message
Note Submitter: wbcarts at juno dot com ---- COMPARING PHP OBJECTS (compound type) We have seen that PHP does a lot of type-juggling on its own -- which can wreak havoc in unexpected ways -- but it is still up to us to produce code that is clear, maintainable AND follows the rules we want to follow. When creating a PHP Object, it is sometimes unclear what makes two of them the same. But the good part is that we can say what is equal and what is not equal. For example, let's say we have a Student class that includes an equals() method which defines what is equal for this type of object. <?php #Student.php class Student { /* * These variables are protected to prevent outside code * from tampering with them. */ protected $student_id; protected $student_name; public function __construct($id, $name) { $this->student_id = (int)$id; // cast to integer here $this->student_name = (string)$name; // cast to string here } /* * This function requires an instance of type Student and * only evaluates two integers that we set in __construct(). */ public function equals(Student $student) { return ($this->getId() == $student->getId()); } public function getId() { return $this->student_id; } public function getName() { return $this->student_name; } public function __toString() { return 'Student [id=' . $this->getId() . ', name=' . $this->getName() . ']'; } } ?> With this class, the protected variables cannot be tampered with by outside code. Also, the __construct() function casts the variables to the PHP primitives WE WANT, while the equals(Student $student) function, requires an argument of type Student -- which eliminates the need for an IDENTITY '===' check AND prevents any other data types from coming in. One other note: notice how the equals() function only evaluates the $student_id, this allows for two students to have the same name -- which is totally possible. Here's a short example -- we'll do it correctly AND try to screw it up! <?php require('Student.php'); $s1 = new Student(122, 'John Doe'); $s2 = new Student(344, 'John Doe'); echo $s1 . '<br>'; // Student [id=122, name=John Doe] echo $s2 . '<br>'; // Student [id=344, name=John Doe] # Check for equality the CORRECT way... echo ($s1->equals($s2) ? 'EQUAL' : 'NOT EQUAL'); // NOT EQUAL # Check for equality by HACKING the known value of $student_id... echo ($s1->equals(122) ? 'EQUAL' : 'NOT EQUAL'); // Catchable fatal error: Argument 1 passed to Student::equals() must be an instance of Student, integer given... etc, etc. ?> See what I mean by writing code that follows OUR RULES? The Student class does the kind of type-juggling we want (and when we want it done) -- NOT when, where, or why PHP does it (not that there's anything wrong with it).

« previous php.notes (#211849) next »