Интерфейсы php 7, подсказки возвращаемого типа и self

Увеличение строки ++

С числами все довольно просто, но что будет если инкрементить строки?

$a = 'fact_2';
echo ++$a;        //> fact_3

$a = '2nd_fact';
echo ++$a;        //> 2nd_facu

$a = 'a_fact';
echo ++$a;        //> a_facu

$a = 'a_fact?';
echo ++$a;        //> a_fact?

$a = 'Привет';
echo ++$a;        //> Привет

При инкременте строки, PHP изменяет последний символ на символ следующий по алфавиту. Так при инкременте, если в конце строки 2, то эта 2-ка изменится на 3. После t следует u. Однако эта операция не имеет никакого смысла в случае, когда строка заканчивается на не буквенно-численный символ (в примере выше это символ кириллицы).

Этот момент хорошо описан в официальной документации по операциям инкремента/декремента, однако многие не читали этот материал, потому что не ожидали встретить там ничего особенного.

Boolean

1. Когда Вы конвертируете что-то в тип boolean, значения типа пустой строки или пустого массива, а также число 0 (будь то 0 или 0.00) рассматривается как FALSE.

Но при этом совершенно неясно, чем руководствовался автор языка, когда решил, что строка «0» тоже должна интерпретироваться как FALSE. При этом «0.00», конечно же, TRUE. *facepalm*

2. Комментарии к статьям в официальном мануале полны интересных советов и замечаний. Вот некоторые из них, касающиеся типа boolean.

При выводе булевых переменных PHP делает нечто странное. Рассмотрим код:

$var1 = TRUE;
$var2 = FALSE;

echo $var1; // Отображает число 1

echo $var2;//Ничего не выводит

echo (int)$var2; //Это выведет 0.

Прекрасно, правда?

3. PHP никогда не предупредит Вас о переводе типа данных из булевого в числовой, поэтому следует быть очень аккуратным. А порой это порождает дикие несуразицы.


var_dump(0 == 1); // false
var_dump(0 == (bool)’all’); // false
var_dump(0 == ‘all’); // TRUE, осторожно!
var_dump(0 === ‘all’); // false

«var_dump(0 == ‘all’)» — что здесь произошло? Так как мы попытались сравнить число и строку, то PHP попытается перевести строку в число. Если строка не переводима в число, то PHP не будет выдавать никаких ошибок или предупреждений. Он просто преобразует такую строку в ноль.

Чтобы избежать такого поведения, надо приводить число к строке:

var_dump((string)0 == 'all'); // false

4. Из предыдущего пункта следует, что любая строка не содержащая в начале чисел равняется нулю при переводе в число. В то же время, любая не пустая строка (кроме «0») переводится в TRUE. Таким образом:

0 == 'all';//TRUE
TRUE == 'all';//TRUE

При этом, конечно же 0 не равняется TRUE. Работа оператора == вообще не согласована, он не имеет свойства транзитивности.

5.  Рассмотрим еще один пример, который касается логического оператора:

$x=TRUE;
$y=FALSE;
$z=$y OR $x;

Чему равно $z? Конечно же FALSE!

Дело в том, что оператор OR имеет низкий приоритет, и присваивание $z=$y будет выполнено раньше. Т.е. вышеприведенный код эквивалентен такому:

($z=$y) OR $x

Что здесь происходит? Выполняется присваивание $z=$y, затем в результате присваивания возвращается TRUE (это не изъян PHP, в другом языке, вроде того же С++ при подстановке присваивания в условие всегда будет возвращаться TRUE). Так как уже было возвращено TRUE, то оператор OR далее ничего не делает, потому что остальные операнды уже не повлияют на результат.

Таким образом конечный результат совсем не тот, который ожидали. Что из этого следует? В силу своей низкой приоритетности, оператор OR скорее следует использовать как оператор альтернативного выполнения действий. Всем знакома данная конструкция:

doSomething() OR die()

В данном случае, если при исполнении функции doSomething произойдет ошибка, или в результате работы функции будет возвращено FALSE (что с точки зрения оператора OR одно и то же), будет выполнена функция die, так как проверке подлежат все операнды оператора до первого TRUE.

Отсюда мораль: если нужно просто проверить булево условие — используйте оператор || вместо OR, у него более высокий приоритет и работает он без сюрпризов.

What is Parent Keyword?

$this only represents the current instance of the class and self:: represents the class itself.You can not use this operator outside the class code and also in extended class to get parent class values.

You can use parent:: keyword as opposite of the parent’s class name because it is easy to change your class hierarchy because you are not hard-code the parent’s class name.parent:: is the special name for parent class which when used in a member function.To use the parent to call the parent class constructor to initialize the parent class so that the object inherits the class assignment to give a name.

NOTE: PHP does not accept parent as the name of a function.

Let’s have a look into both parent:: and self:: for accessing the Child and Parent classes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

classParentcls{

constCLSPARENT=»Parent»;

function__construct()

{

echo»Within «.selfCLSPARENT.» constructor.»;

}

}
 

classChildclsextendsParentcls{

constCLSCHILD=»Child»;

function__construct()

{

parent__construct();

echo»Calling «.parentCLSPARENT.» class»;

echo»Within «.selfCLSCHILD.» constructor»;

}

}

$obj=newChildcls();

 

As per above example, static methods are part of the class but they are not bound to any specific object instance and its properties. Therefore, You can not access static methods using $this but you can access class itself by using self.To access a method in the parent class that’s been overridden in the child by using the parent:: keyword.In the example, we override the constructor function in the child class using prefix parent but you can override any function.

Output:

1
2
3
4
5

Within Parentconstructor.

Calling Parentclass

Within Childconstructor

 

Difference between $this,self and Parent

$this

1. $this refers to the object. 2. $this point to the current object instance does not point to any other object or class.

::self

1. self:: refer to the class itself, not point to any object. 2. using self:: you can access the static properties and static methods of the current class.

::parent

1. parent:: is refer to the parent class. 2. using parent::, you can access the static properties and static methods of the parent class.

With the use of self and parent, you allow to avoid explicitly reference the class by name.

Do let me know how you are using parent and self in your application via the comment section. Don’t forget to share this article on plus and .

История Интернета Как и когда зародилась глобальная сеть?

Теперь, когда у нас есть небольшое представление о том, что такое World Wide Web, мы важно, чтобы мы знали немного больше о происхождении и появление этой технологии, какой мы ее знаем. Любопытно отметить, что великие изобретения или поистине революционные изобретения которые представляют собой прорыв для человечества, произошли не в одночасье, и WWW не стал исключением

Любопытно отметить, что великие изобретения или поистине революционные изобретения которые представляют собой прорыв для человечества, произошли не в одночасье, и WWW не стал исключением .

Поскольку эта технология развивался постепенно в течение 3 разных эпох и разными персонажами, по крайней мере, это то, что нам записывает история.

Все началось в 1940 году благодаря идее американского инженера Ванневара Буша. , который был основан на системе, которая позволяла извлекать информацию, хранящуюся в базе данных, с большой точностью и скоростью.

Другими словами, благодаря интерфейсу, названному его создателем Memex, информация можно получить доступ через звонок или ключ . К сожалению, этот проект не удалось завершить, но, основываясь на этой идее чуть позже, другое изобретение под названием Xanandú делает предложение относительно гипертекстов более формальным.

Этот другой проект был представлен в 50-х годах Тедом Нельсоном и Дугласом Энгельбартом, но им требовалось нечто важное: Интернет, который все еще находился в зачаточном состоянии и не будет полностью функционировать до конца 60-х годов. Но в конце концов им оказался Тим Бернерс Ли, британский ученый-компьютерщик

, который в 1989 году начал работать над идеей WWW, успех которой заключается в объединении Интернета с идеей гипертекстов, и вместе с этим была разработана система гиперссылок, которая является не чем иным, как система, которая позволяет каждому ресурсу в Интернете иметь свою собственную конкретную ссылку

Но в конце концов им оказался Тим Бернерс Ли, британский ученый-компьютерщик. , который в 1989 году начал работать над идеей WWW, успех которой заключается в объединении Интернета с идеей гипертекстов, и вместе с этим была разработана система гиперссылок, которая является не чем иным, как система, которая позволяет каждому ресурсу в Интернете иметь свою собственную конкретную ссылку.

Бернерс Ли разработал свой проект с помощью CERN, европейской ядерной исследовательской организации, расположенной в Швейцарии, и официально представил свой проект 6 августа 1991 года. Используя сервер от компании NeXT и компьютер той же реализации, создайте первую страницу веб-сайта, на которой была бы размещена идея в целом и ее функции. , так что он развился во всем мире.

Всемирная паутина была наконец запущена в ЦЕРНе в 1993 году, после чего она только разрослась.

15.6. Статические свойства и методы. Константы

При работе с классами можно делать методы, которые для своего вызова не требуют создания объекта. Такие методы называются статическими.

Чтобы объявить метод статическим, нужно после модификатора доступа (то есть после public, private или protected) написать ключевое слово static.

Статические свойства принадлежат не какому-то объекту класса, а самому классу, хотя объекты класса и имеют доступ к этим свойствам.
Внутри статических методов нельзя использовать .

Пример

<?php
class Math
{
    private static $pi = 3.14;
    
    public static function getSum($a, $b)
    {
        return $a + $b;
    }
    
    public static function getProduct($a, $b)
    {
        return $a * $b;
    }
    
    public static function getCircleSquare($radius)
    {
        return self::$pi * $radius * $radius;
    }
}
<?php
	echo Math::getSum(1, 2) + Math::getProduct(3, 4);
	echo Math::getCircleSquare(10);

Шунтирующие операторы (короткая запись)

При сравнении типа AND , если первое условие вернет false/0/»/array(), то нет смысла проверять следующие условия, потому что всё условие выполнится только если сразу все вложенные условия вернут что-либо отличное от empty (не false)…

При сравнении типа OR , если хоть одно условие вернет true или что-то отличное от empty, то нет смысла проверять следующие вложенные условия, потому что все условие выполняется когда хоть одно под-условие возвращает не false.

// foo() никогда не буде вызвана
// так как эти операторы являются шунтирующими (short-circuit)

$a = false && foo();
$b = ( false and foo() );
$c = true || foo();
$d = ( true  or  foo() );

Структурирование неструктурированных данных

Приходилось ли вам когда-нибудь работать с “массивом данных”, который на самом деле был больше, чем просто список? Вы использовали ключи массива в качестве полей? И вы чувствовали боль от того, что не знали точно, что было в этом массиве? Не будучи уверенным, действительно ли данные в нем такие, какими вы их ожидаете увидеть, или какие поля доступны?

Давайте представим себе, о чем я говорю: работа с запросами Laravel. Рассмотрим этот пример как базовую операцию CRUD для обновления существующего клиента:

Возможно,вы уже видите возникающую проблему: мы не знаем точно, какие данные доступны в  массиве. Массивы в PHP являются универсальной и мощной структурой данных. Но как только мы начинаем использовать их как свалку данных, мы теряем всю эту мощь и направляемся ближе к тлену, ошибкам, непониманию.

Прежде чем искать решения этой проблемы, вот что вы можете сделать, чтобы понять что находится в этой свалке:

  • Прочтёте исходный код
  • Прочтёте документацию
  • Изучите свалку  через print_r
  • Или используете отладчик для этого

Теперь представьте себе на минуту, что вы работаете с командой из нескольких разработчиков над этим проектом, и что ваш коллега написал этот фрагмент кода пять месяцев назад: я могу гарантировать вам, что вы не будете знать, с какими данными вы работаете, не делая никаких громоздких вещей, перечисленных выше.

Оказывается, что строго типизированные системы в сочетании со статическим анализом могут быть большим подспорьем в понимании того, с чем именно мы имеем дело. Такие языки, как Rust, например, решают эту проблему просто:

Структура – это то, что нам нужно! К сожалению, PHP не имеет структур.  Но у него есть массивы и объекты. Объектов может быть достаточно для решения нашей проблемы:

Для тех, кто может использовать PHP 7.4 или выше, вы можете сделать что-то вроде этого:

Статический анализатор, встроенный в вашу IDE, всегда сможет сообщить нам, с какими данными мы имеем дело.

Этот шаблон упаковки неструктурированных данных в типы, чтобы мы могли использовать наши данные надежным способом, называется “объекты передачи данных” или DTO (Data Transfer Object). Этот шаблон я настоятельно рекомендую вам использовать в ваших проектах большего размера. Для средних и маленьких проектов данный шаблон будет избыточен.

Обсуждая эту статью с коллегами, друзьями или в сообществе Laravel, вы можете столкнуться с людьми, которые не разделяют одно и то же видение сильной типизации. На самом деле есть много людей, которые предпочитают принимать динамическую и слабую типизацию PHP. И тут определенно есть что сказать в свое оправдание.

По моему опыту, однако, есть больше преимуществ в строго типизированном подходе при работе с командой из нескольких разработчиков над проектом в течение серьезного количества времени. Вы должны использовать любую возможность, чтобы уменьшить когнитивную нагрузку. Вы не хотите, чтобы разработчикам приходилось начинать отладку своего кода каждый раз, когда они хотят знать, что именно находится в переменной. Информация должна быть прямо под рукой, чтобы разработчики могли сосредоточиться на том, что важно: создании приложения. Конечно, использование DTO имеет свою цену: существуют не только накладные расходы на определение этих классов; Вам также нужно сопоставить, например, запрос данных с DTO

Конечно, использование DTO имеет свою цену: существуют не только накладные расходы на определение этих классов; Вам также нужно сопоставить, например, запрос данных с DTO.

Преимущества использования DTO определенно перевешивают. Независимо от того, сколько времени вы потеряете, написав этот код, вы компенсируете его в долгосрочной перспективе.

Однако вопрос о построении DTO из “внешних” данных все еще нуждается в ответе.

15.9. Наследование vs композиция и аггрегация

Наследование, композиция и агрегация — это способы взаимодействия классов между собой. Т.е. как один класс может использовать методы другого класса.

Наследование (Is-A)

Это один из принципов ООП, который подразумевает, что класс наследник, будет иметь все те же свойства и методы, что и в базовом классе. В коде это выглядит так:

<?php
 
class A {
    public function helloWorld(){
        echo 'Hello world';
    }
}
 
class B extends A {}
 
$obj = new B;
$obj->helloWorld();
 

Композиция (Has-A)

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

<?php
 
class A {
    public function helloWorld(){
        echo 'Hello World';
    }
}
 
class B {
    protected $a;
    public function __construct(){
        $this->a = new A;  // создает объект другого класса
    }
    public function sayHello(){
        $this->a->helloWorld();  // использует объект другого класса
    }
}
 
$obj = new B;
$obj->sayHello();

Композиция — это по сути включение класса, внутрь другого класса с помощью создания объекта внутри этого класса.

У такого подхода есть один недостаток — сильная связанность, это значит, что, для того чтобы поменять класс A на A1, вам придется переписывать конструктор (new A1 вместо A).

Преимущество у такого способа, это то, что класс B, управляет временем жизни объекта A. Т.е. при удалении объекта B будет и удален, объект A который был создан внутри B.

Агрегация (Has-A)

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

<?php
 
class A {
    public function helloWorld(){
        echo 'Hello World';
    }
}
 
class B {
    protected $a;
    public function __construct(A $a){
        $this->a = $a;
    }
    public function sayHello(){
        $this->a->helloWorld();  // использует объект другого класса
    }
}
 
$objA = new A; // создает объект другого класса
 
$objB = new B($objA);
$objB->sayHello();

В отличие от композиции, тут все наоборот. Преимущество: легко передать новый объект A1 без изменений в коде — слабая связанность. Из недостатков, пожалуй, следует отметить, что в больших системах это приводит к огромному кол-ву переменных в конструкторе

Композиция лучше наследования

Как говорится в известной книге «Шаблоны проектирования» Банды четырёх, по мере возможности нужно выбирать композицию, а не наследование. Есть много хороших причин использовать как наследование, так и композицию. Главная цель этой максимы заключается в том, если вы инстинктивно склоняетесь к наследованию, то постарайтесь представить, может ли композиция лучше решить вашу задачу. В каких-то случаях это действительно более подходящий вариант.

Вы спросите: «А когда лучше выбирать наследование?» Всё зависит от конкретной задачи, но можно ориентироваться на этот список ситуаций, когда наследование предпочтительнее композиции:

  • Ваше наследование — это взаимосвязь is-a, а не has-a. Пример: Человек → Животное vs. Пользователь → Детали пользователя (UserDetails).
  • Вы можете повторно использовать код из базовых классов. (Люди могут двигаться, как животные.)
  • Вы хотите внести глобальные изменения в производные классы, изменив базовый класс. (Изменение расхода калорий у животных во время движения.)

Плохо

class Employee
{
    private $name;
    private $email;

    public function __construct(string $name, string $email)
    {
        $this->name = $name;
        $this->email = $email;
    }

    // ...
}

// Bad because Employees "have" tax data.
// EmployeeTaxData is not a type of Employee

class EmployeeTaxData extends Employee
{
    private $inn;
    private $salary;

    public function __construct(string $name, string $email, string $inn, string $salary)
    {
        parent::__construct($name, $email);

        $this->inn = $inn;
        $this->salary = $salary;
    }

    // ...
}

Хорошо

class EmployeeTaxData
{
    private $inn;
    private $salary;

    public function __construct(string $inn, string $salary)
    {
        $this->inn = $inn;
        $this->salary = $salary;
    }

    // ...
}

class Employee
{
    private $name;
    private $email;
    private $taxData;

    public function __construct(string $name, string $email)
    {
        $this->name = $name;
        $this->email = $email;
    }

    public function setTaxData(EmployeeTaxData $taxData)
    {
        $this->taxData = $taxData;
    }

    // ...
}

Константы

В РНР константы определяются функцией define(), которая имеет следующий формат:

define ($name, $value, $case_sen), где
$name - имя константы;
$value - значение константы;
$case_sen - необязательный параметр логического типа, 
указывающий, следует ли учитывать регистр букв (true) или нет (false).

Пример задания константы:

<?php
    define("pi",3.14,true);
?>

Обратите внимание, что константы используются без предваряющего знака $.

Стандартные константы

PHP предоставляет большой список предопределенных констант для каждого выполняемого скрипта. Многие из этих констант определяются различными модулями и будут присутствовать только в том случае, если эти модули доступны в результате динамической загрузки или в результате статической сборки.
Специальные константы нечувствительны к регистру. Список таких констант представлен ниже.

Имя константы Описание
__LINE__ Текущая строка в файле.
__FILE__ Полный путь и имя текущего файла.
__DIR__ Полный путь к файлу без его имени
__FUNCTION__ Имя функции. (Добавлена в PHP 4.3.0.)
__CLASS__ Имя класса. (Добавлена в PHP 4.3.0.)
__METHOD__ Имя метода класса. (Добавлена в PHP 5.0.0)
__NAMESPACE__ Имя текущего пространства имен

15.8. Наследование

Пример

<?php
class Person
{
    private $name;
    private $age;
    
    public function getName()
    {
        return $this->name;
    }
    
    public function setName($name)
    {
        $this->name = $name;
    }
    
    public function getAge()
    {
        return $this->age;
    }
    
    public function setAge($age)
    {
        $this->age = $age;
    }
}
<?php
class Student extends Person
{
    private $university;
    
    public function getUniversity()
    {
        return $this->university;
    }
    
    public function setUniversity($university)
    {
        $this->university = $university;
    }
}

Обращение к родительскому классу из наследника

Например, мы хотим устанавливать возраст студента только если он больше 16 лет. Для этого мы можем переопределить родительский метод

<?php
class Student extends Person
{
    private $university;
    
    public function setAge($age)
    {
        if ($age >= 16) {
            parent::setAge($age); // Вызываем метод родителя:
        }
    }
    
    public function getUniversity()
    {
        return $this->university;
    }
    
    public function setUniversity($university)
    {
        $this->university = $university;
    }
}

Перезапись конструктора родительского класса

<?php
class Person
{
    private $name;
    private $age;
    
    public function __construct($name, $age)
    {
        $this->name = $name;
        $this->age = $age;
    }
}
<?php
class Student extends Person
{
    private $university;
    public function __construct($name, $age, $university)
    {
        parent::__construct($name, $age);
        
        $this->university = $university;
    }
}

Точное сравнение: 0 == ‘строка’

PHP язык без строгой типизации и потому иногда могут возникать неожиданные результаты при сравнении (проверке) разных значений…

if( 0 == 'строка' ) echo 'Неужели?'; // увидим: 'Неужели?'

// строка превращается в число при сравнении и становится 0:
var_dump( 0 == 'строка' );   //> bool(true)

// но
var_dump( '0' == 'строка' ); //> bool(false)

Происходит так очевидно, потому что превращается в ноль: , а это true, разумеется…

Так например можно пропустить переменную запроса:

// $_GET может быть любой строкой и проверка всегда будет срабатывать...
if( $_GET == 0 ){
	echo $_GET;
}

// поэтому по возможности ставьте проверку строго по типу
if( $_GET === '0' ){
	echo $_GET;
}

Все следующие значения одинаковы, при сравнении через (не строгий оператор сравнения):

0 == false == "" == "0" == null == array()

Ну и так:

1 == '1нечто' == true
true == array(111)

Сквозной пример по классам


####################################################
## 5. Классы
####################################################

# Чтобы получить класс, мы наследуемся от object.
class Human(object):

# Атрибут класса. Он разделяется всеми экземплярами этого класса
species = «H

sapiens»

# Обычный конструктор, вызывается при инициализации экземпляра класса
# Обратите внимание, что двойное подчёркивание в начале и в конце имени
# означает объекты и атрибуты, которые используются Python, но находятся
# в пространствах имён, управляемых пользователем.
# Не придумывайте им имена самостоятельно.
def __init__(self, name):
# Присваивание значения аргумента атрибуту класса name
self.name = name

# Метод экземпляра. Все методы принимают self в качестве первого аргумента
def say(self, msg):
return «{name}: {message}».format(name=self.name, message=msg)

# Метод класса разделяется между всеми экземплярами
# Они вызываются с указыванием вызывающего класса в качестве первого аргумента
@classmethod
def get_species(cls):
return cls.species

# Статический метод вызывается без ссылки на класс или экземпляр
@staticmethod
def grunt():
return «*grunt*»

# Инициализация экземпляра класса
i = Human(name=»Иван»)
print(i.say(«привет»)) # Выводит: «Иван: привет»

j = Human(«Пётр»)
print(j.say(«Привет»)) # Выводит: «Пётр: привет»

# Вызов метода класса
i.get_species() #=> «H

sapiens»

# Изменение разделяемого атрибута
Human.species = «H. neanderthalensis»
i.get_species() #=> «H. neanderthalensis»
j.get_species() #=> «H. neanderthalensis»

# Вызов статического метода
Human.grunt() #=> «*grunt*»

4.6
12
голоса

Рейтинг статьи

String

1. Булевое TRUE приводится к строке «1», тем временем как FALSE — к пустой строке. Как поясняют в мануале сами разработчики PHP, это позволяет производить конверсии между булевыми и строковыми переменными в обоих направлениях.

Остается только гадать, почему FALSE не приводится к строке «0», ведь как раз для такой строки и было придумано исключение. Такое впечатление, что после того как сделали интерпретацию строки «0» в качестве FALSE про это просто забыли.

2. Если Вы используете ассоциативный ключ массива внутри строки с двойными кавычками (double-quoted string) PHP выдает ошибку T_ENCAPSED_AND_WHITESPACE.

Рассмотрим код:

$fruit=array(
   'a'=>'apple',
   'b'=>'banana'
);

print "This is a $fruit";//ошибка T_ENCAPSED_AND_WHITESPACE

Решение проблемы, возникшей на пустом месте:

print "This is a $fruit";    //да, так можно
print "This is a ${fruit}";//Complex Syntax для строк с переменными
print "This is a {$fruit}";//вариация Complex Syntax

3. Используя специальный синтаксис внутри строк с двойными кавычками можно использовать переменные, поля класса и даже результаты вызова его методов. Однако, статические методы и поля класса, а также константы внутри класса Вы использовать уже не можете. Потому что парсер ищет символы ‘$’. А их нет. Смотрите:

class Test {
    const ONE = 1;
}
echo "foo {Test::ONE} bar"; //выведет foo {Test::one} bar

Вообще, какого черта для использования статических полей, методов и констант надо было придумывать какой-то особый синтаксис? Из-за этого единственный выход — разбивать строку не полагаясь на «чудо-парсинг».

Что означает new self(); в PHP?

Я никогда не видел такого кода:

Это то же самое, что new className() ?

EDIT

Если класс наследуется, на какой класс он указывает?

5 ответов

Возможный Дубликат : Понимание Приращения Ссылка-Что означает этот символ в PHP? Что означает ++ , я видел это также в javascript $this->instance = ++self::$instances; с уважением

self указывает на класс, в котором он написан.

Итак, если ваш метод getInstance находится в имени класса MyClass , следующая строка :

Будет делать то же самое, что и :

Правка : еще пара сведений, после комментариев.

Если у вас есть два класса, которые расширяют друг друга, у вас есть две ситуации :

  • getInstance определяется в дочернем классе
  • getInstance определяется в родительском классе

Первая ситуация будет выглядеть следующим образом (я удалил весь ненужный код для этого примера-вам придется добавить его обратно, чтобы получить поведение singleton)* :

Здесь вы получите :

Что означает self означает MyChildClass -то есть класс, в котором он написан.

Для второй ситуации код будет выглядеть следующим образом :

И вы получите такой результат :

Это означает, что self означает MyParentClass , то есть здесь тоже класс, в котором он написан .

С PHP static : теперь его можно использовать именно там, где мы использовали self в этих примерах :

Но с static вместо self вы теперь получите :

Это означает, что static указывает на используемый класс (мы использовали MyChildClass::getInstance() ), а не на тот, в котором он написан.

Конечно, поведение self не было изменено, чтобы не нарушать существующие приложения-PHP 5.3 просто добавил новое поведение, переработав ключевое слово static .

И, говоря о PHP 5.3, вы, возможно, захотите взглянуть на страницу Поздних статических привязок руководства PHP.

Я много раз сталкивался с этой строкой в модулях perl, но не мог понять, что именно это означает. my ($self, %myInputs) = @_; Пожалуйста, объясните мне это заявление,чтобы я мог продолжить.

Это используется в паттерне weakify Objective-C Я предполагаю, что это означает: назначьте слабую ссылку на self с именем ‘weakSelf’ и типом self (например, MyViewController) Если это правильно и кажется вам очевидным: я хочу быть абсолютно уверен, что все будет правильно. Спасибо.

По-видимому, это реализация шаблона Singleton . Функция вызывается статически и проверяет, имеет ли статический класс переменную $_instance .

Если это не так, он инициализирует экземпляр самого себя ( new self() ) и сохраняет его в $_instance .

Если вы вызовете className::getInstance() , вы получите один и тот же экземпляр класса при каждом вызове, что является точкой шаблона singleton.

Однако я никогда не видел, чтобы это делалось таким образом, и, честно говоря, не знал, что это возможно. Что такое $_instance , объявленное как в классе?

Это, скорее всего, используется в шаблоне проектирования singleton, где конструктор определен как частный, чтобы избежать создания экземпляра, оператор double colon (::) может получить доступ к элементам, объявленным статическими внутри класса, поэтому, если есть статические элементы, псевдо-переменная $this не может быть использована, поэтому код, используемый вместо этого, Синглеты-это хорошие методы программирования, которые позволят использовать только 1 экземпляр объекта, например обработчики соединителя базы данных. Из клиентского кода доступ к этому экземпляру будет осуществляться путем создания одной точки доступа, в этом случае он назвал ее getInstance() , getInstance сама по себе была функцией , которая создала объект, в основном используя ключевое слово new для создания объекта, что означает, что также был вызван метод конструктора.

строка if(!isset(self::instance)) проверяет, был ли объект уже создан, вы не могли этого понять, потому что код-это просто фрагмент, где-то в верхней части должны быть статические элементы, такие как, вероятно,

в обычных классах мы бы получили доступ к этому члену просто

но он объявлен статическим, и поэтому мы не могли использовать код $this, который мы используем вместо этого

проверив, есть ли объект, сохраненный в этой переменной статического класса, класс может затем решить, создавать или не создавать один экземпляр, поэтому, если он не установлен,! isset, что означает, что объект не существует в статическом члене $_instance,, он генерирует новый объект, сохраняет его в статическом члене $_instance с помощью команды

и вернул его в клиентский код. Затем клиентский код может с радостью использовать единственный экземпляр объекта с его общедоступными методами, но в клиентском коде вызов единой точки доступа, то есть метода getInstance() , также сложен, его нужно вызывать следующим образом

причина в том, что функция сама по себе объявлена статической.

Источник

Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Люкс-хост
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: