検索
ホームページバックエンド開発PHPチュートリアルオブジェクトを動的にインスタンス化し、コンストラクターにパラメータを渡すPHPのケース分析

フレームワーク開発やモジュール開発などでは、PHP の実行中にオブジェクトを動的にインスタンス化する必要がある場合があります。

動的にインスタンス化されたオブジェクトとは何ですか?まず、PHP の変数関数 (変数関数) の概念を見てみましょう。 たとえば、次のコード:

function foo() {
    echo 'This is the foo function';
}
$bar = 'foo';
$bar();

上記のコードを実行すると、「これは foo 関数です」と出力されます。詳細については、PHP マニュアルの「変数関数」を参照してください。もちろん、動的に呼び出す必要がある場合は、call_user_func 関数または call_user_func_array 関数を使用します。これら 2 つの関数の使用法はこの記事の焦点では​​ありません。理解できない場合は、他の情報を確認してください。この記事の主題に戻ります: 動的にインスタンス化されるオブジェクトとは何ですか?オブジェクトの動的インスタンス化とは、インスタンス化する必要があるオブジェクトが、コード内に直接ハードコーディングされるのではなく、プログラムの実行時に動的に決定される (変数によって決定される) ことを意味すると私は考えています。

上記の例を通じて、オブジェクト指向が非常に人気のある今日、クラスを動的にインスタンス化する必要があることをすでに理解しています。

状況 1: クラスのコンストラクターにパラメーターがないか、パラメーターの数が決まっています

クラスのコンストラクターにパラメーターがない場合、またはインスタンス化したいクラスにコンストラクターがまったくない場合、より簡単な場合は、上記に従うことができます 例を変更するだけで、同じ例に従うことができます:

コード例: (コンストラクターにはパラメーターがありません)

class FOO {
    private $a, $b;
    public function construct() {
        $this->a = 1;
        $this->b = 2;
    }
    public function test() {
        echo &#39;This is the method test of class FOO<br />&#39;;
        echo &#39;$this->a=&#39;, $this->a, &#39;, $this->b=&#39;, $this->b;
    }
}
$bar = &#39;FOO&#39;;
$foo = new $bar();
$foo->test();

実行すると、次の出力が表示されます:

This is the method test of class FOO
$this->a=1, $this->b=2

そうですね、パラメーターを渡す必要があります。そうであれば、次のようにしてください:

class FOO {
    private $a, $b;
    public function construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }
    public function test() {
        echo &#39;This is the method test of class FOO<br />&#39;;
        echo &#39;$this->a=&#39;, $this->a, &#39;, $this->b=&#39;, $this->b;
    }
}
$bar = &#39;FOO&#39;;
$foo = new $bar(&#39;test&#39;, 5);
$foo->test();

も同様の結果を得ることができます:

This is the method test of class FOO
$this->a=test, $this->b=5

が理想的です。

状況 2: クラス構築関数パラメータの数が不確実です

この状況はさらに面倒になりますが、より汎用的に書きたい場合は、この状況を考慮する必要があります。たとえば、次の 2 つのクラス

class FOO {
    public function test() {
        echo &#39;This is the method test of class FOO&#39;;
    }
}
class BAR {
    private $a, $b;
    public function construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }
    public function test() {
        echo &#39;This is the method test of class BAR<br />&#39;;
        echo &#39;$this->a=&#39;, $this->a, &#39;, $this->b=&#39;, $this->b;
    }
}

があり、これら 2 つのクラスをインスタンス化する共通の方法が必要です。 FOO クラスにはコンストラクターがないか、BAR クラスのコンストラクターにはパラメーターがある一方で、FOO クラスのコンストラクターのパラメーターの数はゼロであると考えることができます。幸いなことに、PHP5 は十分強力であり、リフレクションの概念が導入されています。詳細については、PHP マニュアル「リフレクション」を参照してください。ただし、マニュアルには参照するものはありません :)。幸いなことに、名前付けはクラス名とメソッド名からすでに大まかに理解できるので、多くの言葉は必要ありません。

それでは、PHP5 のリフレクションを使用してこの問題を始めましょう:

(まだ PHP4 を使用している学生は、立ち去らないでください。リフレクションのない PHP バージョンを使用している場合、またはリフレクションの目的で使用したくない場合は、互換性、アップグレードするかどうかは関係ありません、とにかくリフレクションを使用したくないのですが、以下に解決策があります)

$class = new ReflectionClass(&#39;FOO&#39;);
$foo = $class->newInstance(); //或者是$foo = $class->newInstanceArgs();
$foo->test();

何か見えましたか?次:

$class = new ReflectionClass(&#39;BAR&#39;);
$bar = $class->newInstanceArgs(array(55, 65));
$bar->test();

OK、それは良さそうなので、それを整理して、次のように設計したいと思います。この関数の最初の関数は、インスタンス化されるクラスの名前です。 2 番目のパラメーター。クラスのコンストラクターのパラメーターをインスタンス化するには、存在するだけ記述します。そうでない場合は、記述しないでください。変数の数を指定して関数を実装するには、次の 2 つの方法があります:

1 つ目は、次のようなメソッドです:

function foo($arg1, $arg2 = 123, $arg3 = &#39;test&#39;, $arg4 = null, ....... ) {
    //some code;
}

この方法には 2 つの欠点があります。パラメーターに 100 個? 2 つ目は、プログラム内のどのパラメータが null またはその他のデフォルト値であるかを判断する必要があることです。 (余談: この書き方ではパラメータのデフォルト値は最後に置く必要があります。デフォルト値のないパラメータをデフォルト値のあるパラメータの途中や前に挿入することはできません。それ以外の場合は、明示的にパラメータを挿入する必要もあります。 value)

パラメーターの数を可変にする別の方法は、PHP の 組み込み関数 func_get_args (ここをクリックしてマニュアルを参照) を使用して、渡されるパラメーターを取得することです。関数内の関数。同様の関数には func_get_num と func_get_arg があります。面倒なのでマニュアルを見つけて読んでください。

それで、私たちが想像した関数パラメータの配置に基づいて、コードは次のようになります:

function newInstance() {
    $arguments = func_get_args();
    $className = array_shift($arguments);
    $class = new ReflectionClass($className);
    return $class->newInstanceArgs($arguments);
}

OK、効果を見てみましょう:

$foo = newInstance(&#39;FOO&#39;);
$foo->test();
//输出结果:
//This is the method test of class FOO

$bar = newInstance(&#39;BAR&#39;, 3, 5);
$bar->test();
//输出结果:
//This is the method test of class BAR
//$this->a=3, $this->b=5

わずか 4 行のコードで、その効果は非常に完璧です。次に、このアイデアをクラスに適用すると、マジック メソッド として直接記述することができ、クラスをさらにクールにすることができます。

class INSTANCE {
    function call($className, $arguments) {
        $class = new ReflectionClass($className);
        return $class->newInstanceArgs($arguments);
    }
}
$inst = new INSTANCE();
$foo = $inst->foo();
$foo->test();
//输出结果:
//This is the method test of class FOO

$bar = $inst->bar(&#39;arg1&#39;, &#39;arg2&#39;);
$bar->test();
//输出结果:
//This is the method test of class BAR
//$this->a=3, $this->b=5

カカ、気持ちいいよ。

接下来讨论一下不使用反射类的情况。例如PHP4中就没有反射,而一些老项目就是运行在PHP4上面的。或者是要保证项目对未知环境的兼容性,Whatever,来关心一下怎么动态传参吧。PHP中动态传参的函数只有一个:call_user_func_array(轻击此处查看手册)。这是一个动态调用函数的函数,作用是可以将函数的参数以数组的形式传递给要调用的函数。好吧,我自己也被自己绕晕了,直接来看实例:

function foo($a, $b) {
    echo &#39;$a=&#39;, $a, &#39;<br />&#39;;
    echo &#39;$b=&#39;, $b;
}
call_user_func_array(&#39;foo&#39;, array(1, &#39;string&#39;));
//本例输出结果:
//$a=1
//$b=string

那么,要实现用这种方法来动态实例化对象并传参,呃……,只有曲线救国了,我们得先写一个函数,让这个函数来实例化对象,而这个函数的参数就原原本本地传给要实例化对象的类的构造函数就好了。打住!那这个函数得有几个参数啊?怎么实现传递不同个数的参数呢?嘿嘿,我一声冷笑,你忘了PHP里提供一个创建匿名函数的函数吗?(又开始绕起来了……)create_function(手册在此),照着手册里面的例子直接画就可以了,我也懒得打字了,直接看下面的代码,注释我写清楚点大家都明白了:

function newInst() {
    //取得所有参数
    $arguments = func_get_args();

    //弹出第一个参数,这是类名,剩下的都是要传给实例化类的构造函数的参数了
    $className = array_shift($arguments);

    //给所有的参数键值加个前缀
    $keys = array_keys($arguments);
    array_walk($keys, create_function(&#39;&$value, $key, $prefix&#39;, &#39;$value = $prefix . $value;&#39;), &#39;$arg_&#39;);

    //动态构造实例化类的函数,主要是动态构造参数的个数
    $paramStr = implode(&#39;, &#39;,$keys);
    $newClass=create_function($paramStr, "return new {$className}({$paramStr});");

    //实例化对象并返回
    return call_user_func_array($newClass, $arguments);
}

好了,至于效果是什么,就麻烦各位看官自己动动手,运行一下看看,是不是自己期望的结果。

如果改写成类里面的魔术方法,哼哼,威力嘛,你懂的!然后呢,我还是懒了,如果要写成魔术方法的话,相信这么easy的事情你很轻松就办到了。就当一个作业吧。另,本文的代码都是本人运行过的,但是,写文章的时候没有使用复制/粘贴功能,所以,你最好是也不要复制粘贴。如果从本文中的代码copy下来运行出错的话,还烦请各位自己debug一下,编程不就是要自己写么。

本来这个话题到这里就应该可以结束了,但是想到我在想到这个办法之前用的方法(好绕……),本着重在交流的态度,一起放出来。我例两个关键函数吧:extract和eval。只是我个人觉得用eval函数比较山寨,能不用最好不用。于是又想出了上面的办法,哈哈,编程最重要的是思想,不是吗?好,又是一道作业题了,大家可以试试用这两个函数(当然也会用到别的函数)来实现带不定数量的参数动态实例化对象的函数。

以上がオブジェクトを動的にインスタンス化し、コンストラクターにパラメータを渡すPHPのケース分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
負荷分散がセッション管理にどのように影響し、それに対処するかを説明します。負荷分散がセッション管理にどのように影響し、それに対処するかを説明します。Apr 29, 2025 am 12:42 AM

負荷分散はセッション管理に影響しますが、セッションの複製、セッションの粘着性、集中セッションストレージで解決できます。 1。セッションレプリケーションサーバー間のセッションデータをコピーします。 2。セッションスティンネスは、ユーザーリクエストを同じサーバーに指示します。 3.集中セッションストレージは、Redisなどの独立したサーバーを使用してセッションデータを保存してデータ共有を確保します。

セッションロックの概念を説明します。セッションロックの概念を説明します。Apr 29, 2025 am 12:39 AM

SESSIONLOCKINGISATECHNIQUESTOESUREAUSER'SSESSIONREMAINSEXCLUSIVETOONEUSATIME.ITISCRUCIALFORPREVENTINGDATACORTIONANDSECURITYBREACHESINMULTI-USERAPPLICATIONS.SESSIONLOCKINGISISIMPLEMENTEDUSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGROCKINGSMECHANISMなど

PHPセッションの選択肢はありますか?PHPセッションの選択肢はありますか?Apr 29, 2025 am 12:36 AM

PHPセッションの代替品には、Cookie、トークンベースの認証、データベースベースのセッション、Redis/Memcachedが含まれます。 1.Cookiesは、クライアントにデータを保存することによりセッションを管理します。 2.トークンベースの認証はトークンを使用してユーザーを検証します。これは非常に安全ですが、追加のロジックが必要です。 3.Databaseベースのセッションは、データベースにデータを保存します。これは、スケーラビリティが良好ですが、パフォーマンスに影響を与える可能性があります。 4. Redis/Memcachedは分散キャッシュを使用してパフォーマンスとスケーラビリティを向上させますが、追加のマッチングが必要です

PHPのコンテキストで「セッションハイジャック」という用語を定義します。PHPのコンテキストで「セッションハイジャック」という用語を定義します。Apr 29, 2025 am 12:33 AM

SessionHijackingとは、ユーザーのSessionIDを取得してユーザーになりすましている攻撃者を指します。予防方法には、次のものが含まれます。1)HTTPSを使用した通信の暗号化。 2)SessionIDのソースの検証。 3)安全なSessionID生成アルゴリズムの使用。 4)SessionIDを定期的に更新します。

PHPの完全な形式は何ですか?PHPの完全な形式は何ですか?Apr 28, 2025 pm 04:58 PM

この記事では、PHPについて説明し、その完全なフォーム、Web開発での主要な使用、PythonとJavaとの比較、および初心者の学習のしやすさについて説明します。

PHPはフォームデータをどのように処理しますか?PHPはフォームデータをどのように処理しますか?Apr 28, 2025 pm 04:57 PM

PHPは、$ \ _ postおよび$ \ _を使用してフォームデータを処理し、検証、消毒、安全なデータベースインタラクションを通じてセキュリティを確保します。

PHPとASP.NETの違いは何ですか?PHPとASP.NETの違いは何ですか?Apr 28, 2025 pm 04:56 PM

この記事では、PHPとASP.NETを比較して、大規模なWebアプリケーション、パフォーマンスの違い、セキュリティ機能への適合性に焦点を当てています。どちらも大規模なプロジェクトでは実行可能ですが、PHPはオープンソースであり、プラットフォームに依存しませんが、ASP.NET、

PHPはケースに敏感な言語ですか?PHPはケースに敏感な言語ですか?Apr 28, 2025 pm 04:55 PM

PHPの症例感度は変化します:関数は鈍感であり、変数とクラスは感度があります。ベストプラクティスには、一貫した命名と、比較のためにケース非感受性関数を使用することが含まれます。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール