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

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

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

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

Q&A

解決済

5回答

15200閲覧

php 指定したフォルダ内のファイルを全て読み込んでくれるメソッド

earnest_gay

総合スコア615

PHP

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

0グッド

4クリップ

投稿2016/06/02 06:44

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」フォルダに入れるだけで勝手に読み込んでくれるので大変便利だと思います。

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

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

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

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

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

guest

回答5

0

全て呼び出すのは効率が悪いので,必要なときに必要なファイルだけ自動で呼び出すという仕組みが,PHPに用意されています.

php

1// 例 2spl_autoload_register(function ($classname) { 3 $path = __DIR__ . '/' . $classname . '.php'; 4 if (file_exists($path)) { 5 require $path; 6 } 7});

これをベースに更に規約を設けて,オートローディングのための関数すら自分で書く必要を無くした仕組みを導入したものが,PHPのパッケージマネージャ「Composer」として用意されています.PSR-4という規約(あるいは旧式のPSR-0)に則ってクラスを作成およびファイルを配置すれば,PHPが提供しているspl_autoload_registerという関数を利用して自動的に読み込みを行ってくれます.

この仕組みは,他者が提供しているライブラリをcomposer installでインストールした場合だけでなく,自分のプロジェクト内のファイルに対しても適用が可能です.composer installあるいはcomposer updateのタイミングで,自分のプロジェクト内の各クラスに対するオートローダが定義されます.

なお大前提として,ディレクトリ構成からして変えたほうがいいかと思います.**HTTPでアクセスする必要のないファイルは公開ディレクトリの外に起きましょう.**例えば以下の例ではwwwを公開ディレクトリとし,http://example.com/archive.phpproject/www/archive.phpに対応することを想定しています.

html

1project 2|--.git 3|--composer.json 4|--vendor 5| `--autoload.php 6|--class 7| |--controller 8| |--model 9| `--view 10`--www 11 |--css 12 |--img 13 |--js 14 |--archive.php 15 |--home.php 16 |--login.php 17 `--setting.php

投稿2016/06/02 06:59

編集2016/06/09 13:26
mpyw

総合スコア5223

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

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

earnest_gay

2016/06/09 13:12

spl_autoload_registerは便利だと聞きますが 使い方が分からずです... 返事遅れてすみません! 時間があるときに具体的な内容でまたこちらで質問してみますので もしよろしければお願いします。 これはまだ解決していないのでこのままにしておきます。
mpyw

2016/06/09 13:23

大雑把に言うと PHPがまだ読み込んでないクラスを使おうとする ↓ spl_autoload_registerで登録した関数が呼び出されるので,第1引数に渡されてきたクラス名を表す文字列をもとにrequireを行う ↓ エラーを回避できる (上でrequireしなければエラーになる) という流れになります.
guest

0

glob()関数でファイルリストを取ってきて、1つずつrequireすれば、できることはできます(StackOverflow)。

php

1foreach (glob("path/to/*.php") as $filename) 2{ 3 irequire $filename; 4}

ただし、このようなやり方でPHPファイルを読み込んだ場合、攻撃者からすると、取ってくる場所にPHPファイルを置くことができれば自動的に実行されるようになりますので、セキュリティ面では危険性があるかもしれません(もちろん、実稼働に際してファイルを置かれないのが大前提ではありますが)。

投稿2016/06/02 06:50

maisumakun

総合スコア145121

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

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

earnest_gay

2016/06/09 13:10

セキュリティー面では脆弱性があるのですね... my_sql_autolooderというのがあるみたいなんですが使い方が分からず...
guest

0

上記のrentoさんのコードで間違っている箇所は4箇所あります。

PHP

1// lead.php 2 3// 間違い1カ所目(一部抜粋) 4__dir__.'class/test1', 5__dir__.'class/test2', 6 7// 正しくは 8__dir__.'/class/test1', 9__dir__.'/class/test2',

PHP

1// index.php 2 3// 間違い2カ所目 4echo test1::method1; 5echo test2::method2; 6 7// 正しくは 8echo test1::method1(); 9echo test2::method2();

PHP

1// test1.php 2 3// 間違い3カ所目 4class test1{ 5 function method1(){ 6 $test1 = "test1読み込めました"; 7 return $test1; 8 } 9} 10 11// 正しくは 12class test1 13{ 14 public static function method1() 15 { 16 $test1 = "test1読み込めました"; 17 return $test1; 18 } 19}

PHP

1// test2.php 2 3// 間違い4カ所目 4class test2{ 5 function method2(){ 6 $test2 = "test2読み込めました"; 7 return $test2; 8 } 9} 10 11// 正しくは 12class test2 13{ 14 public static function method2() 15 { 16 $test2 = "test2読み込めました"; 17 return $test2; 18 } 19}

投稿2016/06/10 18:49

編集2016/06/10 18:55
manto

総合スコア14

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

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

earnest_gay

2016/06/10 19:31

おおお!ありがとうございます! methodで()つけてませんでしたね... 時間あるときに試してみます!
earnest_gay

2016/06/10 23:04

できました! ありがとうございます!
guest

0

setting.phpがindex.phpやlogin.phpと同じ階層にあると仮定します。
setting.php内に以下のコードを記述して下さい。
そして、各index.phpやlogin.php内でsetting.phpを読み込んで下さい。

$scan_dirsに自動で読み込ませたいフォルダを配列で渡しています。
以下コードはPHP5.4以上で動作します。

PHP

1spl_autoload_register(function ($class_name) { 2 $scan_dirs = [ 3 __dir__.'/class/check', 4 __dir__.'/class/get', 5 ]; 6 foreach ($scan_dirs as $scan_dir) { 7 $include_path = $scan_dir.'/'.$class_name.'.php'; 8 if (is_readable($include_path)) { 9 require_once $include_path; 10 break; 11 } 12 } 13});

新たに読み込むディレクトリを増やしたい場合は、以下のように配列に追加すれば良いです。

PHP

1spl_autoload_register(function ($class_name) { 2 $scan_dirs = [ 3 __dir__.'/class/check', 4 __dir__.'/class/get', 5 // ↓新しく3つの読み込むディレクトリを増やす 6 __dir__.'/class/newdir1', 7 __dir__.'/class/newdir2', 8 __dir__.'/class/newdir3', 9 ]; 10 foreach ($scan_dirs as $scan_dir) { 11 $include_path = $scan_dir.'/'.$class_name.'.php'; 12 if (is_readable($include_path)) { 13 require_once $include_path; 14 break; 15 } 16 } 17});

【イメージ】
// インスタンス化
$user = new User();
↑Userクラスがまだ読み込まれていない場合は、通常エラーが発生しますが、オートロード設定をしていると、以下の様な流れになります。

PHP

1// ↓Userが引数として渡される 2spl_autoload_register(function ('User') {

PHP

1 // ↓以下のようなイメージ 2 foreach ($scan_dirs as $scan_dir) { 3 $include_path = $scan_dir.'/User.php'; 4 if (is_readable($include_path)) { 5 require_once $include_path; 6 break; 7 } 8 }

わかりにくい説明ですが、このような流れです。

投稿2016/06/10 02:08

編集2016/06/10 03:11
manto

総合スコア14

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

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

earnest_gay

2016/06/10 11:02

下記のディレクトリ構成で試しましたが読み込めないです... 「testフォルダ」 |index.php |lead.php |ー「classフォルダ」   |   |ー「test1フォルダ」   | |test1.php   |    |ー「test2フォルダ」     |test2.php      【index.php】 <?php require('lead.php'); echo test1::method1; echo test2::method2; ?> 【lead.php】 <?php spl_autoload_register(function ($class_name) { $scan_dirs = [ __dir__.'class/test1', __dir__.'class/test2', ]; foreach ($scan_dirs as $scan_dir) { $include_path = $scan_dir.'/'.$class_name.'.php'; if (is_readable($include_path)) { require_once $include_path; break; } } }); ?> 【test1.php】 <?php class test1{ function method1(){ $test1 = "test1読み込めました"; return $test1; } } ?> 【test2.php】 <?php class test2{ function method2(){ $test2 = "test2読み込めました"; return $test2; } } ?>
guest

0

ベストアンサー

こんにちは。
書き方は下記のような形になります。
_CLASS_DIRはdefineで設定しております。

//----------------------------------------------------
// クラスファイルの読み込み
//----------------------------------------------------
function autoloader($className){
require_once _CLASS_DIR . $className . ".php";
}
spl_autoload_register("autoloader");

?>

投稿2016/06/09 13:20

UponAStar

総合スコア56

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

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

earnest_gay

2016/06/09 13:25

回答ありがとうございます! function autoloader($className){ require_once _CLASS_DIR . $className . ".php"; } 使うときはautoloader();で使うと思うのですが、 因数の$classNameには何を入れたらいいのでしょうか? spl_autoload_register("autoloader");のautoloaderはなんなのでしょうか? 使い方というよりは、因数に入力した~~が~~で~~で、という風に仕組みを説明頂けると理解できそうなところまできています。 すみませんが宜しくお願いします。
UponAStar

2016/06/09 13:42

$classNameには事前に何も入れる必要はありません。 spl_autoload_registerに関数を渡すと自動的にディレクトリ内の ファイル名を読み込んでくれます。 記述はこれ以外に必要ありません。
earnest_gay

2016/06/09 13:47

つまり、上記の記述でlooder.phpなどというファイルを作り 例えば「A」というフォルダ内に入れていたら 「Aフォルダ」にあるphpファイルを全部読み込んでくれる...ということですか? 仮にそうだった場合 ①「Aフォルダ」にあるphpファイルがlooder.phpに集約される ②読み込みたいファイルでrequire('looder.php');と使えばいい という認識であってますか?
UponAStar

2016/06/09 13:48

言い方を間違えました。まだ読み込んでないクラスをrequireした場合 $classNameに格納され、,インスタンス化の前にrequireされます。 その都度一つずつ行うようです。
UponAStar

2016/06/09 13:50

使い方はそれで間違いないかと思います。 index.phpなどでloader.phpをrequireしておけばよいです。
earnest_gay

2016/06/09 14:27 編集

なるほど! setting.phpで何回もrequireやっていることを autoloaderは自動でやってくれるのですね! 読み込んでようがなかろうが、最終的にはautoloaderが拾ってくれるってことですよね。 また疑問が浮かんできたのですがベストアンサーまでお付き合いいただければと思います。 「testフォルダ」 |index.php |login.php |logout.php | |ー「classフォルダ」   |   |ー「checkフォルダ」   |name.php   |email.php   |password.php   |loader.php   |   |ー「getフォルダ」   |birthday.php   |pref.php   |sex.php   |loader.php パッと作ったので分かりやすくはないと思いますが、 クラスをフォルダ毎に分類していた場合は 各フォルダにloader.phpを用意してないといけないですよね? この場合、index.phpでloader.phpを読み込むには require('class/check/loader.php'); require('class/get/loader.php'); ってなりますよね。 できれば1回のrequiredで 「checkフォルダ」のクラスも 「getフォルダ」のクラスも 読み込みたいのですが それは不可能でしょうか? 「getフォルダ」のloader.phpが「checkフォルダ」のクラスも読みに行くわけは... ないですよね?????
earnest_gay

2016/06/10 10:53

今普通の使い方で試してみたのですが全然読み込めないです... Use of undefined constant _CLASS_DIR - assumed '_CLASS_DIR'
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問