Переопределение функций в PHP 5.3

в 21:15, , рубрики: php, метки:

PHP 5.3 давно уже не новость и написано о нем прилично(да и приелся он как-то после выхода версии 5.4). Тем не менее, хотелось бы поставить акцент на одной его особенности.

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


Небольшой пример*:

\index.php

namespace ZendDate {
    function is_object($date) {
		echo "Zend Date constructor is called with param {$date}";exit;
    }
}


namespace Foo {

require_once 'zf2/library/Zend/Loader/AutoloaderFactory.php';
ZendLoaderAutoloaderFactory::factory(array('ZendLoaderStandardAutoloader' => array()));

$date = new ZendDateDate('2012-03-18');

}

Что тут происходит? Я переопределил функцию is_object которая вызывается в самом начале конструктора ZendDateDate. Если изменить определение функции, чтобы значение передавалось по ссылке, то можно изменять не только результат, но и сами параметры, передаваемые в функцию.

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

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

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

В заключение хочу сказать, что на данный момент можно делать такие штуки в Zend, Symfony, Doctrine.

* — версия интерпретатора 5.4.0RC9-dev

Автор: MaksSlesarenko

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js