宣言このような関数を...
function ihatefooexamples(){
return "boo-foo!";
};
そしてredeclareこのようになります...
if ($_GET['foolevel'] == 10){
function ihatefooexamples(){
return "really boo-foo";
};
};
その方法で関数を上書きすることは可能ですか?
とにかく?
この回答が元の質問に直接対応していないというコメントに対処するため。 Google検索からここにアクセスした場合は、ここから始めてください
override_function と呼ばれる利用可能な関数があり、実際に法案に適合します。ただし、この関数が The Advanced PHP Debugger extensionの一部であることを考えると、override_function()
が実稼働での使用を意図しているという議論をするのは困難ですしたがって、「いいえ」と言うと、元の質問者が念頭に置いた意図で関数を上書きすることはできません。
ここで、OOP、特に多態性を利用する必要があります。
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();
インタープリターを変更するより回避性の低い方法は、モンキーパッチです。
モンキーパッチングは、実際の実装を独自の同様の「パッチ」に置き換える技術です。
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();
は、グローバル名前空間\print_r();
でPHP組み込み関数を見つけるまで。
グローバル名前空間で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関数スコープで上書きすることはできません。
そのような匿名関数を使用するあなたのベスト
$ihatefooexamples = function()
{
return "boo-foo!";
}
//...
unset($ihatefooexamples);
$ihatefooexamples = function()
{
return "really boo-foo";
}
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;');
1つのケースのすべての関数をinclude
ファイルに含め、他の関数を別の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 design pattern を確認してください。それから基本的なアイデアを借りることができます。
いいえ、これは問題になります。 PHP変数関数
編集可能なインクルードファイルAがあり、インクルードファイルB(またはメインファイル)でその機能の一部をオーバーライドする関連ケースのソリューション:
メインファイル:
<?php
$Override=true; // An argument used in A.php
include ("A.php");
include ("B.php");
F1();
?>
ファイルAを含める:
<?php
if (!@$Override) {
function F1 () {echo "This is F1() in A";}
}
?>
ファイルBを含める:
<?php
function F1 () {echo "This is F1() in B";}
?>
メインファイルを参照すると、「これはBのF1()です」と表示されます。
これが必要な状況に応じて、次のような匿名関数を使用できます。
$greet = function($name)
{
echo('Hello ' . $name);
};
$greet('World');
...その後、いつでも新しい関数を指定された変数に設定できます