Патч обезьяны в пространстве имен php >= 5.3
Менее уклончивым методом, чем модификация интерпретатора, является исправление обезьяны.
Обезьянье исправление - это искусство замены фактической реализации аналогичным «заплаткой» из ваших собственных.
Навыки ниндзя
Прежде чем вы сможете делать обезьяньи патчи, как PHP-ниндзя, мы сначала должны понять пространства имен PHP.
Начиная с PHP 5.3 мы познакомились с пространствами имен, которые на первый взгляд могут показаться эквивалентными чему-то вроде пакетов Java, но это не совсем то же самое. Пространства имен в PHP — это способ инкапсулировать область действия путем создания иерархии фокуса, особенно для функций и констант. Цель этого раздела, откат к глобальным функциям, — объяснить.
Если вы не указываете пространство имен при вызове функции, PHP сначала ищет в текущем пространстве имен, затем перемещается вниз по иерархии, пока не найдет первую функцию, объявленную в этом пространстве имен с префиксом, и не выполнит ее. В нашем примере, если вы вызываете print_r();
из namespace My\Awesome\Namespace;
, PHP сначала ищет функцию с именем My\Awesome\Namespace\print_r();
, затем My\Awesome\print_r();
, затем My\print_r();
, пока не найдет встроенную функцию PHP в глобальном пространстве имен \print_r();
.
Вы не сможете определить function print_r($object) {}
в глобальном пространстве имен, потому что это вызовет конфликт имен, поскольку функция с таким именем уже существует.
Ожидайте фатальную ошибку, например:
Fatal error: Cannot redeclare print_r()
Однако ничто не мешает вам делать именно это в рамках пространства имен.
Исправление обезьяны
Скажем, у вас есть сценарий, использующий несколько вызовов print_r();
.
Пример:
<?php
print_r($some_object);
// do some stuff
print_r($another_object);
// do some other stuff
print_r($data_object);
// do more stuff
print_r($debug_object);
Но позже вы передумали и хотите, чтобы вывод был заключен в теги <pre></pre>
. С тобой когда-нибудь случалось?
Прежде чем вы пойдете и измените каждый вызов на print_r();
, подумайте вместо этого об исправлении обезьяны.
Пример:
<?php
namespace MyNamespace {
function print_r($object)
{
echo "<pre>", \print_r($object, true), "</pre>";
}
print_r($some_object);
// do some stuff
print_r($another_object);
// do some other stuff
print_r($data_object);
// do more stuff
print_r($debug_object);
}
Ваш скрипт теперь будет использовать MyNamespace\print_r();
вместо глобального \print_r();
Отлично подходит для имитации модульных тестов.
нРадость!
person
nickl-
schedule
26.08.2012