質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.35%

  • PHP

    25493questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

[PHP] __callStaticで詰んでいます。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 969

yoshiky

score 105

お世話になってます。 PHPの__callStaticで定義された関数を呼ぶにあたり、

publicとprivateの中でそれぞれ呼ぼうとしたら「Cannot redeclare」の定義済みエラーになってしまいました。

しかし先に呼ばれる箇所にのみ書くようにすると、今度は2番目以降で「Call to a member function xxx on a non-object in」と、未定義扱いになってしまいます。。

PHPに詳しくないので基本的なミスかもしれませんが、 些細な点でもかまわないので、アドバイスいただきたく、お願いいたします。 情報が不足していたら追記します。取り急ぎ、対象のソースです。

class libCrypt
{
    public static function __callStatic($class, $args)
    {
        function exeClassAutoLoad($class) {
            require_once("$class"."php");
        }
        spl_autoload_register("exeClassAutoLoad");
        return new $class($args[0]);
    }
}
class Point extends My_Controller
{

    public function Hoge()
    {
        $objCrypt = libCrypt::Aes256Cbc('sec_key'); # Aes256Cbc が上の$classにあたります。    
        $strDeCrypt = $objCrypt->exeEnCrypt($fuga); #exeDeCrypt はAes256Cbcにpublicで定義しているメソッドです。
        ・・・
        $this->_bar($data);
    }

    private function _bar($data)
    {
        $objCrypt = libCrypt::Aes256Cbc('sec_key'); # これを書くとPHP Fatal error:  Cannot redeclare exeClassAutoLoad()
        $strDeCrypt = $objCrypt->exeDeCrypt($data); # 上を書かないとここで Call to a member function exeDeCrypt() on a non-object
    }
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

spl_autoload_register を使う必要ないと思います。
__callStatic が直接 require_once すれば大丈夫です。

class libCrypt
{
    public static function __callStatic($class, $args)
    {
        require_once("$class"."php"); // ちなみにこれ、ドットが入らないと思いますが大丈夫ですか
        return new $class($args[0]);
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/14 19:53

    早速のご回答ありがとうございます!

    ご指摘のとおりspl_autoload_registerを外したら2回呼んでも
    エラーになりませんでした。

    これで確認してみます。助かりました。ありがとうございました。

    > // ちなみにこれ、ドットが入らないと思いますが大丈夫ですか
    こちらは require_once($class.".php"); でした。質問にあたり間引いた箇所ですので問題なしです。
    ご指摘ありがとうございます。

    キャンセル

  • 2015/12/14 19:59

    あ、いやでも spl_autoload_register は、正しく使えば便利です。
    使い方を学んでおくに越したことはありません。

    spl_autoload_register はご提示のコードのように、クラスをインクルードしたい時にインクルードするための処理を「自分で」呼び出す必要が無いことがメリットです。
    つまり、libCrypt::__callStatic というクラスをロードするための処理をいちいち実行しなければならないようにしてしまうと、全然有り難みを享受できません。

    // 一旦関数宣言せずに書くこともできます。
    spl_autoload_register(function($className) {
    $className = str_replace('\\', DIRECTORY_SEPARATOR, $className); // 一応 \ は / にしておく。
    include $className . ".php";
    });

    これをすべてのコードの前で1回だけ実行すれば、普通にクラスを作ろうとした時点で勝手にインクルードされます。

    ストレートに $objCrypt = new Aes256Cbc('sec_key'); と書けます。
    うまくいかない場合は、インクルードパスの問題かもしれません。
    http://php.net/manual/ja/function.get-include-path.php

    キャンセル

  • 2015/12/15 10:06

    アドバイスありがとうございます!
    __callStaticとspl_autoload_registerはともに「未定義関数にアクセスした際に呼ばれる」という程度の理解なので、使い方までご提示いただけて助かります。

    > これをすべてのコードの前で1回だけ実行すれば、普通にクラスを作ろうとした時点で勝手にインクルードされます。

    ほかのクラスでも使う箇所が多そうなので、簡単に使えるようにしておいたほうがいいですね。検討します!

    キャンセル

  • 2015/12/16 14:49

    あ、細かいのですが、
    > __callStaticとspl_autoload_registerはともに「未定義関数にアクセスした際に呼ばれる」という程度の理解
    __callStatic の対象は未定義ではなく、アクセス不能なメソッドです。
    private 宣言されたものを外から呼んだ時が含まれます。

    spl_autoload_register は関数とは無関係です。未定義のクラスのみです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • PHP

    25493questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。