1. PHP では非静的メソッドを静的に呼び出すことができますか?
今日は、PHP で className::methodName() メソッドを使用して、静的として宣言されていないメソッドを呼び出すことができるかどうかを尋ねられました。私の心の中では、この用法を以前に見たような気がしますが、少し自信がありません。ご存知のとおり、マニュアルやチュートリアルでは、メソッドは静的メソッドと非静的メソッドに分けられます。通常、静的に呼び出すメソッドは静的メソッドでなければなりません。
非静的メソッドを呼び出すとどうなるでしょうか?まずテストを行ってください。
执行以下,返回错误如下:
1 |
Fatal error: Non-static method test::test() cannot be called statically in /home/×××/test.php |
2 |
on line 7 Call Stack: 0.0002 332548 1. {main}() /home/×××/test.php:0 |
这个时候,可能大家就会认为静态调用非静态方法是行不通的了,但其实,结论下的过早了,因为test()这个方法比较特殊,与类同名,是构造方法。 我们继续测试。
执行结果:
这说明,静态调用非静态方法是可行的,但是静态调用构造方法是不可以的。为了验证这个结论,我又做了如下测试:
🎜🎜🎜🎜🎜🎜🎜
2
🎜🎜<コード>クラス
テスト{
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
3
🎜🎜
関数</code ><code>test() {
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
4
🎜🎜
echo
「うまくいきます」
;
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
5
🎜🎜
}</code > code>test::test();
🎜🎜🎜🎜🎜🎜🎜
8
🎜🎜
?>
🎜🎜🎜🎜🎜 🎜🎜 🎜以下を実行すると、返されるエラーは次のとおりです: 🎜🎜🎜🎜🎜🎜🎜🎜
1
🎜🎜
致命的なエラー: 非静的メソッド test::test() は実行できません/home/ ×××/test.php
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
2
🎜🎜
行 7 で静的に呼び出されます 呼び出しスタック: 0.0002 332548 1. {main}() / home/×××/test.php:0
🎜🎜🎜🎜🎜🎜🎜🎜現時点では、非静的メソッドを静的に呼び出すことは不可能だと思われるかもしれませんが、実際にははい、test() メソッドはクラスと同じ名前を持ち、コンストラクター メソッドであるため、結論を出すのは時期尚早です。 テストを続けましょう。 🎜🎜🎜🎜🎜🎜🎜🎜
01
🎜🎜
<?php
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
02
🎜🎜<コード>クラス
テスト{
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
03
🎜🎜
関数</code ><code>test() {
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
04
🎜🎜
echo
「うまくいきます」
;
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
05
🎜🎜
}</code >🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜<code>06
🎜🎜
function
test2() {
🎜🎜🎜 - code>🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
08
🎜🎜
}
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
09
🎜🎜
}
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
10
🎜🎜
test::test2();
🎜 🎜🎜🎜🎜🎜🎜🎜🎜🎜
11
🎜🎜
?>
🎜🎜🎜🎜🎜🎜🎜🎜 実行結果: 🎜🎜🎜🎜1🎜🎜
それも動作します
🎜🎜🎜🎜🎜🎜🎜🎜 これは、
非静的メソッドの静的な呼び出しは可能ですが、コンストラクターの静的な呼び出しは不可能であることを示しています。 /u>。この結論を検証するために、次のテストを実行しました。 🎜 🎜2
🎜🎜class
test{
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜3
🎜🎜 static
function
test() {
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜4
🎜🎜
echo
「うまくいきます」
;
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜 5
🎜🎜
}
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜6
🎜🎜}
🎜 🎜🎜🎜🎜🎜🎜🎜🎜🎜7
🎜🎜test::test();
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜8コード >🎜🎜?>
🎜🎜🎜🎜実行結果は次のとおりです:
1 |
Fatal error: Constructor test::test() cannot be static in /home/xxx/test.php on line 9 |
构造方法不能声明静态,所以上面的推论正确。
但这个结果的确是很特殊的,因为可能只有PHP可以静态调用非静态方法,我用Java做了实验,如果静态调用非静态方法会报如下错误:
1 |
Cannot make a static reference to the non-static method showString() from the type HelloWorldApp |
其他语言我没有一一尝试,但这已经足够来说明PHP的特殊之处,关于为什么PHP会有这样的情况我暂时没有找到相关说明。
2.静态调用非静态方法是否应该被应用?
那我们是不是可以使用这种方法来代替static方法呢? 首先在代码的可读性上来看,静态调用非静态方法当然是不被推荐的,这会让维护者产生疑惑。
接下来我们再做一些实验,来看一下静态调用非静态方法在效率上是否会有一定的优势。
6 | for ( $k 1
$k <10000; $k ++) { |
上面代码在我这里的执行时间是18到28毫秒,我们再来测试标准的写法。
3 | static function test2(){ } |
6 | for ( $k 致命的なエラー: コンストラクター test::test() は /home/xxx/test.php の 9 行目で静的であることはできません $k <10000; $k ++) { |
上面的代码执行时间在5到10毫秒之间,这样看来,静态调用非静态方法的效率要比标准的静态方法调用低的多,所以在效率上也不推荐静态调用非静态方法。
发现WordPress中居然在用这么诡异的调用方式:
class-wp.php 第 206-207行:
// Substitute the substring matches into the query.
$query = addslashes(WP_MatchesMapRegex::apply($query, $matches));
这里用的静态调用,而实际的成员函数却不是静态的。
注意:PHP不能静态调用非静态属性
🎜🎜🎜 コンストラクターは静的に宣言できないため、上記の推論は正しいです。 🎜🎜しかし、この結果は確かに非常に特殊です。なぜなら
非静的メソッドを静的に呼び出せるのは PHP だけであるからです。Java で実験を行ったところ、非静的メソッドを静的に呼び出すと次のエラーが発生します。報告される:🎜🎜🎜1🎜🎜🎜🎜キャノットタイプのhelloworldapp🎜🎜🎜🎜🎜🎜🎜🎜🎜iのshontring()をshontaticメソッドに静的に参照してくださいPHP の特殊な機能を説明するにはこれで十分ですが、なぜ PHP がそのような状況になるのかについての適切な説明は見つかりませんでした。 🎜🎜
2. 非静的メソッドへの静的呼び出しを適用する必要がありますか? 🎜🎜静的メソッドの代わりにこのメソッドを使用できますか?
まず、コードの可読性の観点から、非静的メソッドを静的に呼び出すことは当然推奨されませんので、メンテナーが混乱することになります。 🎜🎜 次に、非静的メソッドを静的に呼び出すことに効率性の点で利点があるかどうかを確認するために、いくつかの実験を行ってみましょう。 🎜🎜🎜🎜🎜🎜🎜🎜🎜1🎜🎜🎜🎜<?php🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜2🎜🎜🎜 🎜クラス🎜🎜テスト{🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜 🎜🎜3🎜🎜🎜🎜 🎜🎜function🎜🎜test2() { }🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜4🎜🎜🎜🎜} 🎜 🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜5🎜🎜 🎜 🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜6🎜🎜🎜🎜for🎜🎜(🎜🎜$k🎜🎜=0;
🎜🎜$k🎜🎜<10000; 🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜7🎜🎜🎜🎜🎜 🎜test::test2();🎜🎜🎜🎜 🎜🎜🎜🎜🎜🎜🎜🎜8🎜🎜🎜🎜}🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜9🎜🎜🎜🎜?> 🎜🎜🎜🎜🎜🎜🎜🎜🎜上記のコードの実行はここです時間は 18 ~ 28 ミリ秒です。標準的な書き込み方法をもう一度テストしてみましょう。 🎜🎜🎜🎜🎜🎜🎜🎜🎜1🎜🎜🎜🎜<?php🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜2🎜🎜🎜 🎜クラス🎜🎜テスト{🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜 🎜🎜3🎜🎜🎜🎜 🎜🎜static🎜🎜function🎜🎜test2(){ }🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜4🎜🎜 🎜 🎜}🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜 5🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜6🎜🎜🎜🎜for🎜🎜(🎜🎜$k🎜🎜=0;
🎜🎜$k🎜🎜<10000; 🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜7🎜🎜🎜🎜 🎜テスト: :test2();🎜🎜🎜🎜 🎜🎜🎜🎜🎜🎜🎜🎜8🎜🎜🎜🎜}🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜9🎜🎜🎜🎜?> 🎜🎜🎜🎜🎜🎜🎜🎜🎜上記のコードの実行時間は5ですこの観点から、非静的メソッドの静的呼び出しの効率は標準の静的メソッド呼び出しよりもはるかに低いため、 という観点からは
非静的メソッドの静的呼び出しは推奨されません。効率。 🎜
🎜WordPress が実際にこのような奇妙な呼び出しメソッドを使用していることを発見しました: 🎜
🎜class-wp.php 行 206-207: 🎜
// 部分文字列の一致をクエリに置き換えます。
$ query = addedlashes(WP_MatchesMapRegex::apply($query, $matches));
🎜ここでは静的呼び出しが使用されていますが、実際のメンバー関数は静的ではありません。 🎜
🎜注: PHP は非静的プロパティを静的に呼び出すことはできません🎜
🎜🎜🎜🎜🎜🎜🎜🎜1🎜🎜🎜🎜<?php🎜🎜🎜🎜🎜🎜🎜 🎜🎜🎜 🎜 2🎜🎜🎜🎜クラス🎜🎜テスト{🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜3🎜🎜🎜🎜 🎜🎜=」 123分🎜🎜;🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜 🎜🎜4🎜🎜🎜🎜 🎜🎜関数🎜🎜test2() {🎜🎜🎜🎜🎜
报错:
1 |
Fatal error: Access |
echo
「うまくいきます」
;
🎜🎜🎜
6
🎜🎜
}
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
7🎜🎜<code>}
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
8
🎜🎜
echo
test::
$id
;
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜
9
🎜🎜
?>
🎜🎜 🎜🎜🎜🎜🎜🎜エラー: 🎜🎜🎜🎜🎜
1
🎜🎜
致命的なエラー: アクセス
🎜🎜🎜🎜
🎜
上記は、PHP で非静的メソッドを静的に呼び出すことができるかどうかを紹介しました。 (変な呼び方) 内容の側面も含めて、PHP チュートリアルに興味のある友人の参考になれば幸いです。 🎜
🎜
🎜