Как подключить класс php
Перейти к содержимому

Как подключить класс php

  • автор:

Как подключить класс через use?

Привет, у меня имеется следующая структура файлов:
В корне проекта лежат файлы composer.json и index.php, а также папка App.
Папка App имеет следующую структуру:
\Controllers\ТутФайлыКонтроллера.php
\Models\ТутМоделиИВременноКлассыРоута.php

В composer.json написано следующее:

< "require-dev": < "phpunit/phpunit": "^9.5" >, "autoload": < "psr-4": < "App\\": "App/" >> >
checkRoute($routes); ?>
uri == $_SERVER['REQUEST_URI']) < $method = $elem->method; $controller = new $elem->controller; return $controller->$method(); > > > >

Не смотрите на саму организацию всей этой приблуды(Вывод через эхо и всё такое — всё поменяю).
Проблема вот в чем: Автоподключение срабатывает, Строчка «echo ( new Router )->checkRoute($routes);» срабатывает, также, как и подключение в файле routes.php. Но в файле Router.php происходит ошибка:

Fatal error: Uncaught Error: Class ‘TestController’ not found in C:\OpenServer\domains\likeavito\App\Models\Router.php:12 Stack trace: #0 C:\OpenServer\domains\likeavito\index.php(10): App\Models\Router->checkRoute(Array) #1 thrown in C:\OpenServer\domains\likeavito\App\Models\Router.php on line 12

12я строчка это
$controller = new $elem->controller;
Получается, что проблема кроется в «use App\Controllers\TestController;». Без использования автозагрузки приведенный код срабатывал, теперь — нет.
Явное указание namespace тоже не решает вопрос. В гугле ничего нет(Все ссылаются на перепроверки путей, которые я копировал и писал вручную — без толку). Помогите, пожалуйста, голову сломал.

P.S. Если писать автозагрузку средствами php и подключать классы по namespace — все окей.

upd:
Совсем забыл указать, что лежит в файле Route.php:

uri = $uri; $this->controller = $controller; $this->method = $method; > public function __get($property) < return $this->$property; > >
  • Вопрос задан более двух лет назад
  • 401 просмотр

1 комментарий

Простой 1 комментарий

Как подключить класс php

Большинство разработчиков объектно-ориентированных приложений используют такое соглашение именования файлов, в котором каждый класс хранится в отдельно созданном для него файле. Одна из самых больших неприятностей — необходимость писать в начале каждого скрипта длинный список подгружаемых файлов (по одному для каждого класса).

Функция spl_autoload_register() позволяет зарегистрировать необходимое количество автозагрузчиков для автоматической загрузки классов и интерфейсов, если они в настоящее время не определены. Регистрируя автозагрузчики, PHP получает последний шанс для интерпретатора загрузить класс прежде, чем он закончит выполнение скрипта с ошибкой.

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

Предостережение

До PHP 8.0.0 можно было использовать __autoload() для автозагрузки классов и интерфейсов. Однако это менее гибкая альтернатива spl_autoload_register() , функция __autoload() объявлена устаревшей в PHP 7.2.0 и удалена в PHP 8.0.0.

Замечание:

Функция spl_autoload_register() может быть вызвана несколько раз, чтобы зарегистрировать несколько автозагрузчиков. Выброс исключения из функции автозагрузки, однако, прервёт этот процесс и не позволит запускать дальнейшие функции автозагрузки. По этой причине выбрасывать исключения из функции автозагрузки настоятельно не рекомендуется.

Пример #1 Пример автоматической загрузки

В этом примере функция пытается загрузить классы MyClass1 и MyClass2 из файлов MyClass1.php и MyClass2.php соответственно.

spl_autoload_register (function ( $class_name ) include $class_name . ‘.php’ ;
>);

$obj = new MyClass1 ();
$obj2 = new MyClass2 ();
?>

Пример #2 Ещё один пример автоматической загрузки

В этом примере представлена попытка загрузки интерфейса ITest .

spl_autoload_register (function ( $name ) var_dump ( $name );
>);

class Foo implements ITest >

Fatal error: Interface ‘ITest’ not found in .
*/
?>

Смотрите также

  • unserialize()
  • unserialize_callback_func
  • unserialize_max_depth
  • spl_autoload_register()
  • spl_autoload()
  • __autoload()

User Contributed Notes 6 notes

14 years ago

You should not have to use require_once inside the autoloader, as if the class is not found it wouldn’t be trying to look for it by using the autoloader.

Just use require(), which will be better on performance as well as it does not have to check if it is unique.

7 years ago

This is my autoloader for my PSR-4 clases. I prefer to use composer’s autoloader, but this works for legacy projects that can’t use composer.

/**
* Simple autoloader, so we don’t need Composer just for this.
*/
class Autoloader
public static function register ()
spl_autoload_register (function ( $class ) $file = str_replace ( ‘\\’ , DIRECTORY_SEPARATOR , $class ). ‘.php’ ;
if ( file_exists ( $file )) require $file ;
return true ;
>
return false ;
>);
>
>
Autoloader :: register ();

3 years ago

Autoloading plain functions is not supported by PHP at the time of writing. There is however a simple way to trick the autoloader to do this. The only thing that is needed is that the autoloader finds the searched class (or any other autoloadable piece of code) from the files it goes through and the whole file will be included to the runtime.

Let’s say you have a namespaced file for functions you wish to autoload. Simply adding a class of the same name to that file with a single constant property is enough to trigger the autoloader to seek for the file. Autoloading can then be triggered by accessing the constant property.

The constant could be replaced by any static property or method or by default constructor. However, I personally find a constant named ‘load’ elegant and informative. After all this is a workaround. Another thing to keep in mind is that this introduces an unnecessary class to the runtime. The benefit of this is that there is no need to manually include or require files containing functions by path which in turn makes code maintaining easier. Such behaviour makes it easier to alter the project structure since manual includes need not to be fixed. Only the autoloader needs to be able to locate the moved files which can be automated.

A code file containing functions.
/Some/Namespace/Functions.php
namespace Some\Namespace ;

function b () >
?>

Triggering autoloading of the file containing functions.
main.php
\Some\Namespace\Functions :: load ;

14 years ago

It’s worth to mention, if your operating system is case-sensitive you need to name your file with same case as in source code eg. MyClass.php instead of myclass.php

15 years ago

Because static classes have no constructor I use this to initialize such classes.
The function init will (if available) be called when you first use the class.
The class must not be included before, otherwise the init-function wont be called as autoloading is not used.

function __autoload ( $class_name )
<
require_once( CLASSES_PATH . $class_name . ‘.cls.php’ );
if( method_exists ( $class_name , ‘init’ ))
call_user_func (array( $class_name , ‘init’ ));
return true ;
>
?>

I use it for example to establish the mysql-connection on demand.

It is also possilbe do add a destructor by adding this lines to the function:
if( method_exists ( $class_name , ‘destruct’ ))
register_shutdown_function (array( $class_name , ‘destruct’ ));
?>

1 year ago

Autoloading Classes with spl_autoload_register() or spl_autoload() is the best and most modern way to securely code for API integration.

It restricts the various attacks that can be faced by using a «polyfill» or framework that is subject to data injection. Low level attacks, polyfill and framework vulnerabilities are some exploitations limited in using the core functionalities of your host programming language.

Your loop-holes and target endpoints are vastly removed to the level of programming experience of the developer — in not exposing the threats espoused to your programming language and its security protocols.

Each event you transfer data from one program to the next reveals another threat and another attack endpoint. When you are production, it is at this point composer and other tools that gather requirements specific secure integration should limit its use, such as PCI-DSS, HIPAA, or GDPR.

The use of a framework or polyfill gives an attacker hints at what point a function will access memory to produce intended results. Visiting the late L1-Cache Terminal Fault — attacks that use machine language to access memory and read what actually is happening will have all the details of what process is taking place and when.

Not to mention, when a product is open-source, the code is editable and easily compiled. Using access to machine level integrations a simply 10 second loss of time to process could well as infer the entire application has experienced an overhaul.

To deter this, and ensure maximum security for piece of mind and money-wise. The embedded resources of a programming language should be utilized at maximal capacity to prevent an overhaul on multiple endpoints. Visiting a system in use is not deletable or easily moved, removed or altered.

  • Классы и объекты
    • Введение
    • Основы
    • Свойства
    • Константы классов
    • Автоматическая загрузка классов
    • Конструкторы и деструкторы
    • Область видимости
    • Наследование
    • Оператор разрешения области видимости (::)
    • Ключевое слово static
    • Абстрактные классы
    • Интерфейсы объектов
    • Трейты
    • Анонимные классы
    • Перегрузка
    • Итераторы объектов
    • Магические методы
    • Ключевое слово final
    • Клонирование объектов
    • Сравнение объектов
    • Позднее статическое связывание
    • Объекты и ссылки
    • Сериализация объектов
    • Ковариантность и контравариантность
    • Журнал изменений ООП
    • Copyright © 2001-2024 The PHP Group
    • My PHP.net
    • Contact
    • Other PHP.net sites
    • Privacy policy

    Автоматически подключать класс

    Автозагрузку классов можно сделать через функцию spl_autoload_register() .

    spl_autoload_register('autoload'); function autoload($class) < include $_SERVER['DOCUMENT_ROOT'].'/classes/' . $class . '.class.php'; > $user = new User(); // будет автоматически подключен файл «classes/User.class.php» 

    Данный способ рекомендуется использовать вместо прямого подключения классов через include .

    Автоматическое подключение классов через __autoload() признано устаревшим с версии PHP 7.2 и не рекомендуется к использованию.

    Отключить автозагрузку классов

    Отключить автоматическое подклчение классов можно через функцию spl_autoload_unregister() .

    spl_autoload_unregister('autoload');

    Обновлено: 19 ноября 2023

    Комментарии

    Авторизуйтесь, чтобы добавлять комментарии

    • Работа с ООП
    • Конструктор и деструктор
    • Наследование
    • Модификаторы доступа (Инкапсуляция)
    • Вызвать метод класса без создания экземпляра
    • Интерфейс и абстрактный класс
    • Вызов объекта как текст или функция
    • Запретить переопределять метод класса
    • Автоматически подключать класс
    • Синглтон (Singleton)
    • Запретить создавать экземпляр класса

    Как подключить класс php

    Каждое определение класса начинается с ключевого слова class , затем следует имя класса, и далее пара фигурных скобок, которые заключают в себе определение свойств и методов этого класса.

    Именем класса может быть любое слово, при условии, что оно не входит в список зарезервированных слов PHP, начинается с буквы или символа подчёркивания и за которым следует любое количество букв, цифр или символов подчёркивания. Если задать эти правила в виде регулярного выражения, то получится следующее выражение: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$ .

    Класс может содержать собственные константы, переменные (называемые свойствами) и функции (называемые методами).

    Пример #1 Простое определение класса

    class SimpleClass
    // объявление свойства
    public $var = ‘значение по умолчанию’ ;

    // объявление метода
    public function displayVar () echo $this -> var ;
    >
    >
    ?>

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

    Внимание

    Вызов нестатического метода статически вызывает ошибку Error . До PHP 8.0.0 это привело бы к уведомлению об устаревании, и $this не была бы определена.

    Пример #2 Некоторые примеры псевдо-переменной $this

    class A
    function foo ()
    if (isset( $this )) echo ‘$this определена (‘ ;
    echo get_class ( $this );
    echo «)\n» ;
    > else echo «\$this не определена.\n» ;
    >
    >
    >

    $a = new A ();
    $a -> foo ();

    $b = new B ();
    $b -> bar ();

    Результат выполнения приведённого примера в PHP 7:

    $this определена (A) Deprecated: Non-static method A::foo() should not be called statically in %s on line 27 $this не определена. Deprecated: Non-static method A::foo() should not be called statically in %s on line 20 $this не определена. Deprecated: Non-static method B::bar() should not be called statically in %s on line 32 Deprecated: Non-static method A::foo() should not be called statically in %s on line 20 $this не определена.

    Результат выполнения приведённого примера в PHP 8:

    $this определена (A) Fatal error: Uncaught Error: Non-static method A::foo() cannot be called statically in %s :27 Stack trace: #0 thrown in %s on line 27
    Классы, доступные только для чтения

    Начиная с PHP 8.2.0, класс может быть помечен модификатором readonly . Пометка класса как readonly добавит модификатор readonly к каждому объявленному свойству и предотвратит создание динамических свойств. Более того, невозможно добавить их поддержку с помощью атрибута AllowDynamicProperties . Попытка это сделать приведёт к ошибке компиляции.

    #[ \AllowDynamicProperties ]
    readonly class Foo >

    // Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo
    ?>

    Поскольку ни нетипизированные, ни статические свойства не могут быть помечены модификатором readonly , классы, доступные только для чтения также не могут их объявлять:

    // Fatal error: Readonly property Foo::$bar must have type
    ?>

    readonly class Foo
    public static int $bar ;
    >

    // Fatal error: Readonly class Foo cannot declare static properties
    ?>

    Класс readonly может быть расширен тогда и только тогда, когда дочерний класс также является классом readonly .

    new

    Для создания экземпляра класса используется директива new . Новый объект всегда будет создан, за исключением случаев, когда он содержит конструктор, в котором определён вызов исключения в случае возникновения ошибки. Рекомендуется определять классы до создания их экземпляров (в некоторых случаях это обязательно).

    Если с директивой new используется строка ( string ), содержащая имя класса, то будет создан новый экземпляр этого класса. Если имя находится в пространстве имён, то оно должно быть задано полностью.

    Замечание:

    В случае отсутствия аргументов в конструктор класса, круглые скобки после названия класса можно опустить.

    Пример #3 Создание экземпляра класса

    // Это же можно сделать с помощью переменной:
    $className = ‘SimpleClass’ ;
    $instance = new $className (); // new SimpleClass()
    ?>

    Начиная с PHP 8.0.0, поддерживается использование оператора new с произвольными выражениями. Это позволяет создавать более сложные экземпляры, если выражение представлено в виде строки ( string ). Выражения должны быть заключены в круглые скобки.

    Пример #4 Создание экземпляра с использованием произвольного выражения

    В данном примере мы показываем несколько вариантов допустимых произвольных выражений, которые представляют имя класса. Пример вызова функции, конкатенации строк и константы ::class .

    class ClassA extends \stdClass <>
    class ClassB extends \stdClass <>
    class ClassC extends ClassB <>
    class ClassD extends ClassA <>

    function getSomeClass (): string
    return ‘ClassA’ ;
    >

    var_dump (new ( getSomeClass ()));
    var_dump (new ( ‘Class’ . ‘B’ ));
    var_dump (new ( ‘Class’ . ‘C’ ));
    var_dump (new ( ClassD ::class));
    ?>

    Результат выполнения приведённого примера в PHP 8:

    object(ClassA)#1 (0) < >object(ClassB)#1 (0) < >object(ClassC)#1 (0) < >object(ClassD)#1 (0)

    В контексте класса можно создать новый объект через new self и new parent .

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

    Пример #5 Присваивание объекта

    $instance = new SimpleClass ();

    $assigned = $instance ;
    $reference =& $instance ;

    $instance -> var = ‘$assigned будет иметь это значение’ ;

    $instance = null ; // $instance и $reference становятся null

    var_dump ( $instance );
    var_dump ( $reference );
    var_dump ( $assigned );
    ?>

    Результат выполнения приведённого примера:

    NULL NULL object(SimpleClass)#1 (1) < ["var"]=>string(30) "$assigned будет иметь это значение" >

    Создавать экземпляры объекта можно двумя способами:

    Пример #6 Создание новых объектов

    class Test
    static public function getNew ()
    return new static;
    >
    >

    class Child extends Test
    <>

    $obj1 = new Test ();
    $obj2 = new $obj1 ;
    var_dump ( $obj1 !== $obj2 );

    $obj3 = Test :: getNew ();
    var_dump ( $obj3 instanceof Test );

    $obj4 = Child :: getNew ();
    var_dump ( $obj4 instanceof Child );
    ?>

    Результат выполнения приведённого примера:

    bool(true) bool(true) bool(true)

    Обратиться к свойству или методу только что созданного объекта можно с помощью одного выражения:

    Пример #7 Доступ к свойствам/методам только что созданного объекта

    echo (new DateTime ())-> format ( ‘Y’ );
    ?>

    Вывод приведённого примера будет похож на:

    2016

    Замечание: До PHP 7.1 аргументы не имели значения, если не определена функция конструктора.

    Свойства и методы

    Свойства и методы класса живут в разделённых «пространствах имён», так что возможно иметь свойство и метод с одним и тем же именем. Ссылки как на свойства, так и на методы имеют одинаковую нотацию, и получается, что получите вы доступ к свойству или же вызовете метод — определяется контекстом использования.

    Пример #8 Доступ к свойству vs. вызов метода

    public function bar () return ‘метод’ ;
    >
    >

    $obj = new Foo ();
    echo $obj -> bar , PHP_EOL , $obj -> bar (), PHP_EOL ;

    Результат выполнения приведённого примера:

    свойство метод

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

    Пример #9 Вызов анонимной функции, содержащейся в свойстве

    public function __construct () $this -> bar = function() return 42 ;
    >;
    >
    >

    echo ( $obj -> bar )(), PHP_EOL ;

    Результат выполнения приведённого примера:

    extends

    Класс может наследовать константы, методы и свойства другого класса используя ключевое слово extends в его объявлении. Невозможно наследовать несколько классов, один класс может наследовать только один базовый класс.

    Наследуемые константы, методы и свойства могут быть переопределены (за исключением случаев, когда метод или константа класса объявлены как final) путём объявления их с теми же именами, как и в родительском классе. Существует возможность доступа к переопределённым методам или статическим свойствам путём обращения к ним через parent::

    Замечание: Начиная с PHP 8.1.0, константы можно объявлять окончательными (final).

    Пример #10 Простое наследование классов

    class ExtendClass extends SimpleClass
    // Переопределение метода родителя
    function displayVar ()
    echo «Расширенный класс\n» ;
    parent :: displayVar ();
    >
    >

    $extended = new ExtendClass ();
    $extended -> displayVar ();
    ?>

    Результат выполнения приведённого примера:

    Расширенный класс значение по умолчанию
    Правила совместимости сигнатуры

    При переопределении метода его сигнатура должна быть совместима с родительским методом. В противном случае выдаётся фатальная ошибка или, до PHP 8.0.0, генерируется ошибка уровня E_WARNING . Сигнатура является совместимой, если она соответствует правилам контравариантности, делает обязательный параметр необязательным, добавляет только необязательные новые параметры и не ограничивает, а только ослабляет видимость. Это известно как принцип подстановки Барбары Лисков или сокращённо LSP. Правила совместимости не распространяются на конструктор и сигнатуру private методов, они не будут выдавать фатальную ошибку в случае несоответствия сигнатуры.

    Пример #11 Совместимость дочерних методов

    class Base
    public function foo ( int $a ) echo «Допустимо\n» ;
    >
    >

    class Extend1 extends Base
    function foo ( int $a = 5 )
    parent :: foo ( $a );
    >
    >

    class Extend2 extends Base
    function foo ( int $a , $b = 5 )
    parent :: foo ( $a );
    >
    >

    $extended1 = new Extend1 ();
    $extended1 -> foo ();
    $extended2 = new Extend2 ();
    $extended2 -> foo ( 1 );

    Результат выполнения приведённого примера:

    Допустимо Допустимо

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

    Пример #12 Фатальная ошибка, когда дочерний метод удаляет параметр

    class Base
    public function foo ( int $a = 5 ) echo «Допустимо\n» ;
    >
    >

    class Extend extends Base
    function foo ()
    parent :: foo ( 1 );
    >
    >

    Результат выполнения приведённого примера в PHP 8 аналогичен:

    Fatal error: Declaration of Extend::foo() must be compatible with Base::foo(int $a = 5) in /in/evtlq on line 13

    Пример #13 Фатальная ошибка, когда дочерний метод делает необязательный параметр обязательным.

    class Base
    public function foo ( int $a = 5 ) echo «Допустимо\n» ;
    >
    >

    class Extend extends Base
    function foo ( int $a )
    parent :: foo ( $a );
    >
    >

    Результат выполнения приведённого примера в PHP 8 аналогичен:

    Fatal error: Declaration of Extend::foo(int $a) must be compatible with Base::foo(int $a = 5) in /in/qJXVC on line 13

    Внимание

    Переименование параметра метода в дочернем классе не является несовместимостью сигнатуры. Однако это не рекомендуется, так как приведёт к Error во время выполнения, если используются именованные аргументы.

    Пример #14 Ошибка при использовании именованных аргументов и параметров, переименованных в дочернем классе

    class A public function test ( $foo , $bar ) <>
    >

    class B extends A public function test ( $a , $b ) <>
    >

    // Передача параметров согласно контракту A::test()
    $obj -> test ( foo : «foo» , bar : «bar» ); // ОШИБКА!

    Вывод приведённого примера будет похож на:

    Fatal error: Uncaught Error: Unknown named parameter $foo in /in/XaaeN:14 Stack trace: #0 thrown in /in/XaaeN on line 14

    ::class

    Ключевое слово class используется для разрешения имени класса. Чтобы получить полное имя класса ClassName , используйте ClassName::class . Обычно это довольно полезно при работе с классами, использующими пространства имён.

    Пример #15 Разрешение имени класса

    Результат выполнения приведённого примера:

    NS\ClassName

    Замечание:

    Разрешение имён класса с использованием ::class происходит на этапе компиляции. Это означает, что на момент создания строки с именем класса автозагрузки класса не происходит. Как следствие, имена классов раскрываются, даже если класс не существует. Ошибка в этом случае не выдаётся.

    Пример #16 Отсутствует разрешение имени класса

    print Does\Not\Exist ::class;
    ?>

    Результат выполнения приведённого примера:

    Does\Not\Exist

    Начиная с PHP 8.0.0, константа ::class также может использоваться для объектов. Это разрешение происходит во время выполнения, а не во время компиляции. То же самое, что и при вызове get_class() для объекта.

    Пример #17 Разрешение имени объекта

    namespace NS class ClassName >
    >
    $c = new ClassName ();
    print $c ::class;
    ?>

    Результат выполнения приведённого примера:

    NS\ClassName

    Методы и свойства Nullsafe

    Начиная с PHP 8.0.0, к свойствам и методам можно также обращаться с помощью оператора «nullsafe»: ?-> . Оператор nullsafe работает так же, как доступ к свойству или методу, как указано выше, за исключением того, что если разыменование объекта выдаёт null , то будет возвращён null , а не выброшено исключение. Если разыменование является частью цепочки, остальная часть цепочки пропускается.

    Аналогично заключению каждого обращения в is_null() , но более компактный.

    Пример #18 Оператор Nullsafe

    // Начиная с PHP 8.0.0, эта строка:
    $result = $repository ?-> getUser ( 5 )?-> name ;

    // Эквивалентна следующему блоку кода:
    if ( is_null ( $repository )) $result = null ;
    > else $user = $repository -> getUser ( 5 );
    if ( is_null ( $user )) $result = null ;
    > else $result = $user -> name ;
    >
    >
    ?>

    Замечание:

    Оператор nullsafe лучше всего использовать, когда null считается допустимым и ожидаемым значением для возвращаемого свойства или метода. Для индикации ошибки предпочтительнее выбрасывать исключение.

    User Contributed Notes 11 notes

    16 years ago

    I was confused at first about object assignment, because it’s not quite the same as normal assignment or assignment by reference. But I think I’ve figured out what’s going on.

    First, think of variables in PHP as data slots. Each one is a name that points to a data slot that can hold a value that is one of the basic data types: a number, a string, a boolean, etc. When you create a reference, you are making a second name that points at the same data slot. When you assign one variable to another, you are copying the contents of one data slot to another data slot.

    Now, the trick is that object instances are not like the basic data types. They cannot be held in the data slots directly. Instead, an object’s «handle» goes in the data slot. This is an identifier that points at one particular instance of an obect. So, the object handle, although not directly visible to the programmer, is one of the basic datatypes.

    What makes this tricky is that when you take a variable which holds an object handle, and you assign it to another variable, that other variable gets a copy of the same object handle. This means that both variables can change the state of the same object instance. But they are not references, so if one of the variables is assigned a new value, it does not affect the other variable.

    // Assignment of an object
    Class Object public $foo = «bar» ;
    >;

    $objectVar = new Object ();
    $reference =& $objectVar ;
    $assignment = $objectVar

    //
    // $objectVar —>+———+
    // |(handle1)—-+
    // $reference —>+———+ |
    // |
    // +———+ |
    // $assignment —>|(handle1)—-+
    // +———+ |
    // |
    // v
    // Object(1):foo=»bar»
    //
    ?>

    $assignment has a different data slot from $objectVar, but its data slot holds a handle to the same object. This makes it behave in some ways like a reference. If you use the variable $objectVar to change the state of the Object instance, those changes also show up under $assignment, because it is pointing at that same Object instance.

    $objectVar -> foo = «qux» ;
    print_r ( $objectVar );
    print_r ( $reference );
    print_r ( $assignment );

    //
    // $objectVar —>+———+
    // |(handle1)—-+
    // $reference —>+———+ |
    // |
    // +———+ |
    // $assignment —>|(handle1)—-+
    // +———+ |
    // |
    // v
    // Object(1):foo=»qux»
    //
    ?>

    But it is not exactly the same as a reference. If you null out $objectVar, you replace the handle in its data slot with NULL. This means that $reference, which points at the same data slot, will also be NULL. But $assignment, which is a different data slot, will still hold its copy of the handle to the Object instance, so it will not be NULL.

    $objectVar = null ;
    print_r ( $objectVar );
    print_r ( $reference );
    print_r ( $assignment );

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *