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

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

ただいまの
回答率

87.48%

コントローラーの複数アクションメソッドで共通する処理を外出ししたらPHP 5.3でfatal error

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,199
退会済みユーザー

退会済みユーザー

前提・実現したいこと

一旦動作確認を取ったFuelPHPで作った処理を、アクションメソッド内で行うフォーム作成やバリデーションまわりを共通処理としてアクションメソッドの外に出そうとしたところ、ハマってしまいました。
起因はPHP5.3系の問題らしいのですが、回避する方法を知りたいです。
分析用パラメータをフォーム送信にて受信し、集計結果をHTMLの表にするか、CSV出力するか、PDF出力するか、でアクションメソッドを分けていて、どれも分析用パラメータの項目は同じで受付可能な条件も同じなため、共通化しようとしました。

発生している問題・エラーメッセージ

Fatal error: Cannot access self:: when no class scope is active in /home/XXXXXX/fuelphp/fuel/app/classes/controller/kobu.php on line 622

該当のソースコード

case '8': /* レディース */
    if ($p_include['brand']['8'][0] == '')
    {
        $err_flg = true;
        Validation::active()->set_message('include_1', '絞込 レディースブランド指定が正しくありません。');
        return false;
    } elseif ($p_include['brand']['8'][0] != 'all')
    {
        if (!array_key_exists($p_include['brand']['8'][0], self::$arr_brd_8))    //// <- ここが622行め
        {
            $err_flg = true;
            Validation::active()->set_message('include_1', '絞込 レディースブランド指定が正しくありません。');
            return false;
        }
    }
    break;


$arr_brd_8の宣言箇所は

class Controller_Kobu extends Controller_Tmplcmn
{
    static $arr_brd_1, $arr_brd_2, $arr_brd_3, $arr_brd_8, $arr_brd_9;
    static $arr_ib;

試したこと

$arr_brd_8らを、先に単にpublicとして、$this->arr_brd_8などとしてアクセスしていて、ローカルでは動作確認が取れました。
それをサーバーにアップロードしたら「Using $this when not in object context」っていうfatal errorになりました。
回避する方法を探して、static宣言にしたり、self::$arr_brd_8としてアクセスするように書き換えて、ローカルでは動作確認が取れましたが、サーバーでは「Cannot access self:: when no class scope is active」というfatal errorになりました。

補足情報(言語/FW/ツール等のバージョンなど)

FuelPHP v1.7.2
ローカルテスト環境:PHP 5.4.16
サーバー実行環境:PHP 5.3.15
現状の経緯をブログに書いております:FuelPHPもPHP 5.4以降が必須なのかなぁ

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

+2

 Fatal error: Cannot access self:: when no class scope is active

PHP5.3系だと、$thisが自動的にクロージャに束縛されないのが原因ぽいですね。
5.3も考慮するなら、コントローラ自身(もしくは設定値だけまとめて)をuseで明示的に
渡してあげればいけると思います。

//プロパティのstaticを外して元に戻す

$self = $this;
return function () use ($self) {
    $self->arr_brd_8; //使える
}

クロージャ が $this をサポートするようになりました。

PHP 5.3.x から PHP 5.4.x への移行
http://php.net/manual/ja/migration54.new-features.php

php 5.4 リポジトリに舞い戻ってきたクロージャの $this サポート
http://d.hatena.ne.jp/do_aki/20110727/1311767728


 Cannot access self:: when no class scope is active

こちらのエラーも5.3だと無名関数内のスコープでselfを解決できないのが原因だと
思うのですが、ソースは見つけられませんでした。
(クラス外でself::hogeと書いても同じエラーが出ます)

罠っぽい

// 試行バージョン PHP5.6.13

class Hoge
{
    static $value = 'parent';

    public static function callSelf()
    {
        return self::$value;
    }

    public static function callStatic()
    {
        return static::$value;
    }

    public static function callClosureSelf()
    {
        return function () {
            return self::$value;
        };
    }
}

class HogeSub extends Hoge
{
    static $value = 'sub';
}

$closureSelf = HogeSub::callClosureSelf();

var_dump(
    HogeSub::callSelf(),   // parent
    HogeSub::callStatic(), // sub
    $closureSelf()         // sub
);

self:: の制限

self:: あるいは CLASS による現在のクラスへの静的参照は、 そのメソッドが属するクラス (つまり、 そのメソッドが定義されているクラス) に解決されます。 

遅延静的束縛
http://php.net/manual/ja/language.oop5.late-static-bindings.php

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/06/21 17:28

    あぁ、そっか。useで明示的に渡す方法がありましたね。書き方を示していただいてありがとうございます。

    キャンセル

checkベストアンサー

+1

"該当のソースコード"は、無名関数の中に記述されていませんか?
であれば、self::Controller_Kobu::に変更してみてはいかがでしょうか?

私もイマイチ理解していないのですが、無名関数のスコープは、単純に親クラスのそれを引き継いでいるわけではないようです。
http://php.net/manual/ja/functions.anonymous.php

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/06/21 15:25

    ご指摘のとおり、無名関数の中に書いておりました。
    バリデーションルールを定義する無名関数の中でした。
    ご指摘のように書きなおしてみたところ、fatal errorがまるでウソだったように動いてくれています。ありがとうございます。

    キャンセル

0

回答ではありませんが、PHP開発ではサーバごとのPHPバージョンを「5.3」や「7.0」のように、最低限0.1までは揃えておきましょう。

PHPの場合、5.3と5.4で変化することがよくありますし、以前に5.3.3と5.3.14の違いにハマったことすらあります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/06/21 13:21

    ほんと、そうなんですよね。Windows版XAMPPを設定した時から既にバージョンがずれていたようでして。大丈夫だろうと思っていて、まさかこんなふうになるとは。

    キャンセル

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

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

関連した質問

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

  • トップ
  • PHPに関する質問
  • コントローラーの複数アクションメソッドで共通する処理を外出ししたらPHP 5.3でfatal error