php 指定したフォルダ内のファイルを全て読み込んでくれるメソッド
解決済
回答 5
投稿
- 評価
- クリップ 4
- VIEW 9,948
WEBページを制作する際に外部ソースの読み込みはできるだけまとめたいです。
例えば、phpで複数のクラスを定義しているファイルが「test」フォルダ内の「class」というディレクトリにあるとします。
また、「test」フォルダには
img←フォルダ
css←フォルダ
java←フォルダ
class←フォルダ
login.php
home.php
archive.php
logout.php
setting.php
等の主要ページがあります。
サイト制作するにあたり部品化(class)を作ることはよくあると思います。
私の場合はその部品は「class」フォルダに入れて
require('部品A');
require('部品B');
require('部品C');
require('部品D');
require('部品E');
というようにsetting.phpで呼び出して
require('setting.php');
というように最終的にはhome.phpやlogin.phpで呼び出してます。
これは主要ページでの呼び出す記述が一回で済むからです。
しかし、作る部品が多くなるにつれ、
setting.phpに記述するrequireも増えていくのでこれをなんとかしたいです。
例えば、指定したフォルダの中のファイルをすべて呼び出すメソッドなどはないのでしょうか?
それがあればわざわざsetting.phpを間に入れる必要もなくsetting.phpに記述するrequireもなくなり、
作った部品は「class」フォルダに入れるだけで勝手に読み込んでくれるので大変便利だと思います。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+8
全て呼び出すのは効率が悪いので,必要なときに必要なファイルだけ自動で呼び出すという仕組みが,PHPに用意されています.
// 例
spl_autoload_register(function ($classname) {
$path = __DIR__ . '/' . $classname . '.php';
if (file_exists($path)) {
require $path;
}
});
これをベースに更に規約を設けて,オートローディングのための関数すら自分で書く必要を無くした仕組みを導入したものが,PHPのパッケージマネージャ「Composer」として用意されています.PSR-4という規約(あるいは旧式のPSR-0)に則ってクラスを作成およびファイルを配置すれば,PHPが提供しているspl_autoload_register
という関数を利用して自動的に読み込みを行ってくれます.
この仕組みは,他者が提供しているライブラリをcomposer install
でインストールした場合だけでなく,自分のプロジェクト内のファイルに対しても適用が可能です.composer install
あるいはcomposer update
のタイミングで,自分のプロジェクト内の各クラスに対するオートローダが定義されます.
なお大前提として,ディレクトリ構成からして変えたほうがいいかと思います.HTTPでアクセスする必要のないファイルは公開ディレクトリの外に起きましょう.例えば以下の例ではwww
を公開ディレクトリとし,http://example.com/archive.php
がproject/www/archive.php
に対応することを想定しています.
project
|--.git
|--composer.json
|--vendor
| `--autoload.php
|--class
| |--controller
| |--model
| `--view
`--www
|--css
|--img
|--js
|--archive.php
|--home.php
|--login.php
`--setting.php
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
glob()
関数でファイルリストを取ってきて、1つずつrequire
すれば、できることはできます(StackOverflow)。
foreach (glob("path/to/*.php") as $filename)
{
irequire $filename;
}
ただし、このようなやり方でPHPファイルを読み込んだ場合、攻撃者からすると、取ってくる場所にPHPファイルを置くことができれば自動的に実行されるようになりますので、セキュリティ面では危険性があるかもしれません(もちろん、実稼働に際してファイルを置かれないのが大前提ではありますが)。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
checkベストアンサー
0
こんにちは。
書き方は下記のような形になります。
_CLASS_DIRはdefineで設定しております。
//----------------------------------------------------
// クラスファイルの読み込み
//----------------------------------------------------
function autoloader($className){
require_once _CLASS_DIR . $className . ".php";
}
spl_autoload_register("autoloader");
?>
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
setting.phpがindex.phpやlogin.phpと同じ階層にあると仮定します。
setting.php内に以下のコードを記述して下さい。
そして、各index.phpやlogin.php内でsetting.phpを読み込んで下さい。
$scan_dirsに自動で読み込ませたいフォルダを配列で渡しています。
以下コードはPHP5.4以上で動作します。
spl_autoload_register(function ($class_name) {
$scan_dirs = [
__dir__.'/class/check',
__dir__.'/class/get',
];
foreach ($scan_dirs as $scan_dir) {
$include_path = $scan_dir.'/'.$class_name.'.php';
if (is_readable($include_path)) {
require_once $include_path;
break;
}
}
});
新たに読み込むディレクトリを増やしたい場合は、以下のように配列に追加すれば良いです。
spl_autoload_register(function ($class_name) {
$scan_dirs = [
__dir__.'/class/check',
__dir__.'/class/get',
// ↓新しく3つの読み込むディレクトリを増やす
__dir__.'/class/newdir1',
__dir__.'/class/newdir2',
__dir__.'/class/newdir3',
];
foreach ($scan_dirs as $scan_dir) {
$include_path = $scan_dir.'/'.$class_name.'.php';
if (is_readable($include_path)) {
require_once $include_path;
break;
}
}
});
【イメージ】
// インスタンス化
$user = new User();
↑Userクラスがまだ読み込まれていない場合は、通常エラーが発生しますが、オートロード設定をしていると、以下の様な流れになります。
// ↓Userが引数として渡される
spl_autoload_register(function ('User') {
// ↓以下のようなイメージ
foreach ($scan_dirs as $scan_dir) {
$include_path = $scan_dir.'/User.php';
if (is_readable($include_path)) {
require_once $include_path;
break;
}
}
わかりにくい説明ですが、このような流れです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
上記のrentoさんのコードで間違っている箇所は4箇所あります。
// lead.php
// 間違い1カ所目(一部抜粋)
__dir__.'class/test1',
__dir__.'class/test2',
// 正しくは
__dir__.'/class/test1',
__dir__.'/class/test2',
// index.php
// 間違い2カ所目
echo test1::method1;
echo test2::method2;
// 正しくは
echo test1::method1();
echo test2::method2();
// test1.php
// 間違い3カ所目
class test1{
function method1(){
$test1 = "test1読み込めました";
return $test1;
}
}
// 正しくは
class test1
{
public static function method1()
{
$test1 = "test1読み込めました";
return $test1;
}
}
// test2.php
// 間違い4カ所目
class test2{
function method2(){
$test2 = "test2読み込めました";
return $test2;
}
}
// 正しくは
class test2
{
public static function method2()
{
$test2 = "test2読み込めました";
return $test2;
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.36%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/06/09 22:12
使い方が分からずです...
返事遅れてすみません!
時間があるときに具体的な内容でまたこちらで質問してみますので
もしよろしければお願いします。
これはまだ解決していないのでこのままにしておきます。
2016/06/09 22:23
PHPがまだ読み込んでないクラスを使おうとする
↓
spl_autoload_registerで登録した関数が呼び出されるので,第1引数に渡されてきたクラス名を表す文字列をもとにrequireを行う
↓
エラーを回避できる (上でrequireしなければエラーになる)
という流れになります.