Php instance of example

PHP instanceof Operator Tips

Note: This post is over two years old and so the information contained here might be out of date. If you do spot something please leave a comment and we will endeavour to correct.

The instanceof operator in PHP is great at making sure you are looking at a type of object before acting on it. Whilst it’s straightforward to use on its own, using it can lead to some undesirable side effects.

As a basic example, let’s create a couple of interfaces and classes to show the instanceof operator in action. Rather than just have some test names I am using object names that you might find in a system. This consists of User and Order that might form part of a commerce system.

 class User implements UserInterface <> interface OrderInterface <> class Order implements OrderInterface <>

If we instantiate the User object we can detect if the user is an instance of the class User like this.

As the User object implements an interface we can also detect if the User object is an instance of an interface like this.

Conversely, if we were to see if the $user variable we created is an instance of a different kind of object then it would return false, like this.

If we aren’t sure what kind of interface or object we are going to receive then we can pass in a variable that contains the name of the interface.

Читайте также:  Javascript functions not defined

Note that just passing in the interface as a string, as in the following snippet, will produce a syntax error. The item you use to detect the type of object or interface must be either a variable or a fully qualified class or interface name.

Negating the instance of operator is a little less straightforward, but can be done by putting an exclamation mark at the beginning of the statement.

It is usually good practice to wrap the whole thing in brackets so that you can be sure of the outcome of the check.

You can also compare the output of the instanceof operator to false, which essentially negates it. I find this a little more difficult to read, although you could also argue that you might miss the exclamation mark.

When namespaces are involved then care must be taken that the right syntax is used. When using the fully qualified namespace then the proceeding slash is required, otherwise the right instance won’t be found. It’s probably best practice to not use the fully qualified namespace at all though and just to rely on the interface name you are looking for. The following example is looking at a Drupal interface called FormStateInterface with three different ways of writing down the class name.

A single instanceof check is easy enough to understand, but if you are trying to detect if an object is one of a series of types of objects then the code gets a little difficult to read. For example, let’s say that you are trying to detect if an object was one of a series of the three types of interface defined at the beginning of the post; you might create an if statement like the following.

This returns true, which indicates that the object is one of the instance types we are looking for.

I found a good function that allows this to be encapsulated neatly whilst reading stack overflow the other day (see the original stack overflow comment here). To detect if an object is one of a series of types you can use the following function that will take an object and an array of classnames.

This can be run in the following way. Passing in the previously created user object and an array that contains the instance types we are looking for as strings returns true.

The instanceof operator will also work for child objects. Take the following code that creates an interface, defines a User class and then defines an Administrator class that extends the User class.

 class User implements UserInterface <> class Administrator extends User <>

We can instantiate the User and Administrator objects and try to detect them in different ways.

The thing to note from the above code is that a User object is not an instance of an Administrator object and so that comparison returns false. The Administrator object is, however, an instance of the User object and so that comparison is true.

What happens then, if we are trying to detect the instance of just an Administrator object, and not a User object. Unfortunately the instanceof operator can’t be used here. Instead, in order to detect just the one type of class you are looking for you’ll need to use a different comparison using the get_class() PHP method.

Note that the User object is not an Administrator object and so the comparison returns false. The above can also be written differently using the ::class magic constant to return the string of the class name. This is actually the way I normally print out class names and the way I would write this type of comparison.

  • When detecting a type of object try as much as possible to detect the instance, rather than the class. This allows for good SOLID principles to be followed.
  • Don’t use the fully qualified name of the interface. Using just the interface name is sufficient and follows best practice.
  • If looking for the absence of an instance then be sure to wrap the comparison in brackets to avoid any inconsistencies in the precedence of surrounding operators.
  • Be careful when using inheritance, all objects inheriting a parent class will be detected as being the same type as the parent.

Phil Norton

Phil is the founder and administrator of #! code and is an IT professional working in the North West of the UK. Graduating in 2003 from Aberystwyth University with an MSc in Computer Science Phil has previously worked as a database administrator, on an IT help desk, systems trainer, web architect, usability consultant, blogger and SEO specialist. Phil has lots of experience building and maintaining PHP websites as well as working with associated technologies like JavaScript, HTML, CSS, XML, Flex, Apache, MySQL and Linux.

Want to know more? Need some help?

Let us help! Hire us to provide training, advice, troubleshooting and more.

Support Us!

Please support us and allow us to continue writing articles.

Источник

Определение принадлежности объекта к классу

Сейчас мы с вами изучим оператор instanceof . Данный оператор используется для определения того, является ли текущий объект экземпляром указанного класса.

Давайте посмотрим на примере. Пусть у нас даны какие-то два класса:

Создадим объект первого класса:

Проверим принадлежность объекта из переменной $obj первому классу и второму:

Сделайте класс Employee с публичными свойствами name (имя) и salary (зарплата).

Сделайте класс Student с публичными свойствами name (имя) и scholarship (стипендия).

Создайте по 3 объекта каждого класса и в произвольном порядке запишите их в массив $arr .

Переберите циклом массив $arr и выведите на экран столбец имен всех работников.

Аналогичным образом выведите на экран столбец имен всех студентов.

Переберите циклом массив $arr и с его помощью найдите сумму зарплат работников и сумму стипендий студентов. После цикла выведите эти два числа на экран.

Оператор instanceof и наследование

Пусть теперь у нас есть родительский класс и дочерний:

Создадим объект дочернего класса:

Проверим теперь с помощью instanceof , принадлежит ли наш объект классу ParentClass и классу ChildClass :

Как вы видите из примера — оператор instanceof не делает различия при проверки между родительскими и дочерними классами.

Не путайтесь — если объект будет действительно родительского класса то, конечно же, проверка на принадлежность к дочернему классу вернет false :

Сделайте класс User с публичным свойствами name и surname .

Сделайте класс Employee , который будет наследовать от класса User и добавлять свойство salary .

Сделайте класс City с публичными свойствами name и population .

Создайте 3 объекта класса User , 3 объекта класса Employee , 3 объекта класса City , и в произвольном порядке запишите их в массив $arr .

Переберите циклом массив $arr и выведите на экран столбец свойств name тех объектов, которые принадлежат классу User или потомку этого класса.

Переберите циклом массив $arr и выведите на экран столбец свойств name тех объектов, которые не принадлежат классу User или потомку этого класса.

Переберите циклом массив $arr и выведите на экран столбец свойств name тех объектов, которые принадлежат именно классу User , то есть не классу City и не классу Employee .

Применение

Давайте рассмотрим применение оператора instanceof на достаточно сложном примере. Пусть у нас есть вот такой класс для работников:

Пусть также есть такой класс для студентов:

Как вы видите, и работник, и студент имеют имя и какой-то доход: у работника это зарплата, а у студента — стипендия.

Пусть теперь мы хотим сделать класс UsersCollection , предназначенный для хранения работников и студентов. Работников мы будем хранить в свойстве employees , а студентов — в свойстве students :

Давайте теперь реализуем единый метод add для добавления и работников, и студентов. Этот метод параметром будет принимать объект и, если это работник — добавлять его в массив работников, а если студент — в массив студентов. Пример того, как мы будем пользоваться методом нашим методом после его реализации:

add(new Employee(‘john’, 200)); // попадет к работникам $usersCollection->add(new Student(‘eric’, 100)); // попадет к студентам ?>

Итак, давайте реализуем описанный метод add . Здесь нам и поможет изученный нами оператор instanceof :

Давайте также реализуем методы для нахождения суммарной зарплаты и суммарной стипендии:

employees[] = $user; > if ($user instanceof Student) < $this->students[] = $user; > > // Получаем суммарную зарплату: public function getTotalSalary() < $sum = 0; foreach ($this->employees as $employee) < $sum += $employee->getSalary(); > return $sum; > // Получаем суммарную стипендию: public function getTotalScholarship() < $sum = 0; foreach ($this->students as $student) < $sum += $student->getScholarship(); > return $sum; > > ?>

Реализуем также метод, который будет находить общую сумму платежей и работникам, и студентам:

employees[] = $user; > if ($user instanceof Student) < $this->students[] = $user; > > public function getTotalSalary() < $sum = 0; foreach ($this->employees as $employee) < $sum += $employee->getSalary(); > return $sum; > public function getTotalScholarship() < $sum = 0; foreach ($this->students as $student) < $sum += $student->getScholarship(); > return $sum; > // Получаем общую сумму платежей и работникам, и студентам: public function getTotalPayment() < return $this->getTotalScholarship() + $this->getTotalSalary(); > > ?>

Проверим работу нашего класса:

add(new Student(‘kyle’, 100)); $usersCollection->add(new Student(‘luis’, 200)); $usersCollection->add(new Employee(‘john’, 300)); $usersCollection->add(new Employee(‘eric’, 400)); // Получим полную сумму стипендий: echo $usersCollection->getTotalScholarship(); // Получим полную сумму зарплат: echo $usersCollection->getTotalSalary(); // Получим полную сумму платежей: echo $usersCollection->getTotalPayment(); ?>

Скопируйте мой код классов Employee и Student и самостоятельно не подсматривая в мой код реализуйте такой же класс UsersCollection .

Источник

Оцените статью