This is the 12th day of my participation in the More text Challenge. For details, see more text Challenge

Secrets of objects

This article explains how to create objects in PHP, how to compare objects, how to assign values to objects, how to copy objects, how to type objects, how to call each other, and how to use the Instanceof operator. Using good objects makes our program more concise.

N ways to create an object

new

$obj= new MyClass{}; // Create an object for MyClass{};

$obj1= new stdClass(); // Create a built-in class object;

$ob2=new class{}; // Create an anonymous class object;

We’ve seen a lot of examples of how to create new methods outside of a class. Here’s an example of an anonymous class + chained call:

class Outer { private $attr = 1; protected $attr2 = 2; protected function func1() { return 3; } public function func2() {return new class($this->attr) extends Outer {private $attr3; public function __construct($attr) { $this->attr3 = $attr; } public function func3() { return $this->attr2 + $this->attr3 + $this->func1(); }}; } } echo (new Outer)->func2()->func3(); / / 6Copy the code

Here are the key points of this example:

  1. A chained call is executed from left to right; Create a parent object and call func2();

  2. The func2() method creates a new anonymous subclass object and initializes $attr3. It’s important that $this refers to a subclass object instead of a superclass object.

  3. With a subclass object call, the superclass func3() can be called normally, completing the chained call, and executing the method body.

New is paired with pronouns to instantiate the specified class. Here’s an example:

class ParentClass { function creatObjParent() { echo ' new self:'; return new self; }} Class Son extends ParentClass {function creatObjSon() {echo 'new parent:'; return new parent; } class Grandson extends Son {function creatObjGrandson() {echo 'new static:';} class Grandson extends Son {function creatObjGrandson() {echo' new static:'; return new static; $aaa= new Grandson();}} $aaa= new Grandson(); echo get_class($aaa->creatObjGrandson()); //new static:Grandson echo get_class($aaa->creatObjSon()); //new parent:ParentClass echo get_class($aaa->creatObjParent()); //new self:ParentClassCopy the code

Static Creates an object with a static method

Static methods can be called by class names and objects to create new objects:

class Store {
    static function creatobj()
    {
        return new static;
    }
}

$b=Store::creatobj();  
var_dump($b);  //object(Store)#8 (0) { }
Copy the code

Some other uses of new

With an object, create a new object;

class NewClass{}; $a= new NewClass(); $b= new $a; // Create a new object by pairing it with an object; var_dump($a==$b); Var_dump ($a===$b); //false refers to different instances, not identicalCopy the code

Use a string to refer to the class name:

class NewClass{};
$a= 'NewClass';
$b= new $a;
var_dump($b);
Copy the code

Here is a supplementary comparison between objects:

When using the comparison operator (==) to compare two object variables, the rule of comparison is that if the properties and property values of the two objects are equal, and the two objects are instances of the same class, then the two object variables are equal.

If you use the congruence operator (===), the two object variables must point to the same instance of the class (that is, the same object).

4. Object Conversion (Object)

We can also convert other types of data, such as strings, numbers, or arrays, into objects. Just add (object) before the object being transformed.

String to object:

$a= 'NewClass';
$ob=(object)$a;
var_dump($ob);   //object(stdClass)#6 (1) {["scalar"]=>string(8) "NewClass"}
Copy the code

You can see that it has created a built-in class, stdClass, with the string as the value of the ‘Scalar’ property; This process also works with numbers, so you can test it locally.

Array to object:

$a = [1, 2, 3, [1, 2, 3], 'one' = > 123, 'two' = > 321]. $ob=(object)$a; print_r($ob); //output: stdClass Object ( [0] => 1 [1] => 2 [2] => 3 [3] => Array ( [0] => 1 [1] => 2 [2] => 3 ) [one] => 123 [two] => 321 )Copy the code

As you can see, a built-in class, stdClass, is also created, with key as the property name, value as the property value, and, in the case of multidimensional arrays, the second two-dimensional array as the value of a property. You can also specify the attribute name by specifying the key value. You can see that turning arrays into objects is a very quick way to create objects;

One thing to note when converting to an array is that attribute names start with a letter or underscore, followed by any number of letters, numbers, or underscores. If the attribute name does not conform to the rule, the attribute cannot be accessed.

2. Assignments and references to objects

We can create an object by assigning a value to another variable, or by establishing a reference between two objects:

class Myclass{}; $a=new MyClass; $b=$a; $c=&$a; $d=new MyClass; echo (int)($b===$a); Echo (int)($c===$a); Print_r ($c===$b); $c== $b); //1, $c, $b; var_dump($d==$a); Var_dump ($d===$a); $a->{'test'}=5; $a->{'test'}=5; Print_r ($b); //Myclass Object ( [test] => 5 ) Print_r($c); //Myclass Object ( [test] => 5 ) $a=5; var_dump($c); //int(5) var_dump($b); //object(Myclass)#11 (1) { ["test"]=> int(5) }Copy the code

From the example above, we can see a few principles about reference and assignment:

  1. Whether it’s a direct assignment or a reference, both sides of the equal sign point to the same instance. When a property of one object changes, the other two objects change synchronously

  2. Two objects belonging to the same class are equal, but not congruent. Only two variables that refer to the same object are congruent.

  3. When one of the referenced variables a changes, the other variable a changes, and the other variable a changes, the other variable C also changes synchronously, but does not affect the ordinary assigned variable $b.

About how objects in PHP are stored, similar to Pointers:

Instead of holding the entire object’s value, an object variable holds an identifier to access the actual object’s contents. When an object is passed as a parameter/returned as a result/or assigned to another variable, the other variable is not a reference to the original, but they both hold a copy of the same identifier that points to the actual contents of the same object.

Graph TD variable $a --> identifier --> object data variable $b --> identifier

This is why unset($a) does not affect $b, but changing $a affects $b.

When we assign an instantiated object to a variable $a=new Myclass(), we actually establish a relationship between the variable and the identifier.

With that in mind, let’s look at the following example:

class ABB {
    public $foo = 1;
}

class BBB {
    public function foo(ABB $a)
    {
        $a->foo = 42;
    }

    public function bar(ABB $b)
    {
        $b = new ABB;
    }
}

$f = new ABB;
$g = new BBB;
echo $f->foo . "\n";

$g->foo($f);
echo $f->foo . "\n";

$g->bar($f);
echo $f->foo . "\n";
Copy the code

I expected it to be 1, 42, 1, but it was 1, 42, 42. He cracked his face. Why is that?

Function bar($b $b) = function bar($b $b) = function bar($b $b) = function bar($b $b) = function bar($b $b $b) = function bar($b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $b $f->foo is still 42. If we want this new logo to work, we need to add the reference symbol “&” instead of function bar(ABB &$b);

$f->foo ($f); $f->foo ($f); $f->foo ($f);

Clone Object replication

In PHP, we can also create new objects by using the keyword clone. What’s the difference between clone and just ‘=’?

class NewClass{}; $a=new NewClass(); var_dump($a); //object(NewClass)#6 (0) { } $b = clone $a; $a var_dump($b); $a var_dump($b); //object(NewClass)#8 (0) { } $c = $a; var_dump($c===$a); //True var_dump($b===$a); //False, the two points to different objectsCopy the code

From the above example, you can see that the clone object is a new instance, is an independent individual, pointing to another set of independent object data. Even if A is changed in the later period, it will not affect A, A or B, unless they have internal reference relationship.

In addition, Clone can also call the magic method __clone(). Unlike other magic methods, __clone() cannot be called directly, only automatically by the clone keyword. It does not contain any parameters.

When __clone() is not defined in a class, a new instance of the same class is created and its properties and methods are copied.

Let’s see how __clone() works with an example:

class Clonetest
{
    public $objs = 0;
    public $clones;

    public function __construct() {
        return ++$this->objs;
    }

    public function __clone() {
        return ++$this->clones;
    }
}

$obj = new Clonetest();
$obj2 = clone $obj;
print_r($obj);  //Clonetest Object( [objs] => 1  [clones] =>  )
print_r($obj2); //Clonetest Object( [objs] => 1  [clones] => 1)
Copy the code

You can see $obj2-> Clones changed to 1, and the system automatically executes the magic method.

If there is a reference in the original object, all the reference properties will still be a reference to the original variable.

class lkj { protected $var=6; public $ddd; } class ioi { protected $sss; public $asw; } $a=new lkj; $bb=new ioi(); $a->ddd=&$bb; $bb->asw=10; $bb->asw=10; $CCC =clone $a; $CCC =clone $a; $a var_dump($CCC); //output: object(lkj)#14 (2) { ["var":protected]=> int(6) ["ddd"]=> &object(ioi)#6 (2) { ["sss":protected]=> NULL ["asw"]=> int(10) } }Copy the code

You can see that the object property synchronization to which $c-> DDD points has changed.

Calls between objects

Objects of the same class can access each other’s private and protected members even if they are not the same instance. This is because the details of the specific implementation are known inside these objects.

class Foo5 { private $bar; Public function debugBar(Foo5 $object) {echo $object->bar, "\n"; } public function setBar($value) { $this->bar = $value; } public function setForeignBar(Foo5 $object, $value) { $object->bar = $value; } } $a = new Foo5(); $b = new Foo5(); $a->setBar(1); $b->setBar(2); $a->debugBar($b); $b->debugBar($a); $b->debugBar($a); // 1 $a->setForeignBar($b, 3); $a ->setForeignBar($a, 4); $a ->setForeignBar($a, 4); $a->debugBar($b); // 3 $b->debugBar($a); / / 4Copy the code

Instanceof class operator

Instanceof is used to determine whether a PHP variable is an object of a class. Returns true if it is. There are several rules for using it:

If an object is a subclass object, it also belongs to the superclass. However, if it is an instance of the parent class, it is not a child class.

If the object is not of an object type, false is returned and no error message is emitted.

Class names can be strings or objects to refer to, and the system automatically converts them into classes.

Let’s look at an example:

class Test { const CL=10; } class Child extends Test {} $obj1=new Test(); $obj2=new Child(); var_dump($obj1 instanceof Test); //true var_dump($obj1 instanceof Child); //false var_dump($obj2 instanceof Test); //true var_dump($obj2 instanceof Child); //true var_dump(TEST::CL instanceof Test); Var_dump ($obj1 instanceof $obj2); //false var_dump($obj2 instanceof $obj1); //true $st='Child'; var_dump($obj2 instanceof $st); //trueCopy the code

Thank you for reading. If there are any inaccuracies or errors, please leave a message and correct them. I will correct them in time.

Summary is not easy, please do not reprint, otherwise don’t blame the old man you are welcome!

Welcome those who love technology to communicate with me and learn together

References:

www.php.net PHP official documentation