20201009のPHPに関する記事は12件です。

X-Content-TypeOptionsについてと、それにまつわる脆弱性

X-Content-TypeOptionsとは

MIMEタイプの解釈を厳密にし、MIMEタイプをブラウザに誤認させるタイプの攻撃や、JSONハイジャック攻撃を防ぐことが出来るもの。

攻撃については下でざっくり説明しますが、アプリ側が想定してるMIMEタイプ(ContentType)とは違うタイプで誤認されてしまうと、これを使った攻撃ができちゃうよ!ということ。

どんな時に使うの?

古いIEはレスポンスヘッダContent-Typeを無視して、拡張子を元にMIMEタイプを判断する性質がある。
この脆弱性の対策として、IE8以降であればレスポンスヘッダに「X-Content-TypeOptions: nosniff」を設定することでレスポンスヘッダを元にMIMEタイプを判定するように修正することが可能。
ただこの指定を行なってもIE7以前では防げないので注意。

IE7以前でも対策したい場合は?

→ JSONの > や <のエスケープを行う。
JSON内にXSSを発生させる文字が出現しなくなるので、MIMEタイプの誤認が発生したしてもXSSは起こらなくなります。
ここまでやるのかは方針によってだと思いますが…。

ちなみにPHPの場合、json_encodeのオプションパラメータとして JSON_HEX_TAG などを指定することで、小なり記号などのエスケープが可能

設定方法は?

Apacheのhttp.confファイルに以下を記述
設定変更はApacheの再起動かけないと反映されないので注意

Header always append X-Content-Type-Options: nosniff

対策となる脆弱性の例

  1. MIMEタイプをブラウザに誤認させるタイプの攻撃
     - JSONを直接表示することによるXSS
     - ファイルダウンロードによるクロスサイト•スクリプティング

  2. JSONハイジャック攻撃

がメイン。
一つ一つ、ざっくり概要だけまとめます

1.JSONを直接表示することによるXSS(MIMEタイプをブラウザに誤認させるタイプの攻撃)

対象機能 JSONを生成するAPI
想定されるシーン メールに記載されている罠サイトや攻撃を受けたサイトなど、罠サイト閲覧により
リスク ユーザー側のブラウザで不正なJavaScriptが実行されたり、偽情報を表示されたりする

JSONを返す処理で、JSON以外のContent-Typeに誤認されることで、ファイル内のJavaScriptが実行されてしまう。
例えばJSONを返す処理なのにMIMEタイプの指定が抜けていたりすると、デフォルトのtext/htmlとして扱われてしまいファイル内のJavaScriptが実行されてしまったり…

JSONを返すwebAPIは通常XML HttpRequestによるアクセスを想定していますが、APIが返すレスポンスデータがブラウザで直接閲覧されることにより攻撃が可能になる場合があります

・攻撃が可能なパターン
正しくないMIMEタイプで認識されることでおこる。
基本的にはMIMEタイプを正しく設定していれば問題ありませんが、古いIEではリスクが残ってしまう

対策

優先度 対応内容
必須 MIMEタイプを正しく設定
強く推奨 レスポンスヘッダ「X-Content-TypeOptions: nosniff」を設定
推奨 小なり記号などをUnicodeエスケープ
推奨 XML HttpRequestなどCORS対応の機能だけから呼び出せるようにする

2.ファイルダウンロードによるXSS(MIMEタイプをブラウザに誤認させるタイプの攻撃)

対象となる機能 ファイルのアップロード、ダウンロード機能
リスク なりすまし。特にセッション管理や認証のあるページでは被害が大きい

アップロードしたファイルを利用者がダウンロードする際に、ブラウザがファイルタイプを誤認する場合がある。
例えばPDFファイルを想定しているにも関わらずPDFデータ内にHTMLタグが埋め込まれている場合、条件によってはブラウザかまHTMLファイルと誤認されてしまい、JavaScriptが埋め込まれていた場合に実行されてしまう。
(攻撃を仕掛ける場合は攻撃者がアプリケーション利用者に罠を仕掛けて誤認させるように仕向ける)

IEの動作について
ダウンロードコンテンツをIEが処理する場合、そのContent-Typeが IEの扱えるものかを判断し、扱えるものはC ontent-Typeに従って処理を行う。
しかし扱えない種類の場合、URLに含まれる拡張子からファイルタイプを判定していまう。

ファイルダウンロード時の対策

優先度 対応内容
必須 ファイルのContent-Typeを正しく設定する
必須 レスポンスヘッダX-Content-Options: nosniff を出力
必要に応じて ダウンロードを想定したファイルにはレスポンスヘッダとしてContent-Disposition:attachment を指定する(アプリ側で開かずダウンロードファイルの指定になる)

3.JSONハイジャック

対象となる機能 JSONを出力するAPIに秘密情報を提供しているもの
想定されるシーン リンクのクリックなど、罠サイトの閲覧により
リスク 情報を抜かれることで起こるなりすましなど

通常JSONデータをscript要素で受け取ることはできないが、JSONを script要素で受け取るための手法をJSONハイジャックという。
(例外: JSONPでは JSONをコールバック関数の引数にすることでアプリケーションからデータを受け取ることができる。)

基本的にはブラウザ側の脆弱性であり(過去古いfire Foxで脆弱性があった)、現在はブラウザ側で対応されていますが、JSONハイジャックの手法は常に考案されていてその度に対策する背景があるため、アプリ側でも対応しておく方がよい。

対策

優先度 対応内容
強く推奨 レスポンスヘッダ「X-Content-TypeOptions: nosniff」を設定
推奨 リクエストヘッダ X-Requested-With: XMLHttpRequestの確認
推奨 XMLHttpRequestなどCORS対応の機能だけから呼び出せるようにする

以上X-Content-TypeOptionsについてと、それにまつわる脆弱性の例でした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[PHP]実行中の関数名を取得する

はじめに

業務で調べる機会があったので備忘録としてまとめました。

取得方法

実行中の関数は__FUNCTION__という定数に格納してある。

public function test() {
 echo __FUNCTION__;
}

出力結果

test

おまけ

__FUNCTION__のような使用する場所によって値が変化する定数(マジカル定数)は、PHP公式によれば9つ存在する。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP 7.3.9 をMACに入れる

ある案件に参加するので、開発環境を整えました。
php環境だったので、

$ composer install
$ phpenv: version `7.3.9' is not installed
$ phpenv: version `7.3.9' is not installed

と早速やってみたが、「phpenv: version `7.3.9' is not installed」と怒られたので、

$ phpenv install 7.3.9
$ [Error]: Definition 7.3.9 not found.

がーん。7.3.9がない!!

phpenv install -l
Available versions:
...
  7.3.6
  7.3.7
  7.3.8
  7.3snapshot
  7.4snapshot
  master

インストール可能な一覧にも出てこない!
えーーー。と思いながら、anyenvをアップデートしてみる。

$ anyenv update
Skipping 'anyenv'; not git repo
Updating 'anyenv/anyenv-update'...
Updating 'nodenv'...
 |  From https://github.com/nodenv/nodenv
 |  83b7614..631d0b6  master     -> origin/master
 |  * [new branch]      depfu/update/npm/bats-1.2.1 -> origin/depfu/update/npm/bats-1.2.1
 |  * [new tag]         v1.3.1     -> v1.3.1
 |  * [new tag]         v1.3.2     -> v1.3.2
 |  * [new tag]         v1.4.0     -> v1.4.0
Updating 'nodenv/node-build'...
 |  From https://github.com/nodenv/node-build
 |  80400640..c097b5be  master          -> origin/master
 |  * [new branch]        bot-sign        -> origin/bot-sign
 |  * [new branch]        depfu/update/npm/bats-1.2.1 -> origin/depfu/update/npm/bats-1.2.1
 |  * [new branch]        lowjs           -> origin/lowjs
 |  * [new branch]        quickjs         -> origin/quickjs
 |  * [new branch]        scrape-workflow -> origin/scrape-workflow
 |  * [new tag]           v4.9.11         -> v4.9.11
 |  * [new tag]           v4.6.3          -> v4.6.3
 |  * [new tag]           v4.6.4          -> v4.6.4
 |  * [new tag]           v4.6.5          -> v4.6.5
 |  * [new tag]           v4.6.6          -> v4.6.6
 |  * [new tag]           v4.6.7          -> v4.6.7
 |  * [new tag]           v4.6.8          -> v4.6.8
 |  * [new tag]           v4.6.9          -> v4.6.9
 |  * [new tag]           v4.7.0          -> v4.7.0
 |  * [new tag]           v4.7.1          -> v4.7.1
 |  * [new tag]           v4.7.2          -> v4.7.2
 |  * [new tag]           v4.8.0          -> v4.8.0
 |  * [new tag]           v4.8.1          -> v4.8.1
 |  * [new tag]           v4.8.2          -> v4.8.2
 |  * [new tag]           v4.8.3          -> v4.8.3
 |  * [new tag]           v4.9.0          -> v4.9.0
 |  * [new tag]           v4.9.1          -> v4.9.1
 |  * [new tag]           v4.9.10         -> v4.9.10
 |  * [new tag]           v4.9.2          -> v4.9.2
 |  * [new tag]           v4.9.3          -> v4.9.3
 |  * [new tag]           v4.9.4          -> v4.9.4
 |  * [new tag]           v4.9.5          -> v4.9.5
 |  * [new tag]           v4.9.6          -> v4.9.6
 |  * [new tag]           v4.9.7          -> v4.9.7
 |  * [new tag]           v4.9.8          -> v4.9.8
 |  * [new tag]           v4.9.9          -> v4.9.9
Updating 'nodenv/nodenv-default-packages'...
 |  From https://github.com/nodenv/nodenv-default-packages
 |  ee042af..9aa2cdf  master     -> origin/master
 |  * [new branch]      depfu/update/npm/bats-1.2.1 -> origin/depfu/update/npm/bats-1.2.1
 |  * [new tag]         v0.3.0     -> v0.3.0
 |  * [new tag]         v1.0.0     -> v1.0.0
Updating 'nodenv/nodenv-vars'...
Updating 'nodenv/nodenv-yarn-install'...
Updating 'phpenv'...
Updating 'phpenv/php-build'...
 |  error: Your local changes to the following files would be overwritten by merge:
 |  share/php-build/default_configure_options
 |  Please commit your changes or stash them before you merge.
 |  Aborting
 |  Failed to update. Use 'verbose' option for detailed, or 'force' option.
Updating 'phpenv/phpenv-composer'...
Updating 'anyenv manifest directory'...
 |  From https://github.com/anyenv/anyenv-install
 |  dcbcfe1..d9791df  master     -> origin/master

またエラー。

Updating 'phpenv/php-build'...
 |  error: Your local changes to the following files would be overwritten by merge:
 |  share/php-build/default_configure_options
 |  Please commit your changes or stash them before you merge.
 |  Aborting
 |  Failed to update. Use 'verbose' option for detailed, or 'force' option.
Updating 'phpenv/phpenv-composer'...

php-buildの設定ファイルにdiffがあるんだって・・・。
うまくマージしてよと思いながらも、

$ cd ~/.anyenv/envs/phpenv/plugins/php-build/share/php-build
$ git stash
$ cd bin
$ ./php-build update

無事、アップデートできた!

$ phpenv install -l
  ...
  7.3.9
  7.3snapshot
  7.4.0
  ...

「7.3.9」がある!!
じゃあ、揚々と、

$ phpenv install 7.3.9

-----------------------------------------
  "_X509_getm_notAfter", referenced from:
      _zif_openssl_x509_parse in openssl.o
      _zif_openssl_csr_sign in openssl.o
  "_X509_getm_notBefore", referenced from:
      _zif_openssl_x509_parse in openssl.o
      _zif_openssl_csr_sign in openssl.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [libs/libphp7.bundle] Error 1
make: *** Waiting for unfinished jobs....
-----------------------------------------

The full Log is available at '/tmp/php-build.7.3.9.20201009170543.log'.

エラー・・・。opensslのx86_64のライブラリが無いせいでリンクエラーになっているっぽい。
セットアップのエラーループ泣きたくなる。。。

困ったなーと思いながら、とりあえずアップデート

$brew upgrade openssl

10分くらいで完了!
ながい!!

再度、phpenv install 7.3.9 をしてみる

$ phpenv install 7.3.9
[Info]: Loaded extension plugin
[Info]: Loaded apc Plugin.
[Info]: Loaded composer Plugin.
[Info]: Loaded github Plugin.
[Info]: Loaded uprofiler Plugin.
[Info]: Loaded xdebug Plugin.
[Info]: Loaded xhprof Plugin.
[Info]: Loaded zendopcache Plugin.
[Info]: php.ini-production gets used as php.ini
[Info]: Building 7.3.9 into /Users/echi/.anyenv/envs/phpenv/versions/7.3.9
[Skipping]: Already downloaded and extracted https://secure.php.net/distributions/php-7.3.9.tar.bz2


[xdebug]: Installing version 2.9.8

[xdebug]: Compiling xdebug in /var/tmp/php-build/source/xdebug-2.9.8
[xdebug]: Installing xdebug configuration in /Users/echi/.anyenv/envs/phpenv/versions/7.3.9/etc/conf.d/xdebug.ini
[xdebug]: Cleaning up.
[Info]: Enabling Opcache...

[Info]: The Log File is not empty, but the Build did not fail. Maybe just warnings got logged. You can review the log in /tmp/php-build.7.3.9.20201009172959.log or rebuild with '--verbose' option
[Success]: Built 7.3.9 successfully.
Download composer.phar ...
Move composer.phar to /Users/echi/.anyenv/envs/phpenv/versions/7.3.9/composer

できたーーーー!!
ただ、opensslあげたので、なんとなく何かがうごかくなったかもなー。と、ドキドキ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ルーティングの基本(laravel,PHP)

web.php
//特定のHTTPメソッドに対応する場合

Route:○○('viewのパスを記入','コントローラー@アクションメソッド');

//複数のHTTPメソッドに対応する場合

Route::match(['〇〇','〇〇'],'viewのパスを記入','コントローラー@アクションメソッド');
//※['〇〇','〇〇']に指定した複数のメソッドを対応させることが可能

//全てのHTTPメソッドに対応する場合

Route::any('viewのパスを記入','コントローラー@アクションメソッド');

ルーティング情報をコントローラから取得する場合(ルートパラメーター)

web.php
#自動的に対応する値を引数に割り当ててる場合
Route::get('viewのパスを記入/{id}','コントローラ名@アクションメソッド');
#任意の値を引数に割り当てる場合
Route::get('viewのパスを記入/{id?}','コントローラ名@アクションメソッド');
#ルートパラメータを制限したい場合
Route::get('viewのパスを記入/{id}','コントローラ名@アクションメソッド')->where([id =>'[0-9],{2,3}'])
//[0-9]->0~9までの数値に対応
//{2,3} ->10桁から100桁の数値に対応
//定義済み関数のpreg_matchと同じ 
〇〇controller.php
#自動的に対応する値を引数に割り当ててる場合
class Controller extends Controller
{
    public function param(int $id){ 
        return 'id:'.$id;

    }

//.....
〇〇controller.php
#任意の値を引数に割り当てる場合
class Controller extends Controller
{
    public function param(int $id =任意の値){ 
        return 'id:'.$id;

    }

//.....
〇〇controller.php
#正規表現の場合
class Controller extends Controller
{
    public function param(int $id =任意の値){ 
    //※任意の値はルートパラメータで制約しているため従う必要がある
    //例:現在は[0~9],{2-3}に指定しているので 0〜9の数値で尚且つ100桁までの数値を定義する必要がある
     return 'id:'.$id;

    }

//.....

web.php
//可変長パラメータ
Route::get('viewのパスを記入{keywd?}','コントローラ@アクションメソッド')>where('keywd','.*')
//('keywd','.*') ->任意の文字が0文字~~+∞という意味
//可変長は長さが決まっていないことを挿す





  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

brefphpを使って簡単にLaravelをサーバレス環境で動かす

はじめに

ここではbrefについてと、実際の使い方や使ってみた所感などをまとめてみようと思います。

brefphp とは?

PHPアプリケーションをAWS Lambdaに簡単にデプロイするための Composer パッケージです。
コマンド1つでサーバーからアプリケーションのデプロイまで行えます。

:information_source: 使い方

Step :one: serverless のインストール

bref は serverless コマンドを使用してAWS環境にデプロイを行います。
以下のコマンドでインストールしましょう。

npmの場合

npm install -g serverless

yarnの場合

yarn global add serverless

追加したら以下のコマンドでちゃんと実行できるか確認しましょう

$ serverless --version
Framework Core: 2.4.0
Plugin: 4.0.4
SDK: 2.3.2
Components: 3.2.1

Step :two: Laravelプロジェクトの作成 [公式]

今回はLaravelで使うため、プロジェクトを作成します。

Laravelインストーラーがない場合はインストールします

composer global require laravel/installer

プロジェクトを作成します。

laravel new brefphp-test

Step :three: brefphp パッケージのインストール [公式]

作成したLaravelプロジェクトのディレクトリに移動して、
brefphpをインストールします。

composer require bref/bref bref/laravel-bridge

デフォルトのサーバ構成設定ファイルを作成します。

php artisan vendor:publish --tag=serverless-config

Step :four: デプロイの準備

「アクセスキーID」と「シークレットアクセスキー」の作成

デプロイ前に、デプロイ先のサーバ(AWS)のアクセスキーとシークレットキーを使用します。
IAMのユーザー追加画面でテスト用ユーザーを作りましょう。

  1. ユーザー名を決めて、アクセスの種類の「プログラムによるアクセス」をチェックします。
    WS000000.jpg

  2. アクセス権限の設定です。「既存のポリシーを直接アタッチ」を選択して「AdministratorAccess」を選択します。
    名前の通り最強権限なので、発行されるキーは絶対に外部に漏らさないでください!
    WS000001.jpg

  3. タグはよしなに追加します。(自分は何もしません)
    WS000002.jpg

  4. ユーザーの追加完了です。
    「アクセスキーID」と「シークレットアクセスキー」をメモしておいてください。
    WS000004.jpg

プロファイルの追加

メモした「アクセスキーID」と「シークレットアクセスキー」をプロファイルに登録します。

$ aws configure --profile <プロファイル名>

AWS Access Key ID [None]: <アクセスキーID>
AWS Secret Access Key [None]: <シークレットアクセスキー>
Default region name [None]:
Default output format [None]:

すると、 ~/.aws/credentials (Windowsの場合は %USERPROFILE%/.aws/credentials) にプロファイルが登録されます。

/.aws/credentials
[<プロファイル名>]
aws_access_key_id = <アクセスキーID>
aws_secret_access_key = <シークレットアクセスキー>

Step :five: デプロイ

以下のコマンドでデプロイします。
<プロファイル名>は、先程(Step4)で登録した名前を指定してください。

$ serverless deploy -v --aws-profile=<プロファイル名>

Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
~~~~~~~[色々ログ出てきて]~~~~~~~
Serverless: Stack update finished...
Service Information
service: laravel
stage: dev
region: us-east-1
stack: laravel-dev
resources: 15
api keys:
  None
endpoints:
  ANY - https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev
  ANY - https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/{proxy+}
functions:
  web: laravel-dev-web
  artisan: laravel-dev-artisan
layers:
  None

Stack Outputs
WebLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:000000000000:function:laravel-dev-web:2
ArtisanLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:000000000000:function:lara![WS000000.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157186/369830d6-c723-975d-2b78-c94add355649.jpeg)
vel-dev-artisan:2
ServiceEndpoint: https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev
ServerlessDeploymentBucketName: laravel-dev-serverlessdeploymentbucket-o2rnhi5yd9v6

生成されたエンドポイントにアクセスして、LaravelのWelcomeページが出てくれば成功です
Laravel.png

AWS Lambdaの関数にも追加されています。
WS000000.jpg

Step :six: 環境の削除

$ serverless remove コマンドで環境を削除できます。

$ serverless deploy -v --aws-profile=<プロファイル名>

Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
~~~~~~~[色々ログ出てきて]~~~~~~~
Serverless: Stack removal finished...
Serverless: Stack removal finished...

:desktop: ローカル環境の構築

Dockerでローカル環境を構築します。
すでにローカル用のイメージは用意されているので、すぐに立ち上げることができます。

Laravelプロジェクトと同じディレクトリに docker-compose.yml の作成

docker-compose.yml
version: "3.5"

services:
    web:
        image: bref/fpm-dev-gateway
        ports:
            - '8000:80'
        volumes:
            - .:/var/task
        links:
            - php
        environment:
            HANDLER: public/index.php
            DOCUMENT_ROOT: public
    php:
        image: bref/php-74-fpm-dev
        volumes:
            - .:/var/task:ro

docker-compose up -d でコンテナを起動します。1

http://localhost:8000 にアクセスするとLaravelのWelcomeページが表示されます。

:moneybag: 料金について

ローカル環境には料金はかかりません。
AWSにデプロイした際に以下のサービスを利用するため、料金が発生します。

  1. Lambda
  2. API Gateway
  3. S3
  4. CloudFormation

所感

個人開発で使って便利だったので、会社のプロジェクトでも導入してみました。
LambdaやAPI Gatewayによるいろいろな制限があったりして、思うように行かなかった部分もありますが、なんとかサービスもリリースしているような状態です。

EC2に比べてLambdaやAPI Gatewayの料金は基本的にトラフィック依存なので、
アクセス数のそんなにないサービスでは、かなりのコスト削減になりました。

:warning: 発生した問題とその対策

実際にプロジェクトに導入した際に発生した問題と、それについての対策を記述します。
もし似たような問題が発生した場合は参考になればと思います。

POSTで10MBを超えるファイルをアップロードできない

API GatewayのPOSTリクエストサイズの最大が10MBのため、大容量のファイルをPOSTできません。
最終的にS3にアップロードする予定だったので、S3でPresigned URL2を発行して、それに対しアップロードするようにしました。

6MBを超えるデータを返せない

またもやAPI Gatewayの制約により、レスポンスの最大は6MBです。
(まぁ、6MBなんて超えることなんて稀ですが…)
こちらも一度S3にアップロードしてPresigned URLを生成し、
フロントエンドから直接S3のURLを参照するようにしました。

APIのタイムアウトの最長が29秒

API Gatewayの制約上、29秒でタイムアウトしてしまいます。
なので、重い処理はAmazon SQSに投げて処理するようにしました。

PR

brefのSlackコミュニティに日本語チャンネルができました。
一緒にbrefについて語りましょう?


  1. 初回のみイメージをビルドするため時間がかかります。 

  2. 一時的に有効なURLを発行して直接S3にアップロードできるURL 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel ディレクティブについてのまとめ

laravel ディレクティブについて

bladeテンプレート(view)の中で利用できる命令のこと

○○.php
@foreach(連想配列as変数)
//PHPのforeachと同じ
@if条件式
//phpのifと同じ
@unless(変数)
//falseの場合に出力
@iseet(変数)
//trueの場合に出力
@empty(変数)
//変数が存在しない場合のみ(null)の時に出力
@switch
//phpのswitchと同じ
@for
//phpのfor文と同じ
@break
//phpのbreak文と同じ
@loop
//ちょっと特殊 ループ変数と呼ばれる ※わかりづらいので下記に例あり
//index:インデックス番号(0スタート)
//iteration:繰り返し数(1スタート)
//remaining:残っている要素数
//count:配列の総数
//first:最初の項目->>>配列の先頭の時には1を返す
//last:最後の項目 ->>>配列の最後尾の時には1を返す
//even:偶数回目か
//odd:奇数回目か
//depth:入れ子レベル
//parent:親のループ変数(ネストした入れ子の場合)
@forelse
//処理
@empty 
//配列が空の場合の処理
//配列が空の場合の出力を設定できる
//※データの表示によって振り分けるのに@ifディレクティブよりも@forelseの方がおすすめ
@php
//<?phpと同じだが使用は例外的とのこと
@yield(name,[,default])
//name テンプレートからプレイスホルダー(空)の変数を受け取る時に使用

//①
@section(name)
//default
 @show
//②
@section()
@parent
//default
//名前が示す通りにコンテンツのセクションを定義※上記の様に複数の定義方法がある

//default-> 規程のコンテンツ(アクション変数とか)
@each(path,データ,仮変数,配列が空の時に実行)


※※loopディレクティブの例

controller.php
    public function foreach_loop()
    {
        return view('view.foreach_loop', [
            'weeks' => [ '月', '火', '水', '木', '金', '土', '日' ]
        ]);

    }

foreach_loop.php
<tr>
  <th></th>
  <th>index</th>
  <th>iteration</th>
  <th>count</th>
  <th>first</th>
  <th>last</th>
  <th>even</th>
  <th>odd</th>
  <th>depth</th>
</tr>
@foreach ($weeks as $week)
  <tr>
    <td>{{ $week }}</td>
    <td>{{ $loop->index }}</td>
    <td>{{ $loop->iteration }}</td>
    <td>{{ $loop->count }}</td>
    <td>{{ $loop->first }}</td>
    <td>{{ $loop->last }}</td>
    <td>{{ $loop->even }}</td>
    <td>{{ $loop->odd }}</td>
    <td>{{ $loop->depth }}</td>
  </tr>
@endforeach
</body>
</html>

スクリーンショット 2020-10-08 19.12.28.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

キャメルケースとスネークケース

キャメルケース

companyIdblogCategoryのように2語3語と単語同士をつづけた書く書き方。

  • 先頭の単語が小文字

    • 関数名は先頭小文字。例:createBlogCategory()
    • 変数名(引数名)は先頭小文字。例:companyId
  • 先頭の単語が大文字をパスカルケースまたはアッパーキャメルケースと呼ぶ

    • class名は先頭大文字。例:BlogCategory

スネークケース

company_idblog_catefgoryのように2語3語と単語同士をアンダーバーで挟んでつなげる書き方。

  • 定数はすべて大文字。例:BLOG_CATEGORY
  • データベースなどで使われます。

ケバブケース

company-idblog-catefgoryのように2語3語と単語同士をハイフンで挟んでつなげる書き方。

  • HTMLのclass名で使われます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「暗記」ダメ!!!!!!!!! 絶対!!!!!!!!

暗記ってダメなの?

学習をしていく中で1度は耳にする

「暗記」はダメ

といった論調があると思います

最初に結論を言っておくと私はこの記事で
暗記を全て否定するのではなく、拾ってくる情報リソースの多くで頻出している「単語」や「概念」は暗記しましょうね。と伝えたいです。

私の背景

半年前の私は

・HTMLって何
・PHP何それ弱そう
・プログラミング=ホームページを作る事でしょ?

といったようにプログラミングに関してほとんど無知の状態でした。
今では半年間毎日1日8時間の学習を継続しているので、そんなふざけた状態ではないですが、当時は間違いなく全くの初学者でした。

私は初学者だった当時スクールに通うことはせずネットのPHP教材を購入し独学をはじめました。

少し話がそれますが、この半年でオンラインなどの交流会でスクールを卒業された方の話しを10人前後聞いてきたのですが、その方々の満足度は大変高い印象でした。ただし、接頭辞的な感じで、「挫折しない為には」いいですね。といった言い回しをされる方が多い印象でした笑

私も半年間独学をしてきた経験と周りの卒業された方の意見を合わせて考えると時間効率を求めるならスクールは大いにありだと思います。
スクールを通う段階としてはプロゲートで5つくらいの言語を一通りやってみてからでいいのかな〜といった印象です。
お金に余裕があって少しでも一人でやる自信がないと思っている方は即決でスクールを選んだ方が効率は絶対にいいです(こんな事言ってますがスクールの回し者ではありません笑。なんならエンジニアyoutuerみたいに一回くらい企業案件やってみたいです。この動画はテックアカ、、、、?)

さて本題に戻ります。

私はスクールには通いませんでしたがネットで教材を購入しそれを独学しました。その教材の中には「暗記してください」などとは書かれて言いませんでしたが、重要なポイントとして取り上げられているTipsはたくさんありました。

要するに何が言いたいかと言うと

単語レベルの理解はもちろん、多くの人が共通して主立って「重要」と言っている事は四の五の言わず暗記した方が後の開発効率がスムーズになる。

と言うのが私の意見です。

そんなの当たり前だろ。。記事にすることじゃないよね。。と思われるかもしれませんが

初学者の方で
・「暗記」をひとまとめにして「悪」と捉えている
・「暗記」って本当にダメなのか疑心暗鬼になっている

方は少なくないと思い、この記事を書きました。

少なからず私が学習初期の段階では色んな情報に触れて
「暗記は効率悪いんだ」と一括りにしてしまっていました。

暗記しなくてもいい事

もちろん暗記する方が圧倒的に効率が悪くなることもあると思います。
そこで、大きく分けてみると3つに分類できるかなと思います。
※前提として忘れないで頂きたいのはこれは学習して半年程度且つ実務未経験者の意見です?また、PHPやLaravel以外の言語に関しては詳しくないのでご了承ください。笑

1. コードの書き方を暗記する
  私が考えるに暗記してはいけないと情報発信されている方の本質的部分はここだと思います。
  ここは私が細かく言うまでもないですが、効率が悪く、キリがないですよね。笑
  これをやってしまっている方がいたら今すぐにその習慣を辞めて、コードを書いて覚えましょう!
  無心で書き続けていればいつの間にか覚えます。必ずです。

2. 開発環境の構築の仕方
  これはキリがないとか効率が悪いとか言うより初学者のうちにここを重点的に覚えようとすると、挫折率が上がってしまうかと思います。
  サーバーやネットワークの知識が必要となってくるので初学者の段階は
 「そう言うものを使っているんだな」程度の理解でいいのではないでしょうか。

3. 関数を全て覚えようとする
  これもコードを暗記するに近いですが、仮に全て覚えても一生使わないものも出てくる可能性があり且つ効率が悪いからです。
  経験上、使用頻度の高い関数はコードを書いて入れば勝手に覚えます。つまり使用頻度が高い=重要度の高い関数と言う認識で良いかと。

暗記した方がいい事

さて、今度は逆に暗記した方がいい事について少しみていきましょう。
冒頭でも述べましたが、暗記をした方が良い内容は 拾ってくる情報リソースの多くで頻出している「単語」や「概念」の事でしたね。

では具体的にはどう言った単語や概念でしょうか。
私の経験から「早めに覚えておいてよかった」「ここは早めに深く覚えておけばよかった」点から解説します。
※ここからはさらに個人的主観が強くなりますでご了承ください
以下の内応は一応、PHPを対象としていますの
if文/繰り返し文/関数/引数/戻り値/変数
と言ったどのプログラミング言語でも共通する基礎の部分は除きます

ざっくりですが以下2点の理解をまずは「暗記」する事を私はお勧めします。

1.$GETと$POST

2.データベースは何をしているか

詳しくは次の段落で書いていきます。

$GETと$POST

 [なぜこれを覚えておいた方が良いのか]

 それはPHP言語でCRUDを実装する時に超頻出の概念だからです。
 (CRUDとは、システムに必要な4つの主要機能である「Create(生成)」「Read(読み取り)」「Update(更新)」「Delete(削除)」の頭文字を並べた用語です。)
 CRUDはWEBアプリ制作する上で基本的な考え方になります。

 PHPとよく比較されるプログラミング言語が、JavaScriptです。この両者はスクリプト言語でも、動作については全く異なります。
 JavaScriptはHTMLやCSS、画像と同じようにブラウザを表示しているPCにファイルをダウンロードしてから実行し動作するのに対し
 PHPはWebサーバ上にファイルを置いて、以下の順で実行されます。

 1.ブラウザを見ているユーザがクリックなど何かの操作をする
 2.その動作を受けたプログラムがサーバで動作する
 3.動作結果をレスポンスとして、インターネット経由で送り、ブラウザ上にHTMLを表示する
 
このようにPHPのような言語は、サーバサイドのプログラミング言語と呼ばれ、PHPはサーバー側で動くプログラミング言語でこの全体の処理の中でも、$_GETと$_POSTは超頻出です。つまりこの2つの処理が何をしているのかを「暗記」する事はPHPを早く上達する上では効率が良いと言えます。
 

 GETやPOSTについてもっと詳しく知りたいと言う方はこちらの書籍を読んでみるのもいいかと思います。
 HTTP通信についての理解が深まりクライアントとサーバーが裏でどんな事をやっているかのイメージがつくかと思います。
www.amazon.co.jp/dp/4774142042

データベースは何をしているか

データベースを扱うアプリケーションでは「CRUD」のアクションが基本となります。
つまり、データベースに対して行うアクションは、

・データベースにデータを「新規登録」する、
・そのデータを「読み出す」、
・そのデータを「変更し上書き」登録する、
・そのデータを「削除」する、

という、「基本この4つしか無い」ということです。

つまりこの流れのイメージを意識的に暗記する事でコードを書いている時に、今何やっているかの把握ができ結果として開発効率が上がると考えます。

[補足]
個人的にはSQL文法も暗記しておいた方が効率が良いのではと思っています。これも超頻出なので。笑

最後に

まとめとして、頻出する単語や概念、その周りの流れは覚えてしまった方が結果的に効率が上がると言う事です。

本記事とは少しずれますが、有名な方の発言を鵜呑みにするのではなく、その意見を一回自分の頭に持ち込んで、処理して自分なりの答えを導き出すと言う事も重要です。この「脳に対する意識的な習慣」ができていると、エラー時にもイライラしなくなると思います。(エラーでイライラしてしまう人は他責思考が強い人だと思う)
この事は自戒を含めて伝えたいなと思いました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「暗記」ダメ!!!! 絶対!!!!それって本当ですか?

暗記ってダメなの?

学習をしていく中で1度は耳にする

「暗記」はダメ

といった論調があると思います

最初に結論を言っておくと私はこの記事で
暗記を全面的に否定するのではなく、拾ってくる情報リソースの多くで頻出している「単語」や「概念」を意図的に暗記したほうが(集中的に学習する)後の学習効率、開発効率が上がる。と伝えたいです。

想定読者

・自分が初学者と思っている方
・暗記してる事に自覚がある方
・PHP初学者

私の背景

半年前の私は

・HTMLって何
・PHP何それ弱そう
・プログラミング=ホームページを作る事でしょ?

といったようにプログラミングに関してほとんど無知の状態でした。
今では半年間毎日8時間の学習を継続しているので、流石にその状況からは抜け出せたのですが、当時は全くの初学者でした。

学習方法に関しては効率は置いといて挫折しない自信はあったので独学を選択し、主にネットでPHPの教材を購入して学習を行っていました。

少し話がそれますが、この半年でオンラインなどの交流会で10人前後の方にスクールを卒業されての感想を伺ったのですが、その方々の満足度は大変高い印象でした。
ただし、接頭辞的な感じで「挫折しない為には」といった言い回しをされる方が多い印象でした笑

私が半年間独学をしてきた経験と周りの卒業された方の意見を合わせて考えると時間効率を求めるならスクールは大いにありだと思います。
スクールを通う段階としてはプロゲートで5つくらいの言語を一通りやってみてからでいいのかな〜といった印象です。
お金に余裕があって少しでも一人でやる自信がないと思っている方は即決でスクールに通う事を選択した方が絶対にいいです(別にスクールの回し者ではありません笑。なんならエンジニアyoutuerみたいに一回くらい企業案件やってみたいです。この動画はテックアカ、、、、?)

さて本題に戻ります。

私はスクールには通いませんでしたがネットで教材を購入しそれを独学しました。その教材の中には「暗記してください」などとは書かれて言いませんでしたが、重要ポイントとして取り上げられているTipsはたくさんありました。今教材を見返してもその部分(その周辺の知識)を学習初期の段階で、暗記しておけば後の開発効率はよくなるだろうなー。というのが私の意見です。
(ただし、最初からそこだけを集中して学習するよりかは、一般的な書籍や、Udemyなどの動画講義を一通り終えた後に重要部分を集中的に学ぶ感じが良いかと思います。)

要するに何が言いたいかと言うと

単語レベルの理解はもちろん、多くの人が共通して主立って「重要」と言っている事は四の五の言わず暗記した方が後の開発効率がスムーズになる。

と言うのが私の意見です。

そんなの当たり前だろ。。記事にすることじゃないよね。。と思われるかもしれませんが

プログラミング初学者の方で
・「暗記」をひとまとめにして「悪」と捉えている
・「暗記」って本当にダメなのか疑心暗鬼になっている

方は少なくないと思い、この記事を書きました。

少なからず私は学習初期の段階で様々な情報に触れて
「暗記は効率悪いんだ」と一括りに悪いイメージをもっていました。

暗記しなくてもいい事

こんな事を偉そうに言っていますが基本、暗記する事は圧倒的に効率が悪いと思います。
そこで、具体的に効率が悪くなる項目を大きく3つに分けて解説していきたいと思います。

※前提として忘れないで頂きたいのはこれは学習して半年程度且つ実務未経験者の意見です?また、PHPやLaravel以外の言語に関しては詳しくないのでご了承ください。笑

1. コードの書き方を暗記する
  私が考えるに暗記してはいけないと情報発信されている方の本質的部分はここだと思います。
  ここは私が細かく言うまでもないですが、効率が悪く、キリがないですよね。笑
  これをやってしまっている方がいたら今すぐにその習慣を辞めて、コードを書いて覚えましょう!
  無心で書き続けていればいつの間にか覚えます。必ずです。

2. 開発環境の構築の仕方
  これはキリがないとか効率が悪いとか言うより初学者のうちにここを重点的に覚えようとすると、挫折率が上がってしまうかと思います。
  サーバーやネットワークの知識が必要となってくるので初学者の段階は
 「そう言うものを使っているんだな」程度の理解でいいのではないでしょうか。あなたの目的に沿った学習を優先しましょう

3. 関数を全て覚えようとする
  これもコードを暗記するに近いですが、仮に全て覚えても一生使わないものも出てくる可能性があり且つ効率が悪いからです。
  経験上、使用頻度の高い関数はコードを書いて入れば勝手に覚えます。つまり使用頻度が高い=重要度の高い関数と言う認識で良いかと。

暗記した方がいい事

さて、今度は逆に暗記した方がいい事について少しみていきましょう。
冒頭でも述べましたが、暗記をした方が良い内容は 拾ってくる情報リソースの多くで頻出している「単語」や「概念」の事でしたね。

では具体的にはどう言った単語や概念が当てはまるのでしょうか。
私の経験から「早めに覚えておいてよかった」「ここは早めに覚えておけばよかった」という主観から例をあげ解説します。
※ここからはさらに個人的主観が強くなりますでご了承ください
一応以下の内応は、PHP言語を対象としていますの

if文/繰り返し文/関数/引数/戻り値/変数
と言ったどのプログラミング言語でも共通する基礎の部分は除きます

ざっくりですが私は以下2点の理解を優先的に深める事をお勧めします。

1.$GETと$POST(HTTP通信とスーパーグローバル変数の扱い方)

2.データベースは何をしているか

詳しくは次の段落で書いていきます。

$GETと$POST

 [なぜこれを覚えておいた方が良いのか]

 それはPHP言語でCRUDを実装する時に超頻出の概念だからです。
 (CRUDとは、システムに必要な4つの主要機能である「Create(生成)」「Read(読み取り)」「Update(更新)」「Delete(削除)」の頭文字を並べた用語です。)
 CRUDはWEBアプリ制作する上で基本的な考え方になります。

 PHPとよく比較されるプログラミング言語が、JavaScriptです。この両者はスクリプト言語でも、動作については全く異なります。

 JavaScriptはHTMLやCSS、画像と同じようにブラウザを表示しているPCにファイルをダウンロードしてから実行し動作するのに対し
 PHPはWebサーバ上にファイルを置いて、以下の順で実行されます。

 1.ブラウザを見ているユーザがクリックなど何かの操作をする

 2.その動作を受けたプログラムがサーバで動作する

 3.動作結果をレスポンスとして、インターネット経由で送り、ブラウザ上にHTMLを表示する
 
このようにPHPのような言語は、サーバサイドのプログラミング言語と呼ばれ、PHPはサーバー側で動くプログラミング言語でこの全体の処理の中でも、$_GETと$_POSTは超頻出です。つまりこの2つの処理が何をしているのかを意識的に「暗記」する事はPHPを早く上達する上では効率が良いと言えます。(暗記より理解という言葉を使う方がいい気がしてきました笑)
 

 GETやPOSTについてもっと詳しく知りたいと言う方はこちらの書籍を読んでみるのもいいかと思います。
 HTTP通信についての理解が深まりクライアントとサーバーが裏でどんな事をやっているかのイメージがつくかと思います。
www.amazon.co.jp/dp/4774142042

データベースは何をしているか

データベースを扱うアプリケーションでは「CRUD」のアクションが基本となります。
つまり、データベースに対して行うアクションは、

・データベースにデータを「新規登録」する、
・そのデータを「読み出す」、
・そのデータを「変更し上書き」登録する、
・そのデータを「削除」する、

という、「基本この4つしか無い」ということです。

つまりこの流れのイメージを意識的に暗記する事でコードを書いている時に、今何やっているかの把握ができ結果として開発効率が上がると考えます。

[補足]
個人的にはSQL文法もスラスラ書けるようになるまで暗記しておいた方が効率が良いのではと思っています。これも超頻出なので。笑

最後に

まとめとして、頻出する単語や概念、その周りの流れを最初に覚えてしまった方が結果的に効率が上がると言う事です。

本記事とは少しずれますが、影響力のある発信者の意見や、ネットに転がっている情報を全て鵜呑みにするのではなく、その情報を一度は自分の頭に持ち込んで、処理して自分なりの答えを導き出すと言う事も重要です。

この「脳に意識的に負荷を与える習慣」ができていると、例えばエラー時にもイライラしなくなると思います。(エラーでイライラしてしまう人は他責思考が強い人だと思う)
この事は自戒を含めて書き残しておきます思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPでコードを書いていたら突如画面が真っ白になった時の話し

 はじめに

釣りみたいなタイトルですがパソコンの不備などで起きた事象ではなく、しっかりとプログラミングを書いてエラーが発生した事で起きた現象です。笑

原因

結論から申しますと、
この現象の原因は、exit文を記述する位置に問題がありました。

エラー内容は以下の通り日本語にすると
「fetchというメンバー関数はありません」と怒られています。
(おそらく当時のコードはexit文の後にDB操作をしていたのでしょう)

Fatal error: Uncaught Error: Call to a member function fetch() on bool in 
階層フォルダ\階層ファイル Stack trace: #0 {main} thrown in 
階層フォルダ\階層ファイル on line 21

exit文とは

スクリプトを強制終了させる文です。

exit;//処理の終了
exit ('ここで終了');//処理の終了
exit (0);//処理の終了

exit文は、スクリプトの処理を「exit;」と記述した箇所で終了させます。exitは言語構造です。文字列や数値などのステータスを指定しない場合は、「 ( ) 括弧 」無しで記述できます。

私は1番上以外の記述はした事がないです。

解決策

ブラウザの画面が真っ白になった場合は、exit文の位置をみてみましょう。

見方は簡単でその後の処理は行われないと考えればOKです笑

※記述した箇所でスクリプトが強制的に終了しているため、コードの書き方によっては、エラー文が発生せずにただただ画面が真っ白い状態になる事もあると思います。

焦らないで

私は当時PHPを触り始めて間もない頃だったので、ブラウザと一緒に頭も真っ白になりました。

ただし、落ち着いて起きている現象やエラーを理解して行けばその先には必ず成長が待っています。今回は私自身過去のエラーの中でインパクトのあったものを取り上げましたが、課題解決の根本的な方法は一緒だと思います。

私も他人いとやかく言える技術レベルではありませんが焦らず一歩づつ共に成長していきましょう。

参考URL

[URL]https://teratail.com/questions/11286

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Moodle 3.9 - 質問

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Codewars] Find the odd int

概要

Codewarsの問題 Find the odd intの回答の復習とベストプラクティスをまとめる個人メモです。

問題文

Given an array of integers, find the one that appears an odd number of times.
There will always be only one integer that appears an odd number of times.

整数の配列の中から奇数回出現する数値を求める。


findIt([20,1,-1,2,-2,3,3,5,5,1,2,4,20,4,-1,-2,5]);

自分の回答

二重ループを行い出現した数だけ変数を増加させ、2で割り切れるかどうかチェックしました。

function findIt(array $seq) : int
{
    $count = 0;
    for($i=0; $i<count($seq); $i++){
      for($j=0;$j<count($seq); $j++){
        if($seq[$i] === $seq[$j]){
          $count++;
        }
      }
      if ($count % 2 == 1){
        return $seq[$i];
      }
      $count = 0;
    }
}

ベストプラクティス

array_count_values関数を使用し、配列に出現する値の数を数えています。
戻り値は仮想配列です。
https://www.php.net/manual/ja/function.array-count-values.php

function findIt(array $seq) : int
{
    $nums = array_count_values($seq);
    foreach ($nums as $key => $val) {
      if ($val % 2) {
        return $key;
      }
    }
}

変数に格納していないパターンも多かったですが、どちらにせよarray_count_valuesを使用すべきでした。

    foreach (array_count_values($seq) as $key => $value) {
        if ($value%2 == 1){
            return $key;
        }
    }

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む