- 投稿日:2020-03-25T23:27:54+09:00
PHP ユーザー関数定義 引数 スコープ などなどメモ
記事を書いた人
PHP勉強中の初心者です。
はじめてユーザー関数を使ってコードの短絡化に挑戦した時に混乱したことをまとめてみました。記事の対象者
自分と同じような初心者の方のお役に立てればと思います。
開発環境
PHP 7.3.11
OS macOS Catalina ver. 10.15.3関数とは
変数を「値を入れる箱」というならば、関数は「一連の処理を入れておく箱」のようなイメージでしょうか。
関数には2種類あります。
1. 組み込み関数
2. ユーザー定義関数組み込み関数とは、PHPに元々用意してある関数のこと。例えばmb_strlen()とかisset()とか。
膨大な数の関数が用意されています。ユーザー定義関数とは、自分で作る関数です。
作成するメリットとしては
1. 繰り返し登場する処理を何度も書かずに済む
2. 繰り返し登場する処理に編集が必要になった際、関数化してあれば関数を編集するだけで済む
3. コードの短絡化が出来て、可読性が上がる
といったところでしょうか。function.phpfunction echoHello(){ echo "hello"; }といった感じで作成します。
関数化で躓いたところ(1)
変数のスコープ
「スコープ」とは、参照可能な範囲のことを言います。
例えば、以下のユーザー定義関数には5つの登場人物がいます。
定数(1)(2)、変数(3)(4)(5)(6)、関数(7)です。function.phpconst DSN='mysql:dbname=hage;host=localhost;charset=utf8mb4'; define("CONSTANT", "Hello world."); $message = "Hello"; $_POST['message'] = "Hello"; function hage($x, $y){ // ┐ echo DSN . "\n"; //(1) │ echo CONSTANT. "\n"; //(2) │ echo $message. "\n"; //(3) │ ☆ echo $_POST['message'] ."\n"; //(4) │ echo $x. "\n"; //(5) │ echo $y. "\n"; //(6) │ } // ┘ hage(100, $message); //(7)この関数を実行するとどうなるでしょうか。
qiita.phpmysql:dbname=hage;host=localhost;charset=utf8mb4//(1) Hello world.//(2) Notice: Undefined variable: message in /Applications/XAMPP/xamppfiles/htdocs/trial/trial.php on line 160 //(3) Hello//(4) 100//(5) Hello//(6)(3)のところでNoticeエラーが発生します。
$message
変数は定義されていないと怒られます。
私はここで混乱しました。だって$message
は定義したと思っていたからです。ここで、先ほど言及したスコープの登場です。
それぞれの登場人物の「参照可能な範囲 = スコープ」を見ていきます。
①定数のスコープ → グローバル。つまり、ソースコードのどこからでも呼び出し可能
(1)(2)共に関数の外で定義しましたが関数内に呼び出す事ができました。
②関数のスコープ → グローバル。つまり、ソースコードのどこからでも呼び出し可能
(7)で、hageを呼び出すことに成功しています。
③スーパーグローバル変数のスコープ → グローバル。つまり、ソースコードのどこからでも呼び出し可能
PHPが用意している特殊な変数です。$_SESSION
,$_REQUEST
などがあります。
(https://www.php.net/manual/ja/language.variables.superglobals.php)
④変数のスコープ → それを定義したレベルでのみ呼び出し可能
つまり、関数内で定義した変数は関数内だけで有効。関数外で定義した変数とは変数名が同じでも別物ということです。(3)の$messageは☆マークの範囲内でしか読み書き出来ません。
ここが躓きポイントでした。関数化で躓いたところ(2)
引数について
引数とは、上のコードでいうと
qiita.phpfunction hage($x, $y){の
$x
,$y
の事です。$x
は第一引数、$y
は第二引数と呼ばれます。
また厳密に言うと、$x
,$y
は「仮引数」と呼ばれます。
仮引数は必ず変数になります。その値は関数が呼び出される時に決まります。上記のコードで言うと、以下のように関数の引数を設定して値を決めています。
qiita.phphage(100, $message); //(7)上記の100,
$message
を実引数と呼びます。
ここでは、「仮引数の$x
に実引数100を、仮引数の$y
に実引数の$message
を渡している」、
または、「仮引数に実引数(100と$message
)を指定して、関数hage()を呼び出している」
と、言えますね。関数呼び出し時に引数を設定し忘れると致命的なエラーを吐きます。
qiita.phphage(); //(1) hage($message); //(2) //Fatal error: Uncaught ArgumentCountError: Too few arguments to function hage(),... (3)(1)は実引数の指定忘れ、(2)は実引数が一つ足りません。hage関数では仮引数を2つ設定したので、実引数も2つ渡してあげないといけません。
では、関数に引数を設定しないとどうなるでしょうか。
qiita.phpconst DSN='mysql:dbname=hage;host=localhost;charset=utf8mb4'; define("CONSTANT", "Hello world."); $message = "Hello"; $_POST['message'] = "Hello"; function hage(){ // ┐ echo DSN . "\n"; //(1) │ echo CONSTANT. "\n"; //(2) │ echo $message. "\n"; //(3) │ ☆ echo $_POST['message'] ."\n"; //(4) │ echo $x. "\n"; //(5) │ echo $y. "\n"; //(6) │ } // ┘ echo hage(); //(7)結果は以下のようになりました。
qiita.phpmysql:dbname=hage;host=localhost;charset=utf8mb4//(1) Hello world. //(2) Notice: Undefined variable: message in /Applications/XAMPP/xamppfiles/htdocs/trial/trial.php on line 160 //(3) Hello //(4) Notice: Undefined variable: x in /Applications/XAMPP/xamppfiles/htdocs/trial/trial.php on line 162 //(5) Notice: Undefined variable: y in /Applications/XAMPP/xamppfiles/htdocs/trial/trial.php on line 163 //(6)スコープが関数内に限る(3)の
$message
に加えて、(5)(6)の$x
,$y
も未定義のエラーとなりました。
どこにも定義していないので当然ですね。返り値について
上記のコードには登場しませんでしたが、関数は返り値(return)を返す事ができます。
qiita.phpfunction sayHello($friend){ //(1) $message = "Hello," . $friend . "."; //(2) return $message; //(3) } $message = sayHello('Haru'); //(4) echo $message; //(5) //出力結果 //Hello,Haru.(1)でsayHello関数に仮引数である
$friend
を指定しています。
(2)で処理内容を記述してます。
(3)で$message
を返り値に指定しています。(2)で格納された値が返されると言う事です。
(4)で返り値を受け取り、変数に格納します。実引数は'Haru'と指定しました。実引数に指定するのは変数でも文字列でも目的に合わせて指定できます。(仮引数は変数のみでした)。
※この時、関数内の$message
と返り値を格納している関数の外の$message
は全くの別人です。前述の「スコープ」の違いがありますね。
(5)で変数に格納した返り値を出力しています。まとめると、
(1)〜(3)でsayHello関数は、「返り値(return値)」を返しています。。
呼び出し側である(4)では、関数の返り値を受け取っています。関数の「スコープ」はグローバルですので、例えば、
qiita.php$message = sayHello('Haru'); //(4) function sayHello($friend){ //(1) $message = "Hello," . $friend . "."; //(2) return $message; //(3) } echo $message; //(5)などと記述の順番が入れ替わっても、値を受け取る事ができます。
引数名と変数名
さて、私が理解が浅く混乱していたのがこの変数名と引数名のところです。。。
再び、こちらのコードが登場です。
qiita.phpfunction sayHello($friend){ //(1) $message = "Hello," . $friend . "."; //(2) return $message; //(3) } $message = sayHello('Haru'); //(4) echo $message; //(5)
$friend
が仮引数です。
(1)のsayHello〜の記述から、「関数内」と言う事になります、
なので、仮引数と(2)の$friend
変数名は必ず合わせる必要があります。
違う変数名を使えば、当たり前ですが違う変数として扱われます。それに対して、「関数の外(すなわち関数の呼び出し側)の変数名」と「仮引数名」は合わせる必要はありません。
qiita.phpfunction sayHello($friend){ //(1) $message = "Hello," . $friend . "."; //(2) return $message; //(3) } $name = 'Haru'; //※(3) $message = sayHello($name); //(4) echo $message; //(5) //出力結果 //Hello,Haru.別に同じにしても結果は変わりません。
qiita.phpfunction sayHello($friend){ //(1) $message = "Hello," . $friend . "."; //(2) return $message; //(3) } $friend = 'Haru'; //(※3) $message = sayHello($friend); //(4) echo $message; //(5)実引数には、仮引数と違う変数名を指定してあげても、文字列を指定してあげても大丈夫という事でした。
以上、長くなりましたが、私が初めてユーザー関数を使ったときに混乱したことをまとめてみました。
同じように初めて使う人の役に立てばと思って書きましたが、何か間違いやご指摘事項あればご教授いただけると力になります。
- 投稿日:2020-03-25T23:23:57+09:00
【Laravel】 From句にサブクエリを使用する
結論
laravel 5.6.3から
joinSub、leftJoinSubが使える.$subQuery = ProfileUserView::select(['user_id', 'company_id']) ->whereBetween('created_at', [$from, $to]) ->distinct(); $mostViewQuery = \DB::query() ->selectRaw('company_id, COUNT(user_id) AS pv') ->fromSub($subQuery, 'sub') ->groupBy('company_id');ver 5.6.3以前
それより以前は mergeBindings使う.
https://github.com/laravel/framework/issues/19711
$count = DB::table( DB::raw("({$sub->toSql()}) as sub") ) ->mergeBindings($sub->getQuery()) // you need to get underlying Query Builder ->count();こんな感じ
$subQuery = ProfileUserView::select(['user_id', 'company_id']) ->whereBetween('created_at', [$from, $to]) ->distinct(); $mostViewQuery = \DB::table(\DB::raw("({$subQuery->toSql()}) as sub") ) ->mergeBindings($subQuery->getQuery()) ->selectRaw('company_id, COUNT(user_id) AS pv') ->groupBy('company_id');ただしmergeBindingsは、bindするパラメーターの順序を気をつけないといけないので注意する
- 投稿日:2020-03-25T23:11:50+09:00
Laravel base64エンコードされた画像を保存する
/** * 画像保存 * @param string $base64Context * @param string $storage * @param string $dir * @return App\Models\Image */ public function storeImage($base64Context, $storage, $dir) { try { preg_match('/data:image\/(\w+);base64,/', $base64Context, $matches); $extension = $matches[1]; $img = preg_replace('/^data:image.*base64,/', '', $base64Context); $img = str_replace(' ', '+', $img); $fileData = base64_decode($img); $dir = rtrim($dir, '/').'/'; $fileName = md5($img); $path = $dir.$fileName.'.'.$extension; Storage::disk($storage)->put($path, $fileData); return $path; } catch (Exception $e) { Log::error($e); return null; } }
- 投稿日:2020-03-25T23:11:50+09:00
【Laravel】 base64エンコードされた画像を保存する
/** * 画像保存 * @param string $base64Context * @param string $storage * @param string $dir * @return App\Models\Image */ public function storeImage($base64Context, $storage, $dir) { try { preg_match('/data:image\/(\w+);base64,/', $base64Context, $matches); $extension = $matches[1]; $img = preg_replace('/^data:image.*base64,/', '', $base64Context); $img = str_replace(' ', '+', $img); $fileData = base64_decode($img); $dir = rtrim($dir, '/').'/'; $fileName = md5($img); $path = $dir.$fileName.'.'.$extension; Storage::disk($storage)->put($path, $fileData); return $path; } catch (Exception $e) { Log::error($e); return null; } }
- 投稿日:2020-03-25T22:35:54+09:00
セッション
Request->session()->put('キー', 値);$変数 = Request->session()->get('キー');sessionの格納先は
strage/framework/sessions
になる。データベースでセッションを使う
下記設定に変更する
config/session.php'driver' => env('SESSION_DRIVER', 'database')SESSION_DRIVER=databaseコマンド実行
php artisan session:tableマイグレーションファイルが作成されるので
php artisan migrate
すればDBでセッションを扱えるようになる
- 投稿日:2020-03-25T21:39:09+09:00
PHPでは関数の引数が多くてもエラーにならない
phpでは関数に引数を渡すときに定義されている数より多くてもエラーにはならないようです。
<?php // 2つ引数で関数を呼び出す。 function twoArgumentFunction($one, $two) { echo $one . ':' . $two; } # 引数二つで関数を呼び出す。 twoArgumentFunction('first', 'second'); // => first:second // 3つの引数だと呼び出せる twoArgumentFunction('first','second','third'); // => first:second引数の数が少ないと「Fatal error」が発生します。
// 1つの引数で呼び出すとエラーになる twoArgumentFunction('first'); // Fatal error: Uncaught ArgumentCountError: Too few arguments to function twoArgumentFunction(), 1 passed in index.php on line 13 and exactly 2 expected
- 投稿日:2020-03-25T21:05:26+09:00
Elastic BeanstalkでのLaravelにてstorageへのシンボリックリンクを張る方法
はじめに
Elastic BeanstalkでのLaravelにてstorageへのシンボリックリンクを張る方法で手こずったので備忘録です
TL;DR
container_commandsにて「ln」を使用して、相対パスでシンボリックリンクを貼りました
コード
ebextensions/commands.configcontainer_commands: 0x_storage_link: command: "ln -s ../storage/app/public storage" cwd: "/var/app/ondeck/public"最後に
他に良い方法がありそうですが。。。
補足
「php artisan storage:link」でシンボリックリンクを貼ると絶対パスになりました。(参考サイトと同事象)
参考
- 投稿日:2020-03-25T19:20:54+09:00
Goodby/CSV 大量にデータをインポートすると、マルチバイト文字列が欠落する場合がある
自分用の備忘録
何が問題か
私が教えてほしいです。
大量に(400行ぐらい)データをインポートすると、1~数行、
日本語文字列が一文字(3バイト分)だけ欠落するという事象が発生した原因は不明。誰か教えて
直し方
これを
$config->setFromCharset("UTF-8");こうすれば直った
$config->setFromCharset(NULL);ソースコード
/** * Import Csv By Goodby\CSV Parser * このメソッドはCSVの読み込みのみを担当し、加工はコントローラー側に任せる想定 * * @param string $filePath * @return array * @link https://github.com/goodby/csv * @link https://nori-life.com/laravel-csv-import-goodbycsv/ */ public function import($filePath) { // variable definition $rows = array(); // goodby csv configuration $config = new LexerConfig(); $config->setDelimiter(","); // e.g. [",", "\t"] $config->setEnclosure('"'); // e.g. ["'", '"'] $config->setEscape("\\"); // UTF-8にすると、大量にデータを読み込んだ際に、マルチバイト文字列が欠落する場合がある模様 //$config->setFromCharset("UTF-8"); // e.g. [NULL, "UTF-8", "SJIS-win", "EUC-JP"] $config->setFromCharset(NULL); // e.g. [NULL, "UTF-8", "SJIS-win", "EUC-JP"] $config->setToCharset("UTF-8"); // e.g. [NULL, "UTF-8", "SJIS-win", "EUC-JP"] $config->setIgnoreHeaderLine(TRUE); // format csv $interpreter = new Interpreter(); $interpreter->addObserver(function(array $row) use (&$rows){ $rows[] = $row; }); // parse csv $lexer = new Lexer($config); $lexer->parse($filePath, $interpreter); // parsed csv data into $rows here. return $rows; }
- 投稿日:2020-03-25T19:12:07+09:00
Wordpress ページによって読み込むcssを変える
はじめに
wordpressでページごとに読み込むcssを変えたい!と思う事があるかもしれません。
実はphpの条件分岐を使えば、簡単にできるのです。
今回は固定ページごとに、読み込むcssを変える方法を紹介スラッグ(Slug)を確認
まずは固定ページのスラッグ(Slug)を確認
固定ページ一覧>クイック編集
から確認できるかと(無理だったら目的のページの編集画面まで行こう)header.phpで条件分岐
header.php<head> .省略 . . <?php if(is_page('movie100')) { ?> <link href="<?php echo get_template_directory_uri(); ?>/css/movie100.css" rel="stylesheet "> <?php }?> </head>これでスラッグが
movie100
の固定ページでは、movie100.css
が読み込まれます。もっと複数の条件分岐をしたい場合
<?php if(is_page(array('movie100', 'manga100'))) : ?> <link href="<?php echo get_template_directory_uri(); ?>/css/movie100.css" rel="stylesheet "> <?php else: ?> <link href="<?php echo get_template_directory_uri(); ?>/css/style.css" rel="stylesheet "> <?php endif; ?>これでスラッグが
movie100
とmanga100
の固定ページの場合はmovie100.css
が読み込まれ、それ以外のページではstyle.css
が読み込まれる。
- 投稿日:2020-03-25T18:22:58+09:00
『NHKニュース速報』を取得して表示する
はじめに
この記事は、日本の公共放送NHKのニュース速報を取得し、PHPで表示する方法を掲載しています。
過度な取得は、提供元のサーバに負荷をかけることとなりますので、絶対にしないでください。
また、あくまで取得して表示するまでの方法を掲載しています。表示デザイン等は一切考慮しておりませんので、ご了承ください。仕組み
NHKのニュースサイト「NHK NEWS WEB」のバックグラウンドで動作している「sokuho_news.xml」にアクセスし、データを取得します。
その後、echoを使ってデータを表示します。ソースコード
BreakingNews.php<?php $xmlData = simplexml_load_file("https://www3.nhk.or.jp/sokuho/news/sokuho_news.xml"); ?> <ul> <?php foreach ($xmlData->report->line as $line): ?> <li><?= htmlspecialchars($line, ENT_QUOTES, 'UTF-8') ?></li> <?php endforeach; ?></ul>@tadsanさんのご指摘により、一部変更しました!
ご指摘ありがとうございました。解説
初めに「simplexml_load_file」でNHK NEWS WEBのXMLファイルをパースし、オブジェクトに代入します。
その後、echo を使ってオブジェクトにある文字列を表示する仕組みです。
foreach文で繰り返してあるのは、ニュース速報電文が複数ある場合対応するためです。テスト用電文
simplexml_load_fileの取得先を以下のXMLファイルにすることで、動作チェックをすることができます。
sokuho_news.xml<?xml version="1.0" encoding="UTF-8" ?> <flashNews flag="1" pubDate="Sun, 21 Jul 2020 20:00:00 +0900"> <report category="1" date="2019/07/21 20:00" link=""> <line>テスト用電文1 これはテスト用電文1です(20:00)</line> <line>テスト用電文2 これはテスト用電文2です(20:00)</line> </report> </flashNews>終わりに
NHKニュース速報を取得して表示する方法でした。
なお、繰り返しとなりますが、過度な取得は、提供元のサーバに負荷をかけることとなりますので、絶対にしないでください。
- 投稿日:2020-03-25T17:53:16+09:00
Laravelを利用したWebアプリ制作を学べる教材まとめ
はじめに
あらゆる教材に手を出すと、結局この教材はどういうことが学べるんだっけ??と失念しがちなので自分用に作ってみました。
※随時更新予定※
Techpitの教材編
Laravel(+Vue.js)でSNS風Webサービスを作ろう!
ページリンク
https://www.techpit.jp/p/laravel-vue-sns完成見本サンプル(※私がデプロイしたもの。Mail機能のみ未実装。)
http://laravel-vue-sns.herokuapp.com/
開発環境
Mac,Docker(Laradock)
PHP 7.3、Node.js 10、Vue.js 2.6.11、Laravel 6.8、PostgreSQL 11.6
~Dockerを利用するメリット~Webサーバーやデータベース本体やその設定内容をファイル化できるという点が挙げられます。
そのようなファイルをほかの人に配布することで、誰でも同じ環境を構築できます。
本教材では、そうしたDocker用に作られたファイルを利用して開発環境を作ります。
活用ライブラリ
MDBootStrap、Vue Tags Input
学べる内容
初学者がポートフォリオ作成で躓く(私含め)であろうミドルウェア、リクエスト、認可、ポリシー、さらにはフロンドエンドフレームワーク(Vue.js)との連携まで、実際にアプリを作りながら体験できる。以下、以前書いた感想記事。
https://chobimusic.com/laravel_vue_sns/
進め方
2章・3章:ログイン機能4章:記事投稿機能
4-3 authミドルウェア 4-4 フォームリクエストの作成 4-5 依存性の注入(DI)、fillableの利用5章:記事更新・削除機能
5-2 null演算子 5-5 認可(ポリシーの作成)によるユーザー権限の考慮6章:パスワード再設定メール(MailHogでのテストメール/Sendgridでの本番メール)
7章:いいね機能(VueコンポーネントをBladeに組み込み)
7-5 @json 7-7 いいね機能のアクションメソッド追加(web.php)8章:タグ機能
8-6 フォームリクエストのバリデーション(鬼門)9章:フォロー&ユーザーページ機能
10章:Googleアカウントを使ったログイン機能
11章:デバッグバーの活用(SQLの改善)
12章:Herokuへデプロイ
所感
このチュートリアルで連携するVue.jsに関しては、Vue Routerなどの公式ライブラリを活用しない。また、blade側に@jsonディレクティブを記載してデータ転送(サーバー上にあげる。Vueで取り出し。)しているのが印象的。
SPA開発ではないのでVueで非同期のデータ受け渡し&装飾をしている感じ。(フォローボタン・いいね機能)
URLの遷移がある部分は全てLaravel側で構築している。
内容自体かなり濃いので、Laravel、Vue.js共にある程度わかっていないと理解が難しいが、とても勉強になる。
SPA開発まではいかずともLaravelとVue.jsを連携させたい!といった方にはとてもおすすめ!!
Googleアカウントでログイン機能を実装することで、アプリ運用に伴うセキュリティ面のハードルが少し下がる。
どこからどこまでBladeで作ってVue側で補うか、境目の判断が難しい。。。
ちょっと動的なコンテンツを入れるだけならならjQueryを活用するのもアリ??
【Laravel x Vue.js】SPAクイズアプリケーションを作ってみよう!
ページリンク
https://www.techpit.jp/p/laravel-vue-quiz完成見本サンプル
https://laravel-vue-quiz.herokuapp.com/
開発環境
Mac,Homebrew
PHP 7.3、Node.js 10、Vue.js 2.6.10、Laravel 6.8、SQLite
活用ライブラリ
Chart.js,Axios(API※非同期でのサーバーアクセス※をより使いやすくしたもの),Laravel-Admin
学べる内容
サーバーサイドにLaravel、フロントサイド(表示部分)は、Vueで作成。メインとなるビューはトップ("/")と("/quiz")クイズの2画面。
Vue Router(ルーティング制御ができる公式プラグイン)でSPA化("/"と"/quiz"ページの遷移がリロードせずにできる)。
進め方
3章:Laravelプロジェクトとは別のディレクトリでVue.jsのプロジェクトを作成。4章:LaravelディレクトリとVueディレクトリをがっちゃんこ。index.blade.phpでvueを読み込み。
5章:Vou Router(router.js)の導入でSPA化
6章:API連携の実装(api.phpの編集)。Laravel側で取得したDB情報 をVue(フロントサイド)からAPIで読み込む。
7章・8章:ログイン、ユーザー登録もVue側でビューを作成。
9章:ランキング機能、キーワード画面の実装 ※いずれもAPIを使う
10章:ブラッシュアップ
11章:Laravel-Adminの導入
12章:Herokuへデプロイ
所感
LaravelにVueを組み込むにしてもどこまで組み込むのかで難易度が大きく変わることに気付けた。例えばいいねボタンの実装とかであれば簡単だが、SPA化するとなるとAxiosやVue Routerなどの知識も必要になる。
また、Laravel-adminが使いこなせればWordPressを使用することなくブログ運営なんかもできるなと感じた。(同じようなものだと他にはVoyagerなどがあるみたい。これを駆使したチュートリアルが見つからなかったのは残念。)
Laravel6とAWSで作るブックレビューサイト
ページリンク
https://www.techpit.jp/p/laravel6-aws完成見本サンプル
https://laravel-vue-quiz.herokuapp.com/
開発環境
AWS,cloud9(win,mac共通)
PHP 7.3、Node.js 10、MySQL5.7、Laravel 6
学べる内容
AWSでのアプリ開発画像投稿機能(シンボリックリンク)
GitHubリポジトリの作成~cloud9からの独自ドメインへのデプロイ
EC2インスタンスの立ち上げ、TeraTermでのSSH接続
所感
最初に作ったポートフォリオはこちらの教材を参考にした。削除・編集機能までは実装しないのが残念だが、AWSの活用を学べるのはありがたい。
最後にカスタマイズ提案があり、いいね機能やコメント機能など。
こちらはまだ未実装なので試してみてもいいかもしれない。
無料でできるチュートリアル
Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう
ページリンク
https://www.hypertextcandy.com/vue-laravel-tutorial-introduction/
開発環境
Mac,Docker(Laradockを用いていない!!)
PHP 7.4、Node.js 10、Vue.js 2.6、Laravel 6、PostgreSQL、AWS S3(写真保存)
学べる内容
フロントエンドに Vue.js + Vue Router + Vuex 、サーバーサイドに Laravel を使用したSPAアプリ開発。
進め方
3章:Laravelプロジェクト作成。Laravel Mixでフロントをビルド。Vue Routerを導入。4章:api.phpを編集してサーバーサイドのAPIを実装。(会員登録,ログイン,ログアウト)
6章・7章:状態管理ライブラリVuexの導入。ユーザー認証データなどコンポーネントをまたいで参照したいデータを入れておけるストアの実装。
10章:写真投稿フォーム Vue.jsで投稿機能を実装。
11章:JSONへの変換。
16章:Herokuへのデプロイ&カスタマイズ提案
所感
無料のチュートリアルとしては断トツで深いところまで学べる。Laradockを使わずともDockerでLaravelは使えることにも気づいたので挑戦してみたい。
データの受け渡しやいいねなどあらゆる機能をVue.jsで実装。
教本含め、ここまで複雑なアプリ開発ができるチュートリアルを見たことがない。
もっとこういうチュートリアルが増えてほしい!!
おわりに
1つの教材ですべてを網羅することはできないので、いろんなチュートリアルをこなしながらスキルアップを目指したい。
- 投稿日:2020-03-25T16:40:25+09:00
【PHP】PHPUnitインストールからテスト実行まで
環境
PHP 7.4.3
Composer 1.10.1PHPUnitインストール
既にcomposerを入れてるので、コマンドからインストールするだけでした。
C:\php>composer require phpunit/phpunit --dev
word description composer PHPのパッケージ管理ツール require npmでいうところのinstall dev ローカルにインストールするオプションコマンド コマンド実行すると、composer.jsonの"require-dev"に追加されます。
composer.json{ "require": {}, "require-dev": { "phpunit/phpunit": "^9.0" } }バージョンを確認してみます。
C:\php> vendor\bin\phpunit --versionconmoserでインストールするとphpunitコマンドはvendor/bin/phpunitに生えるので、上記のような実行方法になります。
phpunit で実行するには別途設定がいるのですが、今は割愛。テスト対象の作成
四則演算をするだけのプログラムでテストをします。
arithmetic.php<?php class Arithmetic { public function add($x,$y) { return ($x+$y); } public function substract($x,$y) { return ($x-$y); } public function multiply($x,$y) { return ($x*$y); } public function divide($x,$y) { return ($x/$y); } } ?>テストコード作成
以下テストコードです。
arithmeticTest.php<?php require_once 'arithmetic.php'; class arithmeticTest extends PHPUnit\Framework\TestCase{ protected $obj; protected function setUp() :void { $this->object = new Arithmetic(); } public function testAdd() { $this->assertEquals(5,$this->object->add(2,3)); } public function testSub() { $this->assertEquals(5,$this->object->substract(8,3)); } public function testMulti() { $this->assertEquals(6,$this->object->multiply(2,3)); } public function testDiv() { $this->assertEquals(5,$this->object->divide(10,2)); } } ?>require_onceは外部ファイルを1度だけ読み込む命令です。
下記の記事がrequireとrequire_onceの違いについて分かりやすかったです。
http://alphasis.info/2012/06/php-control-require_once/setUp()は:voidを付けないとエラーになりました。理由はよくわからない。
PHP Fatal error: Declaration of arithmeticTest::setUp() must be compatible with PHPUnit\Framework\TestCase::setUp(): void in C:\php\arithmeticTest.php on line 8assertメソッドについては以下の記事にまとまっていたので参考にさせて頂きました。
https://qiita.com/rev84/items/12fbd16d210d6a86eff9実行時のコマンドはテストファイル名.phpでOKです。
C:\php>vendor\bin\phpunit arithmeticTest.php PHPUnit 9.0.1 by Sebastian Bergmann and contributors. .... 4 / 4 (100%) Time: 57 ms, Memory: 4.00 MB OK (4 tests, 4 assertions)失敗時は以下のように表示されます。
C:\php>vendor\bin\phpunit arithmeticTest.php PHPUnit 9.0.1 by Sebastian Bergmann and contributors. F... 4 / 4 (100%) Time: 129 ms, Memory: 4.00 MB There was 1 failure: 1) arithmeticTest::testAdd Failed asserting that 5 matches expected 10. C:\php\arithmeticTest.php:14 FAILURES! Tests: 4, Assertions: 4, Failures: 1. C:\Users\tomioka-y5\Desktop\php>
- 投稿日:2020-03-25T14:48:12+09:00
初心者|docker-compose|PHP+ Nginx + MySQL
docker-compose.ymlファイルだけでphp環境を簡単に構築できないかと思い、調べて見ました。(残念ながらdocker-compose.ymlファイルだけではダメでしたが...)
リスペクトな記事
この記事を作成するにあたり、参考にさせていただいた記事です。
本件、同様の既存記事を踏襲する内容となります。DockerによるPHP開発環境構築(PHP + MySQL + Nginx)
Docker + Nginx + PHP-FPM なら40秒くらいで環境を準備できる docker-compose が楽しくなってきました。したいこと
dockerを使って、ローカル環境でphpを使いたい
したこと
1) docker-compose.yml の用意
下記、コピペでOKです
docker-compose.ymlversion: "3" services: db: image: mysql:5.7 volumes: - ./db/mysql:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: root_pass_fB3uWvTS phpmyadmin: image: phpmyadmin/phpmyadmin:latest restart: always ports: ["8888:80"] depends_on: ["db"] php: image: php:7.4-fpm volumes: - ./nginx/html:/usr/share/nginx/html - ./php/php.ini:/usr/local/etc/php/conf.d/php.ini depends_on: ["db"] nginx: image: nginx:latest volumes: - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf - ./nginx/html:/usr/share/nginx/html restart: always ports: ["8080:80"] depends_on: ["php"]2)とりあえず docker-compose up
docker-compose.ymlファイルのあるディレクトリで
docker-compose up -d
してみてください。エラーが出るはずです。エラーが出たことを確認しましたら
docker-compose down
で停止してください。エラーが出た理由は
nginx:
サービスで使う default.conf ファイルがクライアント側に存在しないためです。default.conf ファイルを用意する必要があります
3)【重要】 nginx用のdefault.confファイルの用意
default.conf ファイルを用意します。
default.confserver { listen 80; server_name localhost; root /usr/share/nginx/html; index index.php index.html; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ [^/]\.php(/|$) { fastcgi_pass php:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }4) default.confファイルの保存先
上記の工程(2)で
docker-compose up -d
をした後であれば、docker-compose.ymlファイルのあるディレクトリにnginx
php
db
という3つのディレクトリが生まれているはずです。ディレクトリ
nginx / conf.d
の中にdefault.confファイルを保存してください。「default.conf」というディレクトリが先に存在している場合は、削除してください(入れ替えてください)
5)もう一度 docker-compose up
再度に
docker-compose up -d
してください。今回は上手く立ち上がったのではないでしょうか?6)確認してみる
動作確認のため、ディレクトリ
nginx / html
の中にindex.php
ファイルをおいてください。(index.php
ファイルの内容は何でも結構です)index.phpの例<?php echo phpinfo();ブラウザで
http://localhost:8080/
へアクセスして表示されれば確認完了です
補足
データベースとphpMyAdminは不要です
上記の docker-compose.yml には個人的な都合でmysqlとphpmyadminを入れておりますが、php環境を作る目的だけであれば不要なものです。
よってサービスdb:
とphpmyadmin:
は削除いただいてOKです。ただし、削除する場合はサービスphp:
内にあるdepends_on: ["db"]
を削除することを忘れないように。もし、phpMyAdminへアクセスする場合は
http://localhost:8888/
です。
ユーザー名root
、パスワードroot_pass_fB3uWvTS
でログインできるはずです。nginx−default.conf の記述について
こちらの参考サイトがとても勉強になりました。
参考サイト:nginx連載4回目: nginxの設定、その2 - バーチャルサーバの設定
参考サイト:nginx連載5回目: nginxの設定、その3 - locationディレクティブnginx と PHP-FPM の関係性について
こちらの参考サイトがとても勉強になりました。
参考サイト:nginx と PHP-FPM の仕組みをちゃんと理解しながら PHP の実行環境を構築する
FastCGIって何?
こちらの参考サイトがとても勉強になりました。
- 投稿日:2020-03-25T13:17:29+09:00
Laravel 新規プロジェクト作成手順(laravel コマンドが使えなかったとき、composerコマンドでやってみよう)
- 投稿日:2020-03-25T10:06:32+09:00
CodeIgniterのget_instance()についてまとめた
はじめに
今回新たに参画したプロジェクトでCodeIgniterが使われていたので勉強がてらまとめてみました。
フレームワークの中身を読んでいるとget_instance()
にたどり着いたので今回はそれを題材にして記事にいたしました。get_instance()
コントローラのメソッド内でインスタンス化されるクラスは全てCodeigniterのネイティブリソースにアクセスできます。
get_instance()
関数を利用することによってシンプルに書くことが可能になります。
- 返り値
- コントローラのインスタンスへの参照
- 返り値の型
- CI_Controller
- 関数の役割
- メインのCodeIgniterオブジェクトを返す
通常、Codeigniterの利用可能なメソッドを呼び出すには
$this
を使う必要があります。$this->load->helper('url'); $this->load->library('session'); $this->config->library('base_url');しかし
$this
はそのコントローラ内、モデル内、 ビュー内にのみ機能するようになります。独自のカスタムクラスからCodeigniterのクラスを使用したい場合は以下のようにします。
まず、変数にCodeigniterのオブジェクトを割り当てましょう。$CI =& get_instance();オブジェクトを変数に割り当てたのなら、
$this
の代わりにその変数を使用します。$CI =& get_instance(); $CI->load->helper('url'); $CI->load->library('session'); $CI->config->item('base_url');もし別のクラス内で
get_instance()
を使うならプロパティに割り振ると良いですよ〜。class Igniter { protected $CI; // コンストラクタでなくてもOKですが、 // クラスが呼ばれた段階で実行されるのて楽なのでおすすめです。 public function __construct() { // Codeigniterのスーパーオブジェクトを割り当てます。 $this->CI =& get_instance(); } public function foo() { $this->CI->load->helper('url'); redirect(); } public function bar() { $this->CI->config->item('base_url'); } }プロパティに振らない場合は、
class Igniter { public function foo() { $CI =& get_instance(); // 1回目の呼び出し $CI->load->helper('url'); redirect(); } public function bar() { $CI =& get_instance(); // 2回目の呼び出し $CI->config->item('base_url'); } }メソッドが増えるごとに呼び出さなければならないのでプロパティに振ることをお勧めです。
- 投稿日:2020-03-25T08:11:15+09:00
Laravelのライブラリ「laravel-dompdf」を使ってビューの表示をPDFとして表示しよう
目的
- ライブラリを使用して現在のビューとして表示しているコードをそのままPDFで表示する方法をまとめる
実施環境
- ハードウェア環境
項目 情報 OS macOS Catalina(10.15.3) ハードウェア MacBook Air (11-inch ,2012) プロセッサ 1.7 GHz デュアルコアIntel Core i5 メモリ 8 GB 1600 MHz DDR3 グラフィックス Intel HD Graphics 4000 1536 MB
- ソフトウェア環境
項目 情報 PHP バージョン 7.4.3 Laravel バージョン 7.0.8
- ライブラリ環境
項目 情報 備考 laravel-dompdf v0.8.6 アプリ名ディレクトリに移動後コマンド`composer show -i 実施条件
- 下記の記事に沿って環境構築を行っていること。
- ローカル開発環境でブラウザから確認可能なLaravelアプリがあること。
実施方法概要
- コントローラの確認
- アクションの記載変更
- 確認
実施方法詳細
コントローラの確認
PDFとして表示したいビューファイルが呼び出されているコントローラファイルを表示する。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; ・ ・ ・
use Illuminate\Http\Request;
の下に下記の内容を記載する。use PDF;コントローラファイルの設定部分が下記の様になっていることを確認する。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use PDF; ・ ・ ・アクションの記載変更
先に確認したコントローラファイルのビューを表示しているアクションを確認する。
return view('ビューファイルディレクトリ名.ビューファイル名');先に確認した
return
部分を下記の様に記載する。$pdf = PDF::loadView('ビューファイルディレクトリ名.ビューファイル名'); #変数などの引数を伴ってビューを呼んでいる場合 $pdf = PDF::loadView('ビューファイルディレクトリ名.ビューファイル名', compact('変数や配列などの引数')); return $pdf->stream();確認
下記コマンドを実行してローカルサーバを起動する。
$ cd アプリ名ディレクトリ $ php artisan serve修正したアクションとリンクするURLにアクセスする。
PDFで表示されればOKである。(日本語は文字化け表示されるが、現在の設定だと正常である。)
- 投稿日:2020-03-25T07:05:02+09:00
composer install できない
composerがインストールできないときの解決した方法
解決法
https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode
↑
ここに飛ぶ手順に沿って解決
MacOSの場合
IPv6の設定が正しくされていないらしい、、、
1. ネットワーク機器の名前を確認(たぶんWi-Fi)
networksetup -listallnetworkservices2. 一旦、IPv6を無効にする(Wi-Fiの場合)
networksetup -setv6off Wi-Fi3. 再度IPv6を設定する
networksetup -setv6automatic Wi-Fi4. composer installを実施
- 投稿日:2020-03-25T05:23:19+09:00
laravel5.5 配列を用いたページネーション
今回の題
Eloquent モデルとクエリビルダに対しては paginate() メソッドを使えばあっという間に実装できる。
めちゃくちゃ簡単で便利。が。
配列を使ったページネーションはどうやるんだ?と考えたときに少し苦労したので自分用にメモ。
Twitter apiで遊んでいて、取得したツイートをページ上で一覧表示させたくて使いました。方法
LengthAwarePaginatorを使います。
公式のリファレンスに情報が少なすぎ……。use Illuminate\Pagination\LengthAwarePaginator; //配列($array)をコレクションに変換 $array = collect($array); $array_result = new LengthAwarePaginator( $array->forPage($request->page, 20), count($result->statuses), 20, $request->page, array('path' => $request->url()) );1ページあたりの表示数は、LengthAwarePaginatorの第一引数と第三引数にある数字を好きな数字に変えてあげると変更できます。この記事だと1ページあたり20件。
こいつをviewに渡して、リンクを表示させたい箇所に{{ $array_result->links() }}を書いてあげれば完成。
- 投稿日:2020-03-25T01:15:32+09:00
【Laravel】初学者が更なる高みを目指して学ぶべきこと
はじめに
自分のために更なるスキルアップを目指して書いてみました。
同じく簡易的なポートフォリオサイトを作れるくらいの方々の参考になれば幸いです。
※以下、私のレベル感。
https://chobimusic.com/laravel_craftbeers/
現状
・基礎的なRESTfulサービスは作れる。(index,createstore,show,edit,update,destroyまで実装)・ユーザー認証機能は実装できる。
・Eloquentの基本は理解している。
学ぶべきこと
①ミドルウェア
②リクエスト
③依存性の注入
④認可機能(ポリシー)
①ミドルウェア
未ログインユーザーが投稿などできないようにするために必要。以下はindex、show以外にアクセスしようとするとログイン画面へリダイレクトされるようにしている。
//web.php <?php Auth::routes(); Route::get('/', 'ArticleController@index')->name('articles.index'); Route::resource('/articles', 'ArticleController')->except(['index', 'show'])->middleware('auth'); Route::resource('/articles', 'ArticleController')->only(['show']);
※app/Http/MiddlewareディレクトリのAuthenticate.phpファイル記載のroute('login')の部分を編集すればリダイレクト先を変更できる。また、上記のようにルーティングにもいろいろ使えるメソッドが存在する。
・nameメソッド(別名:名前付きルート)
URLを生成したり、リダイレクトしたりできる。・onlyメソッド
resourceメソッドにそのアクションのみを指定できる。・exceptメソッド
resourceメソッドからそのアクションを除外できる。
②リクエスト
以下でリクエストは作成できる。主にフォーム周りで送信された値のバリデーションを行う。
$ php artisan make:request ArticleRequest
(コントローラーでバリデーションを行わせることもできるが、一般的にコントローラーにはあまり多くの処理を持たせないようにすることが望ましい。)・authorizeメソッド
リクエストの対象となるリソース(ここでは記事)をユーザーが更新して良いかどうかを判定する。・rulesメソッド
バリデーションのルールを定義する。・attributesメソッド
バリデーションエラーメッセージに表示される項目名をカスタマイズできる。
③依存性の注入 , DI(Dependency Injection)
コントローラーにおいて、アクションメソッドの引数で型宣言を行うと、そのクラスのインスタンスが自動で生成されてメソッド内で使えるようになる。以下のように、外で生成されたクラスのインスタンスをメソッドの引数として受け取る流れのことをDIという。
//〇〇Controller public function edit(Article $article) { return view('articles.edit', ['article' => $article]); }
最初はチュートリアルをやっていると、よくこのタイプの引数を見かけて、毎度意味が分からず頭を抱えていた。例えば、URLがarticles/1/editだとすると、idが1であるArticleモデルのインスタンスが代入される形になる。
また、ビューには'article'というキー名で、変数$articleの値(Articleモデルのインスタンス)を渡している。
④認可機能(ポリシー)
①のミドルウェアでログイン有無によるアクセスの制限はできる。しかし、ログイン後に考慮すべき投稿コンテンツの更新・削除・編集に関してはミドルウェアだけでは制限できない。
他人の投稿を編集などできないようにするのに必要になるのが認可機能の1つであるポリシー。
ポリシーの作成
$ php artisan make:policy ArticlePolicy --model=Article //--modelをつけることでモデルに対応したポリシーになる。
ポリシーのメソッドとコントローラーのアクションメソッド対応表
ポリシーのメソッド
コントローラーのアクションメソッド
viewAny
index
view
show
create
create,store
update
edit,update
destroy
destroy
ポリシーでfalse
を返す場合、対応するアクションメソッドは処理されず、ステータスコード403
のHTTPレスポンスがクライアントに返さる。
public function view(?User $user, Article $article) //?を付けることで引数がnullでも許容される。(未ログインでも可) { return true; //誰でも詳細画面は見れることにする。 } public function delete(User $user, Article $article) { return $user->id === $article->user_id; //投稿したユーザーしか削除できないようにする。 }
コントローラーに加えることでポリシーを適用。
public function construct() { $this->authorizeResource(Article::class, 'article'); }
・constructメソッド
クラスのインスタンスが生成された時に初期処理として呼び出さなくても必ず実行される。・authorizeResourceメソッド
第1引数にモデルのクラス名(App/Articleでも可)、第2引数にルーティングのパラメータ名。($ php artisan route:listで出力されるURIの{}内の部分)
知っておくと便利だなと思ったもの
Null合体演算子(??)
式1 ?? 式2
という形式で記述。式1がnull
でない場合は式1、式1がnull
である場合は、式2が結果となる。
ルーティングの確認
$ php artisan route:list
最初のころは無視してチュートリアル進めていたけれどもこれみるとミドルウェアがどのアクションメソッドに適用されているか確認できたりする。
RESTfulに関して
ほぼほぼ以下のような規則になっているので、知っているとなにかと良い。
メソッドアクション
ルート情報
引数
メソッド
index
/コントローラ
GET|HEAD
create
/コントローラ/create
GET|HEAD
store
/コントローラ
Request $request
POST
show
/コントローラ/{id}
$id
GET|HEAD
edit
/コントローラ/{id}/edit
$id
GET|HEAD
update
/コントローラ/{id}
Request $request, $id
PUT|PATCH
delete
/コントローラ/{id}
$id
DELETE
更なる高みを目指して
まずはこれらの機能をポートフォリオに実装してみます。今後はProviderやフロントエンドフレームワーク(Vue.js)との連携を目指します。
読んでいただきありがとうございました。
おしまい。
- 投稿日:2020-03-25T00:37:32+09:00
Wordpress 作成したプラグインに設定項目を追加する方法
プラグインに設定を追加して保存できるようにする
プラグインに設定項目(オプション)を追加するには以下のことを行う。
- メニューの作成
- 設定項目の登録
- 設定画面に表示するフォームを作成
<?php /* Plugin Name: Test plugin Description: A test plugin to demonstrate wordpress functionality Author: Test Name Version: 0.1 */ // プラグインに設定ページを追加 add_action('admin_menu', 'test_plugin_setup_menu'); function test_plugin_setup_menu() { // メニューの作成 add_menu_page( __( 'TestPlugin', 'textdomain' ), // ページタイトル 'Test Plugin', // メニュータイトル 'manage_options', // Capabilities、メニューが含む機能? 'test-plugin', // メニューslug 'test_setting_function', // 設定画面で実行する関数 'dashicons-chart-pie' // メニューに表示するアイコン ); // 設定の登録関数を呼び出し add_action( 'admin_init', 'register_test_plugin_settings' ); } // 設定の登録関数 function register_test_plugin_settings() { // 設定項目を1つずつ追加、オプション名は取り出すときにも使う register_setting( 'test-plugin-settings-group', 'test_option_1' ); register_setting( 'test-plugin-settings-group', 'test_option_2' ); register_setting( 'test-plugin-settings-group', 'test_option_3' ); } // 設定画面で実行する関数 function test_setting_function() { ?> <div class="wrap"> <h1>プラグイン名</h1> <!-- 設定項目のフォーム --> <form method="post" action="options.php"> <?php settings_fields( 'test-plugin-settings-group' ); ?> <?php do_settings_sections( 'test-plugin-settings-group' ); ?> <table class="form-table"> <tr valign="top"> <th scope="row">設定項目1</th> <td><input type="text" name="test_option_1" value="<?php echo esc_attr( get_option('test_option_1') ); ?>" /></td> </tr> <tr valign="top"> <th scope="row">設定項目2</th> <td><input type="text" name="test_option_2" value="<?php echo esc_attr( get_option('test_option_2') ); ?>" /></td> </tr> <tr valign="top"> <th scope="row">設定項目3</th> <td><input type="text" name="test_option_3" value="<?php echo esc_attr( get_option('test_option_3') ); ?>" /></td> </tr> </table> <!-- 保存ボタン --> <?php submit_button(); ?> </form> </div> <?php }設定したデータをテンプレートに表示する方法
オプションをテンプレートで表示するには、
get_option()
を使う。パラメータには登録したオプション名を記入する。
<?php echo esc_attr( get_option('test_option_1') ); ?>
- 投稿日:2020-03-25T00:18:29+09:00
apache環境でのPHP について
はじめに
CakePHP3の勉強をするついでに、環境構築をする際にApache環境でPHPをどのように設定をするのかをまとめてみようと思います。
今まで、特に意識することなくwebに落ちているコマンド叩いて、開発環境を構築できていましたが、何を設定するべきなのか、どのように動いているのかをdockerで環境構築するにあたりまとめようと思います。構成
- Webサーバ
- Apache2
- 言語
- php
2つのPHP動作パターン
Apacheを動作させる方法は2パターンある
- モジュール版
- Apacheの1つの追加機能としてモジュール版がある
- Webサーバーを動かすユーザー(root権限など)で動作する
- WebサーバーのプロセスのなかでPHPを実行
- CGI版
- CGI(版のPHP)を動かす各ユーザーは、Webサーバー本体を動かすユーザーとは異なる
- Webサーバーとは別のプロセスで実行 セキュリティ的にはCGIで処理速度ではモジュールが良いという話 同一Webサーバに別プロジェクトが存在するなどの場合はCGIを選ぶべきで、そうで無い場合はモジュールを選びましょうということでしょう。 なので、レンタルサーバで開発をする訳ではないので、モジュール版で開発環境を作ります。
モジュール版PHPをインストール
DockerFile## Packageインストール RUN apk add --update --no-cache php7 php7-apache2httpd.confにモジュール記述
httpd.conf# Get information about the requests being processed by the server ## モジュール版PHP LoadModule php7_module modules/mod_php7.so ## URLでファイル名を省略した場合の表示しようとする優先順位を設定します。 DirectoryIndex index.php index.html <FilesMatch \.php$> SetHandler application/x-httpd-php </FilesMatch> # Uncomment the following to allow .phps files to be handled by the php source filter, # and displayed as syntax-highlighted source code #<FilesMatch "\.phps$"> # SetHandler application/x-httpd-php-source #</FilesMatch>これでPHPをApacheのプロセスの中で実行できるようになります。
※phpをサーバにインストールすることで勝手に記述されたファイルができていた。