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

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

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

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

Q&A

解決済

2回答

3667閲覧

特定クラスからの呼び出しを禁止する実装方法はどうすればいいですか。

matsujin_

総合スコア25

PHP

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

1グッド

0クリップ

投稿2016/07/20 04:33

現在、セッション情報を取得するSessionクラスがあり色々なところで利用されています。

ですが、特定クラスからSessionクラスを操作してセッション情報のデータを変えたり、取得するのを禁止したいです。
特定クラスからSessionクラスにアクセスされた場合は、例外をなげるようにできればと思っています。

実装をする人が気がつければいいのですが、特定クラスは不特定多数の人がさわり、たまにしか触らないので
忘れて間違えてSessionクラスから情報を操作するのを防ぎたいです。

ちなみに最初に思いついた実装方法は、Sessionクラスのすべてのメソッドの引数にクラスを渡して、特定クラスだったら例外を出すように考えましたが、Sessionクラスが使われているところが多くてバグにつながるのと、Sessionクラスのメソッド(public,static)の数も多いのでチェックの関数を入れるのも大変なのであきらめました。

もっとシンプルで既存のソースに影響がない方法でSessionクラスのメソッドが呼び出されたら際に自動でチェックする実装方法がありましたら、教えて頂けますでしょうか。

よろしくお願いします。

tanat👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

Kosuke_Shibuyaさんの回答から丸パクリですが・・・

php

1<?php 2 3class Session { 4 private function check() { 5 $classes = ['test2']; //禁止したいclass 6 $info = debug_backtrace(); 7 $class = $info[count($info) - 1]['class']; 8 if (in_array($class, $classes)) { 9 throw new Exception('You may not use this method.'); 10 } 11 } 12 13 public static function test() { 14 self::check(); // 制限を掛けたいmethodにこれを書く。 15 echo "OK\n"; 16 } 17} 18 19class test1 { 20 function aa() { 21 Session::test(); 22 } 23} 24 25class test2 { 26 function aa() { 27 Session::test(); 28 } 29} 30 31(new test1)->aa(); 32(new test2)->aa();
-----出力 OK Fatal error: Uncaught exception 'Exception' with message 'You may not use this object.' in ~~ ```ちょっと実証コードを載せます。 `foo`クラスの`check`メソッドの`$classes`に禁止したいclassを入れます。 そして制限したいメソッドの頭に`self::check()`を入れてチェックさせます。 これだと、新しいstaticメソッドが一個と、それぞれのメソッドに一行追加するだけなので、やりやすいのではないでしょうか?

投稿2016/07/20 09:14

shi_ue

総合スコア4437

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

matsujin_

2016/07/21 01:05

細かく解説して頂きありがとうございます。 今回、対応しそうなstaticメソッドが20近くありそうだったので、すべて入れるのが大変そうなると、次にSessionにstaticメソッドを追加する人が入れ忘れる場合があるのを懸念いたしました。 でも、今回は自分の技量を考えるとこれがベストだと感じました。 そもそも、Sessionクラスの設計がここまでの用途に作られていないんだなと気づけ、今後の設計にとても勉強になりました。 ありがとうございました。
guest

0

ベストアンサー

コンストラクタでフィルタリングすればいいのでは?

get_called_class()
debug_backtrace()


php<?php

1 2class Sample 3{ 4 5 private static $forbidenClass = [ 6 'Sample2' 7 ]; 8 9 private static function init() 10 { 11 $trace = debug_backtrace(); 12 foreach ($trace as $dbg) { 13 if ($dbg['class'] != __CLASS__ && 14 in_array($dbg['class'], self::$forbidenClass)) { 15 $msg = sprintf('%s クラスから呼ぶことは禁止されています。', $dbg['class']); 16 throw new \Exception($msg); 17 } 18 } 19 } 20 21 public static function method() 22 { 23 self::init(); 24 return true; 25 } 26 27} 28 29class Sample2 30{ 31 32 public static function method() 33 { 34 Sample::method(); 35 } 36 37} 38 39try { 40 Sample2::method(); 41} catch (Exception $e) { 42 var_dump($e); 43}

投稿2016/07/20 04:36

編集2016/07/20 16:37
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shi_ue

2016/07/20 04:48 編集

横から失礼。get_called_classは Session が返って来そうです。
matsujin_

2016/07/20 04:48

返答ありがとうございます。 ほとんどのメソッドがstaticで実装されていたので、コンストラクタのことが完全に考えからぬけておりました。 イニシャライザを使ってフィルタリングを試してみたいと思います。
退会済みユーザー

退会済みユーザー

2016/07/20 04:49

Sessionクラスの実装次第ですね。static メソッドしかないようなクラスなら Session::method() になると思います。
shi_ue

2016/07/20 05:01

debug_backtrace !! そんな手があったか・・・
退会済みユーザー

退会済みユーザー

2016/07/20 05:04

autoload でゴニョゴニョする方法もあるかもしれませんんが、__construct() で debug_backtrace() を使う方が、シンプルにかけると思います。
matsujin_

2016/07/20 06:19

publicメソッドについては確認できました。 ありがとうございます。 PHPにstaticイニシャライザがないのですね。 はじめて知りました・・・。 イニシャライザ作成は自分の技量とコストを考えて今回は見送りました。 Session::method()についてですが、コンストラクタの代わりという意味なのでしょうか? そうすると別のstaticメソッドが呼ばれてしまうと駄目だしと思っていて実装が見えていないのですが、教えて頂けますでしょうか。
matsujin_

2016/07/21 00:52

細かく書いて頂いてありがとうございます。 とても参考になりました。 やはり、staticメソッドすべてにこのチェックをいれなければいけなさそうですね。 ありがとうございましたm_ _m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問