Можете ли вы объявить такую функцию …
function ihatefooexamples(){ return "boo-foo!"; };
И затем переделайте это несколько так …
if ($_GET['foolevel'] == 10){ function ihatefooexamples(){ return "really boo-foo"; }; };
Можно ли переписать функцию таким образом?
Так или иначе?
Чтобы ответить на комментарии, этот ответ напрямую не затрагивает исходный вопрос. Если вы попали сюда из Google Search, начните здесь
Доступна функция, называемая override_function, которая действительно соответствует счету. Однако, учитывая, что эта функция является частью расширения расширенного PHP-отладчика , трудно сделать аргумент, что override_function()
предназначен для использования в производстве. Поэтому я бы сказал «Нет», невозможно переписать функцию с намерением, которое имел в виду первоначальный вопросник.
Здесь вы должны использовать ООП, в частности полиморфизм.
interface Fooable { public function ihatefooexamples(); } class Foo implements Fooable { public function ihatefooexamples() { return "boo-foo!"; } } class FooBar implements Fooable { public function ihatefooexamples() { return "really boo-foo"; } } $foo = new Foo(); if (10 == $_GET['foolevel']) { $foo = new FooBar(); } echo $foo->ihatefooexamples();
Менее уклончивым методом, чем изменение интерпретатора, является патч обезьяны.
Monkey patching – это искусство замены реальной реализации аналогичным «патчем».
Прежде чем вы сможете использовать патч обезьяны, как PHP Ninja, нам сначала нужно понять пространства имен 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();
Отлично подходит для издевательских модульных тестов.
NJoy!
Посмотрите на override_function
чтобы переопределить функции.
override_function – переопределяет встроенные функции
Пример:
override_function('test', '$a,$b', 'echo "DOING TEST"; return $a * $b;');
Вы не можете обновлять любые функции в PHP. Однако вы можете переопределить их. Проверьте функции переопределения, а также функции переименования , чтобы сохранить функцию, которую вы переопределяете, если хотите.
Поэтому имейте в виду, что когда вы переопределяете функцию, вы ее теряете. Вы можете захотеть сохранить его, но под другим именем. Просто говорю.
Кроме того, если это функции в классах, которые вы хотите переопределить, вам просто нужно создать подкласс и переопределить функцию в своем классе, не выполняя функции rename_function и override_function.
Пример:
rename_function('mysql_connect', 'original_mysql_connect' ); override_function('mysql_connect', '$a,$b', 'echo "DOING MY FUNCTION INSTEAD"; return $a * $b;');
короткий ответ – нет, вы не можете перезаписать функцию после ее использования в области функций PHP.
лучше всего использовать анонимные функции
$ihatefooexamples = function() { return "boo-foo!"; } //... unset($ihatefooexamples); $ihatefooexamples = function() { return "really boo-foo"; }
этот$ihatefooexamples = function() { return "boo-foo!"; } //... unset($ihatefooexamples); $ihatefooexamples = function() { return "really boo-foo"; }
не$ihatefooexamples = function() { return "boo-foo!"; } //... unset($ihatefooexamples); $ihatefooexamples = function() { return "really boo-foo"; }
Я бы включил все функции одного случая в файл include
, а остальные – в другой.
Например, simple.inc
будет содержать function boofoo() { simple }
и really.inc
будет содержать function boofoo() { really }
Это помогает читать / поддерживать вашу программу, имея все функции одного и того же типа в одном inc
.
Затем в верхней части основного модуля
if ($_GET['foolevel'] == 10) { include "really.inc"; } else { include "simple.inc"; }
Вы можете использовать расширение PECL
runkit_function_redefine
– Заменить определение функции новой реализацией но это плохая практика, на мой взгляд. Вы используете функции, но ознакомьтесь с шаблоном проектирования Decorator . Можно взять основную идею из нее.
Нет, это будет проблемой. Переменные функции PHP
В зависимости от ситуации, в которой вы нуждаетесь, возможно, вы можете использовать анонимные функции следующим образом:
$greet = function($name) { echo('Hello ' . $name); }; $greet('World');
… тогда вы можете установить новую функцию для данной переменной в любое время