20200907のPHPに関する記事は19件です。

AWSを使ったWordPress環境構築(単一構成)

事前準備

EC2インスタンスを作成

SSH接続

$ssh -i .ssh/key.pem ec2-user@public_ip

※key.pemはssh_key

※public_ipはインスタンスのpublic_ip

Apacheのインストール

  • Apachのインストール・起動
$ sudo yum install -y httpd
$ sudo systemctl start httpd

MySQL5.7のインストール

MySQL Yum RepositoryからMySQL5.7をインストールする。

  • Yumリポジトリの情報のインストール
$ sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
  • MySQL8.0リポジトリを無効にし、MySQL5.7リポジトリを有効にする
$ sudo yum-config-manager --disable mysql80-community
$ sudo yum-config-manager --enable mysql57-community
#適用されているか確認
$ cat /etc/yum.repos.d/mysql-community.repo
  • MySQLのインストール・起動
$ sudo yum install -y mysql-community-server
$ sudo systemctl start mysqld
  • MySQLの初期パスワードの確認
$ sudo cat /var/log/mysqld.log | grep root@localhost
[Note] A temporary password is generated for root@localhost: 12桁の文字列
  • MySQLのパスワード変更
$ mysqladmin -uroot -p password
Enter password:古いパスワード
New password:新しいパスワード
Confirm new password:新しいパスワード
#Warnigがでても変更はできています
Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.

Passwordのポリシーについて

  • WordPress用のDB・ユーザーを作成する
$ mysql -uroot -p
Enter password:設定したパスワード
#WordPress用のユーザー作成
mysql> CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'wordpressユーザーのパスワード';
#WordPress用のDB作成
mysql> CREATE DATABASE `wordpress`;
#DB権限を作成したユーザーに付与
mysql> GRANT ALL PRIVILEGES ON `wordpress`.* TO "wordpress"@"localhost";
#設定反映
mysql> FLUSH PRIVILEGES;
mysql> EXIT;

PHP7.4のインストール

sudo yum install phpを実行すると、PHP5.4がインストールされてしまします。

Amazon LinuxのリポジトリにPHP5.4しかないためです。

amazon-linux-extrasを使用することで解決できます。

  • amazon-linux-extrasが存在するかの確認
$ which amazon-linux-extras
/usr/bin/amazon-linux-extras
  • amazon-linux-extrasがインストールされていない場合は、インストールを行う
$ sudo yum install -y amazon-linux-extras
$ sudo yum update -y
  • amazon-linux-extrasからPHP7.4をインストールする
$ sudo amazon-linux-extras install -y php7.4
$ sudo yum clean metadata
#追加でパッケージをインストール(必要なければ不要です。)
$ sudo yum install -y php-mbstring php-xml
$ sudo yum update -y

WordPressのインストール

  • WordPressをインストール
#インストールしたいディレクトリに移動
$ cd ~
$ wget http://ja.wordpress.org/latest-ja.zip
$ unzip latest-ja.zip
#サンプルをコピー
$ cp wordpress/wp-config-sample.php wordpress/wp-config.php
$ sudo vim wordpress/wp-config.php

#DBの設定値を変更する。
define( 'DB_NAME', 'database_name_here' );
define( 'DB_USER', 'username_here' );
define( 'DB_PASSWORD', 'password_here' );
define( 'DB_HOST', 'localhost' );

#セキュリティーキーの変更する。
define( 'AUTH_KEY',         'put your unique phrase here' );
define( 'SECURE_AUTH_KEY',  'put your unique phrase here' );
define( 'LOGGED_IN_KEY',    'put your unique phrase here' );
define( 'NONCE_KEY',        'put your unique phrase here' );
define( 'AUTH_SALT',        'put your unique phrase here' );
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
define( 'LOGGED_IN_SALT',   'put your unique phrase here' );
define( 'NONCE_SALT',       'put your unique phrase here' );

※セキュリティキーはオンラインジェネレータ を使用してください。

  • Apachの設定

Amazon Linuxの場合、 .htaccess がディフォルトで無効となっているため設定を行う必要がある。

実際の親ファイル/etc/httpd/conf/httpd.confではなくconf.dに設定を記載する。

$ sudo vim /etc/httpd/conf.d/file_name.conf

#「sample」にはアクセスしたいURIを指定
#「/home/ec2-user/wordpress/」にはインストールしたディレクトリを指定する
Alias /sample/ /home/ec2-user/wordpress/
<Directory "/home/ec2-user/wordpress">
  AllowOverride All
  Options None
  Require all granted
  #ipを制限する場合に記載
  Require ip ××××××××××××
</Directory>

#Apache文法の確認
$ sudo httpd -t
Syntax OK
$ sudo systemctl restart httpd
  • http://ホスト/sample/にアクセスしてWordPressの初期設定画面が開ければ成功です!

  • アクセスした際に403エラーとなる場合は権限設定を行う。

#実行権限の付与
#「/home/ec2-user」にはインストールしたディレクトリを指定する
$ sudo chmod o+x /home/ec2-user

間違っている点があればお教えください!
冗長化構成は後日アップします!

参考

Amazon Linux による WordPress ブログのホスティング

CentOS7にyumでMySQL5.7最新版をインストールする

AWS EC2(Amazon Linux)にPHP7.4をインストール

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

PHUMLでPHPのクラス図を画像で作成する

PHPのソースコードからクラス図を自動生成

PHPSTORMにはクラス図を作成してくれる機能がついているそうですがお家環境にはPHPSTORM入っていないので
クラス図を自動生成してくれるツールを探していてphumlというツールを発見しました。
ちなみに私はubuntu使ってますがwindowsやmacでもphpさえ入れていれば動くと思います。

インストール

https://github.com/jakobwesthoff/phuml
からダウンロードして適当な場所に展開しましょう。
僕は~/.localにphumlとして展開しました。

展開するとphpで実行出来るようになります。

$php ~/.local/phuml/src/app/phuml
phUML Version 0.2 (Jakob Westhoff <jakob@php.net>)
Usage: phuml [-h|-l] [OPTIONS] <DIRECTORY> <PROCESSOR> [PROCESSOR OPTIONS] ... <OUTFILE>

Commands:
    -h      Display this help text
    -l      List all available processors

Options: 
    -r      Scan given directorie recursively

Example:
    phuml -r ./ -graphviz -createAssociations false -neato out.png

    This example will scan the current directory recursively for php files.
    Send them to the "dot" processor which will process them with the option
    "createAssociations" set to false. After that it will be send to the neato
    processor and saved to the file out.png

僕は毎度入力するのしんどいのでシンボリックリンク貼っときました。

sudo ln -si ~/.local/phuml/src/app/phuml /usr/local/bin

あとは解析したいディレクトリに移動してサンプルにもある用に

phuml -r ./ -graphviz -createAssociations false -neato out.png

を実行して上げればOKです。
試しにlaravelのエコシステムの一つpassportのsrcディレクトリ内で実行してみました。

passport_src.png

ちゃんと表示できました!

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

PHPのソースコードからクラス図を自動生成

PHUMLでPHPのクラス図を画像で作成する

PHPSTORMにはクラス図を作成してくれる機能がついているそうですがお家環境にはPHPSTORM入っていないのでクラス図を自動生成してくれるツールを探していてphumlというツールを発見しました。
環境はUbuntu18.04LTSです。

インストール

https://github.com/jakobwesthoff/phuml
からダウンロードして適当な場所に展開しましょう。
僕は~/.localにphumlとして展開しました。
これで実行できるようになりました。

$php ~/.local/phuml/src/app/phuml
phUML Version 0.2 (Jakob Westhoff <jakob@php.net>)
Usage: phuml [-h|-l] [OPTIONS] <DIRECTORY> <PROCESSOR> [PROCESSOR OPTIONS] ... <OUTFILE>

Commands:
    -h      Display this help text
    -l      List all available processors

Options: 
    -r      Scan given directorie recursively

Example:
    phuml -r ./ -graphviz -createAssociations false -neato out.png

    This example will scan the current directory recursively for php files.
    Send them to the "dot" processor which will process them with the option
    "createAssociations" set to false. After that it will be send to the neato
    processor and saved to the file out.png

僕は毎度入力するのしんどいのでシンボリックリンク貼っときました。

sudo ln -si ~/.local/phuml/src/app/phuml /usr/local/bin

あとは解析したいディレクトリに移動してサンプルにもある用に

phuml -r ./ -graphviz -createAssociations false -neato out.png

を実行して上げればOKです。
試しにlaravelのエコシステムの一つpassportのsrcディレクトリ内で実行してみました。

passport_src.png

ちゃんと表示できました!

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

【Laravel】バッチ処理、Cronのタスクスケジュール実行まで

今日も張り切って備忘録。
バッチの理解を深める為、簡単な処理を実装してみた。

環境

PHP 7.3.8
Laravel 6.18.35

バッチ処理を書く

Userテーブルに登録されているユーザー数を取得するバッチを作成する。
まずコマンドクラスを生成する。

php artisan make:command UserCount

コマンドを実行すると、ファイルがapp/Console/Commands/の直下に作成される。

UserCountCommand.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
//あとでログを出力する処理もいれるので
use Illuminate\Support\Facades\Log;
//操作するテーブルを読み込む
use App\User;

class UserCountCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */

    //コマンドの名前を設定
    protected $signature = 'user:count';

    /**
     * The console command description.
     *
     * @var string
     */
    //バッチの説明をここに書く
    protected $description = 'ユーザー数を取得';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
      //標準出力&ログに出力するメッセージのフォーマット
      $message = '[' . date('Y-m-d h:i:s') . ']UserCount:' . User::count();

      //INFOレベルでメッセージを出力
      $this->info( $message );
      //ログを書き出す処理はこちら
      Log::setDefaultDriver('batch');
      Log::info( $message );
    }
}

これでバッチが完成

ターミナルでコマンドを実行

php artisan user:count

こんな感じで表示されればOK
スクリーンショット 2020-09-07 21.52.22.png

バッチをCronで定時実行する

crontabにエントリーを記述する事で、エントリーの内容にそって定期的にバッチ処理を実行する事が出来ます。

参考:Laravelのタスクスケジュール(cron)を使いこなす

というわけで、crontabをvimコマンドで編集します。

$crontab -e

以下の1行を追加するだけでOK

* * * * * php /path_to_your_project/artisan schedule:run 1>> /dev/null 2>&1

$commands に作成したバッチコマンドを追加するのと、scheduleにバッチのスケジュールを記載する。

app/Console/Kernel.php
class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        \App\Console\Commands\UserCountCommand::class
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // user:countコマンドを毎分実行する
        $schedule->command('user:count')->everyMinute();
    }

ログファイルを見てみると

スクリーンショット 2020-09-07 22.07.56.png
ちゃんと1分おきに実行されていますね!

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

PHP_UMLの--helpをgoogle翻訳で翻訳

オブジェクト指向の勉強をしたくなりました。PHPを普段使っているのですが、ツールがあまり見つからずPHPSTORMなら自動生成してくれるみたいだけど、お家の環境にはないのでググったところPHP_UMLというツールを発見。
しかし使い方がわからない&英語わからないので翻訳することにしました。

↓もっと便利なツールを見つけて記事にしました。

クラス図を作成するもっと便利なツールみつけて記事にしました。
https://qiita.com/tdera/items/1a0dc91d37a89c22d4ba
コチラのほうが参考になるかもです。。


これを使って既存フレームワークの解析をしていきたいです。

PHP_UML

結構古いツールみたいです。。でもちゃんと動いてくれればOK。
https://pear.php.net/package/PHP_UML

-o directory

出力ディレクトリパス、またはファイル名(提供されない場合、XMIコードは画面に印刷)

-f format, --format=format

出力フォーマット: "xmi"(デフォルト)、「html」、「htmlnew」、「php」
html / htmlnew / phpの場合、必要に応じて独自のXMIファイルを提供し、次のように渡しますargument to phpuml

-x XMI version

生成するXMIバージョン(1または2)

-n name

生成されたUMLモデルの名前

-e encoding

出力文字エンコーディング

--no-deployment-view

配置ビューの生成を無効にする

--no-component-view

コンポーネントビューの生成を無効にする

--no-dollar

変数のドル記号を削除します

--no-docblocks

docblockの解析を無効にする(@package@param ...)

--show-internal

@internalでマークされた要素を含める

--only-api

@apiでマークされた要素のみを含める

-i pattern, --ignore=pattern

無視するパターン/パス名(example: .svn)

-m pattern, --match=pattern

一致するパターン (default is: *.php)

-l errorLevel, --error-level=errorLevel

エラー報告レベルを設定します(0サイレントモード、PHPエラーの場合は1、例外、すべてのエラーの場合は2、警告)

--pure-object

PHP_UMLが必要な場合は、このスイッチを使用します非オブジェクト指向のすべてを無視するコード

-h, --help

このヘルプメッセージを表示して終了

-v, --version

プログラムのバージョンを表示して終了する

引数

input
解析するPHPファイルまたはディレクトリ(例:D:/ htdocs /)スペースを使用して、さまざまなエントリを区切ります。デフォルトでは、PHP_UMLは現在のディレクトリを解析します。

例1 phpuml D:/htdocs/
PHP_UMLは、D:/ htdocs /を再帰的に解析し、XMIコードを表示します。

例2 phpuml /var/www/test -o /tmp -x 1 -n Foo -m *.php6 -i .svn
PHP_UMLは/ var / www / testを再帰的に解析し、php6のみを保持します
ファイル、およびsvnフォルダーを除外します。 UMLモデルの名前は「Foo」、およびバージョン1で生成されたXMIファイルは、次の場所に保存されます「/tmp/Foo.xmi」

...なんかちょっと変だな。

なんか画像にしてだしてくれるツール別に見つけたのでそっち使ってみます。
https://github.com/jakobwesthoff/phuml

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

セッションハイジャック対策

はじめに

最近、セキュリティの勉強をよくすることが多くなったのでそのことについて記事にして皆さんに分かりやすく教えることが出来たらと思い記事にさせて頂きます。今回は、セッションハイジャックについて説明させて頂きます。

目次

  1. セッションハイジャックとは
  2. セッションハイジャック種類
  3. セッションハイジャック対策
  4. さいごに

セッションハイジャックとは

まず、最初にWebはスタートレスに出来ているのでECサイトやログイン機能があるサイトでは、さっきこのサーバーに来た人物はAさんだと判断することが出来ません。そのために、考案されたのがセッションという機能です。(実際には、Cookieといった機能が最初に出来たのですが、セキュリティのことを考えてセッションが開発されました)AさんにはこのセッションID、BさんにはこのセッションIDと割り振ることで判断しています。

実際にPHPでセッションIDを見たい場合は、このように表示することで確認することが出来ます。

<?php

session_start();
echo session_id(); // セッションIDが表示される

?>

セッションハイジャックとは、このセッションの情報を第三者が乗っ取りその人物になりきりサイトにログインをすることを言います。

セッションハイジャックの種類

セッションハイジャックには主に3種類あります。

セッションの推測
セッションの盗聴
セッションID固定攻撃

まず、セッションの推測は第三者がセッションのIDを推測してユーザーが利用していたサイトにそのセッションIDを使用してアクセスすることを言います。

セッションの盗聴は、通信を傍受して盗むことです。また、XSSなどのサイバー攻撃を使用して第三者が作ったサイトに誘導してセッションIDを盗み出すことです。例えば、SNSのサイトでこのURLを押して下さいと第三者が作ったURLに誘導します。そのサイトにはXSSという脆弱性が仕込まれており知らないうちにそのSNSサイトのセッションIDが盗まれてしまうのです。

セッションID固定攻撃は、今までとは逆の発想です。第三者がユーザーに対してこのセッションIDを使用して下さいといったことを送りユーザーはそのセッションIDを使用してサイトにログインすると、第三者はそのセッションIDを使用してサイトにアクセスすることが出来るようになります。例えば、ユーザー宛にSNSのURLのパラメータとしてhttps://aaa@example.com?PHPSESSIONID=1111といったSNSのURLを送りユーザーがこのURLのリンクを開くとセッションIDがこの値になってしまいます。そして、このセッションIDを使用するといったことです。

セッションハイジャック対策

最初に、セッションIDをURLに含めないといったことがあります。
セッションをやり取るする時に、セッションIDをcookieに格納してやり取りする、hiddenに格納してやり取りする、URLに格納してやり取りするとあるのですが、最初の二つは利用していいのですがURLに格納してやり取りするのは、第三者に盗聴される可能性が高くなるります。

次に、セッションIDを推測されてしまう値に設定しないといったことがあります。Webアプリケーション開発ツールやフレームワークに実装されているセッション管理を利用するといいでしょう。

最後に、ログイン時に新しいセッションIDを生成するようにすることです。
PHPでそのやり方をするには、下記のやり方をします。

session_start();
echo session_id();
session_regenerate_id; // 新しい、セッションIDを生成する
echo session_id(); // 上のセッションIDとは違うIDが生成されます

さいごに

最近、よくプログラミングをする人が増えてきており沢山の人々が、サイトを作っていますがその際に速さを意識しすぎてセキュリティは後回しといった人が多い可能性があるので、セキュリティも気にしながらサイトを作ることを心がけましょう。

参考文献

セッションハイジャック- Wikipedia
セッションハイジャックとは?

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

Twitterでかっこよくソースコードを表示するCarbonを君は知っているか。

こんにちは、現在フリーのweb制作者として活動していますしょーごと申します。

さてみなさん、ソースコードのハイライトは見ていて気持ちが良いですよね。

VSCodeのコードハイライトだと、class名が緑色になるのが好きだったりします。

スクリーンショット 2020-09-07 20.47.45.jpg

これに慣れてしまうと、もう質素なメモ帳など使えなくなりますよね。

しかし、Twitterにはエディター機能はないので、ツイートしたくてもそのままソースコードを貼り付けると、すごく味気なくなります(文字数制限もきつい)

スクリーンショット 2020-09-07 20.51.48.jpg

私はTwitterを初めて8年、エンジニアを初めて2年立ちますが、2020年からイカしたサービスを活用しています。

コードハイライト大好き教のあなた、今日からCarbonを使うのです。

Carbonとは

Twitterできれいにソースコードを共有できるサービスです。

Carbon

スクショで貼るより綺麗です。

スクリーンショット 2020-09-07 20.10.48.jpg

様々な言語、テーマに対応しているのが写真でわかるかと思います。

上記の写真でのテーマはVSCodeですが、私はsetiというテーマが好きなので、setiで表示していきます。

Ruby

スクリーンショット 2020-09-07 20.16.29.jpg

JavaScript(Vue)

スクリーンショット 2020-09-07 20.19.38.jpg

Sass

スクリーンショット 2020-09-07 20.23.08.jpg

PHP

スクリーンショット 2020-09-07 20.40.51.jpg

簡単投稿、画像保存も可能

Twitterでサインインすればすぐツイートできますし、画像としてpngなどでエクスポートすることも可能です。

スクリーンショット 2020-09-07 20.34.36.jpg

投稿時にはCreated with @carbon_appは消しても問題ありません。
pic.twitter.com以下があれば問題ありません。

スクリーンショット 2020-09-07 20.23.34.jpg

スクリーンショット 2020-09-07 20.32.28.jpg

うーん、おしゃれ!!!

Twitterにソースコードを共有する心理としては、

「私のこのスマートなコードを見てくれ!これ便利でおすすめだぜ!!」

pose_makasenasai_boy.png

という心理かと思いますので(独断と偏見)

訴求力で見ても、とてもスマートなソースコードの共有方法だと思います。

Carbon

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

Laravelでuniqueの対象から自分自身の値を外す

問題

  • ユーザー情報の編集や更新をするフォームを作ってバリデーションを設けた
  • ユーザー名メールアドレスにuniqueを適用した
  • uniqueの対象以外の情報を変更したいのに、uniqueに引っかかってしまって、その先に進めない

この職種のDELETE_FLAGを変更したいのに、
image.png

uniqueが適用されている職種名のエラーが出てきてしまう。
image.png

コード

現在のコード、バリデーションはこのような状態

Works/EditCheckController.php
$validator = Validator::make($request->all(), [
    'edit_name' => 'required|max:20|unique:works,works_name',
    'edit_flag' => 'boolean',
],
[
    'edit_name.required' => '職種名を入力してください。',
    'edit_name.max' => '職種名は20字以内で入力してください。',
    'edit_name.unique' => 'この職種名は既に登録されています。',
    'edit_flag.boolean'  => '0か1を入力してください。',
]);

解決策

uniqueの引数を増やす

Works/EditCheckController.php
$validator = Validator::make($request->all(), [
    'edit_name' => 'required|max:20|unique:works,works_name,'.$request -> edit_id.',works_id',
    'edit_flag' => 'boolean',
],
[
    'edit_name.required' => '職種名を入力してください。',
    'edit_name.max' => '職種名は20字以内で入力してください。',
    'edit_name.unique' => 'この職種名は既に登録されています。',
    'edit_flag.boolean'  => '0か1を入力してください。',
]);

uniqueの内容は、
unique: uniqueチェックをしたいテーブル名, uniqueチェックをしたいカラム名,.uniqueチェックの対象外にしたいデータがあるレコードの主キー.',uniqueチェックの対象外にしたいデータがあるレコードの主キーのカラム名'
となっている。

処理の内容としては、

  • uniqueチェックをした時の主キー対象外にしたいデータがあるレコードの主キーが一致すれば、uniqueの結果を返さない
  • uniqueチェックをした時の主キー対象外にしたいデータがあるレコードの主キーが一致しなければ、uniqueの結果を返す

(であってるはず)

確認

uniqueの対象となっているWORKS_NAMEを変更せずに他のデータを編集できるようになり、
image.png

既に登録されているデータはuniqueの対象にすることができた。
image.png

参考文献

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

【PHP】unset、isset、header

PHPについて学習内容を備忘録としてまとめます。

unset

定義した変数の割り当てを削除する関数。不要になった配列を削除することも可能です。
例えば、配列で要素を削除したい場合にこのように記述します。

$ary = array(0,1,2,3,4); 
unset($array[3]);

上記のように定義すると4番目の要素『3』を削除することができます。

isset

引数に変数にすることができ、変数に値がセットされている場合にtrueを返します。
もし値がセットされていない場合にはfalseを返します。

たとえば下記のようなコードのような分岐処理を行うことができます。

if(isset(x)){
    xに値がセットされている場合
}
else
{
    xに値がセットされていない場合
}

セッションに値がポストした際に指定のパスに飛ばすなどの動作をすることも可能になります。

header

HTTPヘッダを送信する関数になります。
ある処理を終えた後に指定のパスに飛ばしたい時などに使用されます。

下記のように定義すると指定パスのファイルに飛ばすことができます。

<?php
  header('Location: ../index.php');
  exit;
?>

上記の例だと、header関数が動いた時点でindex.phpに飛ばしてくれます。
ファイル分岐などを行いたいときに活用することができます。

参考URL

https://techacademy.jp/magazine/11410
https://techacademy.jp/magazine/12288
https://techacademy.jp/magazine/11609

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

【Laravale】foreachで回したセレクトボックスの初期値を変数で設定する

概要

例えばキャラクターAの職業を変更したいと仮定する。編集ボタンを押すとキャラクターAの情報が表示され、職業はセレクトボックスで選択できる。セレクトボックスの中身は foreach を使って、コントローラから持ってきた職業一覧である $jobs の中身を表示するが、その初期値をキャラクターAの変更前の職業である 戦士 にしたい。

リレーション

  • charactersテーブルjobsテーブルがある。
  • charactersテーブルには jobs_id というインデックスがあり、リレーションを組んでいる。
  • jobsテーブルの name カラムには職業が入っている。魔術師とか竜騎士とか(まあなんでもいい)。セレクトボックスにはこの職業が羅列されることになる

セレクトボックス

基本として、これでセレクトボックスに『jobsテーブルに入っている職業』が羅列される。

edit.blade.php
<div class="">
  <select name="job_id">
    @foreach($jobs as $job)
      <option value="{{ $job->id }}">{{ $job->name }}</option>
    @endforeach
  </select>
</div>

デフォルト値の設定

コントローラからキャラクターの職業を持ってくる
(職業一覧、キャラクターの情報などを取得する部分、渡すべき変数でこの記事に関係ないものは省略する)。

CharacterController.php
$character_job = $character->job->character_name;

return view('character.edit')
  // 中略
  ->with('jobs', $jobs)
  ->with('character_job', $character_job);

あとはセレクトボックスの記述を修正する。

edit.blade.php
<div class="">
  <select name="job_id">
    @foreach($jobs as $job)
      @if ($job->name === $character_job)
        <option value="{{ $job->id }}" selected="selected">{{ $job->name }}</option>
      @else
        <option value="{{ $job->id }}">{{ $job->name }}</option>
      @endif
    @endforeach
  </select>
</div>

「セレクトボックスの職業とキャラクターの職業が一致する場合」selected する
(書いたはいいが記事に登場する職業の設定などはほとんど関係がなかった)。

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

【Laravel】foreachで回したセレクトボックスの初期値を変数で設定する

概要

例えばキャラクターAの職業を変更したいと仮定する。編集ボタンを押すとキャラクターAの情報が表示され、職業はセレクトボックスで選択できる。セレクトボックスの中身は foreach を使って、コントローラから持ってきた職業一覧である $jobs の中身を表示するが、その初期値をキャラクターAの変更前の職業である 戦士 にしたい。

リレーション

  • charactersテーブルjobsテーブルがある。
  • charactersテーブルには jobs_id というインデックスがあり、リレーションを組んでいる。
  • jobsテーブルの name カラムには職業が入っている。魔術師とか竜騎士とか(まあなんでもいい)。セレクトボックスにはこの職業が羅列されることになる

セレクトボックス

基本として、これでセレクトボックスに『jobsテーブルに入っている職業』が羅列される。

edit.blade.php
<div class="">
  <select name="job_id">
    @foreach($jobs as $job)
      <option value="{{ $job->id }}">{{ $job->name }}</option>
    @endforeach
  </select>
</div>

デフォルト値の設定

コントローラからキャラクターの職業を持ってくる
(職業一覧、キャラクターの情報などを取得する部分、渡すべき変数でこの記事に関係ないものは省略する)。

CharacterController.php
$character_job = $character->job->character_name;

return view('character.edit')
  // 中略
  ->with('jobs', $jobs)
  ->with('character_job', $character_job);

あとはセレクトボックスの記述を修正する。

edit.blade.php
<div class="">
  <select name="job_id">
    @foreach($jobs as $job)
      @if ($job->name === $character_job)
        <option value="{{ $job->id }}" selected="selected">{{ $job->name }}</option>
      @else
        <option value="{{ $job->id }}">{{ $job->name }}</option>
      @endif
    @endforeach
  </select>
</div>

「セレクトボックスの職業とキャラクターの職業が一致する場合」selected する
(書いたはいいが記事に登場する職業の設定などはほとんど関係がなかった)。

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

【PHP】シングルクォーテーションとダブルクォーテーションの違い

プログラミング勉強日記

2020年9月7日
シングルクォーテーションもダブルクォーテーションも同じ場面で使用するけど、実際にどんな違いがあるのかをまとめる。

特徴

 シングルクォーテーション:中身を文字列として扱う(変数や制御文字列もただの文字列として扱う)
 ダブルクォーテーション:中身を文字列として扱うが、変数や制御文字列はもともとの元として扱う
 
 シングルクォーテーションはすべて文字列として扱うので、シングルクォーテーションの方が速度が速い。

速度における違い

 以下のようにただの文字列を出力する場合は、出力される内容は同じ。

//ダブルクォーテーション
echo "Hello World";
echo '<br>';

//シングルクォーテーション
echo 'Hello World';
出力結果
Hello World
Hello World

 冒頭でも述べたが、動作処理速度は変数展開を用いる場合と変数の単純代入の場合、シングルクォーテーション>>ダブルクォーテーションである。(約1.2~2倍程度の差がある)
 しかし、文字列連結の場合と文字列比較の場合には速度の差はあまりない。

動作における違い

 冒頭に変数や制御文字列の扱いが異なると記述したが、具体例を用いて説明する。制御文字列は、改行(\n)や空文字(nil)といった文字以外の特別な制御を実行するために用いられる文字。
 以下の具体例のように、シングルクォーテーションの場合は、制御文字列や変数がそのまま文字列として出力されている。ダブルクォーテーションはそのまま変数の中身や制御文字列として出力されている。

$str = "World";

echo 'Hello $str';
echo "Hello $str";
echo "Hello {$str}";

echo 'Hello World\n';
echo "Hello World\n";
出力結果
Hello $str
Hello World
Hello World
Hello World\n
Hello World(表示上改行される)

まとめ

 システムとしてはわずかではあるが、シングルクォーテーションを使用した方が早くなる。(大規模なシステムの場合は大きい差になる)
 基本的にはシングルクォーテーションを使用して、必要な個所(変数展開など)のときにダブルクォーテーションを使うと良い。

参考文献

【PHP】’(シングルクォーテーション)と”(ダブルクォーテーション)はどちらを使うべきか(PHP高速化)
ダブルクォーテーション、シングルクォーテーションの違い

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

Try-Catch がうまく動いてくれなかった

Try-Catch がなぜかガン無視されると思ったら、Exceptionという単語のスペルを間違っていただけでした。

try_catch.php
try{

}catch(\Exception $e){//ここスペルミスしてました

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

【PHP】blastmail APIでメルマガ登録・解除をする

概要

blastmailを使ってメールマガジン登録・解除を実装する機会がありました。
そのときの手順やAPIの使い方についてメモです。

blustmailの準備

blastmailに会員登録すると、

  • 管理画面へのログイン情報
  • API key

が発行されます。

blastmailのAPIを利用するために、これらの情報を使うことになります。
API Keyは登録時のメールに記載されています。

また、管理画面の「契約情報>アカウント情報」の最下部でも確認できます。

APIの連携

APIを使ってメルマガ登録や解除などを行う手順としては、

  1. API経由でログインをし、アクセストークンを発行
  2. 発行されたアクセストークンをパラメーターに含めてAPIを叩く
  3. メルマガへの新規登録やユーザーの登録情報を確認などができる

といった感じです。

blastmailのAPIリファレンス

ログイン(アクセストークン発行)

詳しいパラメータはこちら

まずはblustmailにログインしてアクセストークンを発行します。
ログインはPOSTのみ有効となっており、今回はCurlを使いました。

login.php
$url = 'https://api.bme.jp/rest/1.0/authenticate/login';
$login_data = [
    'username' => 'ログインID',
    'password' => 'ログインパスワード',
    'api_key' => 'API Key',
    'f' => 'json' // responseをjson形式に指定
];

// curlの設定
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); // 取得するURLを指定
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); // POST送信
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 実行結果を文字列で返す
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data)); // POSTする値
$response = curl_exec($ch); // APIを叩く
$token = json_decode($response, true); // レスポンスをjsonから配列に変換

// ログイン失敗
if (!isset($token['accessToken'])) {
    echo 'ログインに失敗しました';
}

// レスポンス結果($token)
// {'accessToken':'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'}

ログインに成功すれば、accessTokenが返ってきます。

ログアウト(アクセストークンの破棄)

詳しいパラメータはこちら

ログアウトしてアクセストークンを破棄します。
ログアウトはGETが使えるので、file_get_contents()を使いました。

logout.php
$url = 'https://api.bme.jp/rest/1.0/authenticate/logout?';
$query = ['access_token' => $token['accessToken']];
$response = file_get_contents($url . http_build_query($query));

$responseには0(false)または1(true)が入ります。
ログアウトに成功すればtrueが返ってきます。

個別登録(新規登録)

メルマガの購読登録を新規で行う場合です。

項目設定

今回は、新規登録にあたって必要な情報は「メールアドレス」のみとしています。

「項目設定」から登録させる項目を決めることができます。
他にも氏名や電話番号などを登録することも可能です。

qiita_blast002.png

登録する項目のパラメーター名は以下で確認できます。
「テキストメール(メール新規作成)>差し込みコード」

メールアドレスの場合は「c15」になります。

qiita_blast003.png

実装

詳しいパラメータはこちら

Curlを使ってPOSTで登録データを送信します。

regist.php
// $token['accessToken']には、ログインで得た
// アクセストークンが代入されているものとします

$url = 'https://api.bme.jp/rest/1.0/contact/detail/create';
$regist_data = [
    'access_token' => $token['accessToken'],
    'c15' => '登録したいメールアドレス' // 登録したい項目のパラメータ
];

// curlの設定
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($regist_data));
$response= curl_exec($ch);

// 登録失敗
if (!(bool)$response) {
    echo '登録に失敗しました';
}

$responseには0(false)または1(true)が入ります。
登録に成功すればtrueが返ってきます。

管理画面の「読者一覧」に登録したユーザーが表示されれば成功です。
qiita_blast001.png

※ただし、以前に登録していて解除した場合などの、

  • 管理画面上にはないメールアドレス
  • 登録済みで配信停止中のメールアドレス

はデータベースに情報が残っているからか、新規登録ができませんでした。
そのため、次に説明する配信ステータスの変更を行う必要があります。

 
実装としては登録履歴があるかを調べ、

  1. 未登録なら新規登録
  2. 登録履歴があれば「配信中」にステータスを変更

のような形で新規登録を実装することになります。
最後にこれらをまとめたソースコードを記載します。

配信ステータス変更

登録の削除、配信停止などを行う場合はステータスの変更を行います。
変更するには登録者のIDが必要なので、まずはユーザーを検索してIDを取得します。

個別検索(ユーザー検索)

詳しいパラメータはこちら

メールアドレスまたはユーザーIDから、登録情報を検索します。

search.php
// $token['accessToken']には、ログインで得た
// アクセストークンが代入されているものとします

$url = 'https://api.bme.jp/rest/1.0/contact/detail/search?';
$query = [
    'access_token' => $token['accessToken'],
    'email' => 'メールアドレス',
    'f' => 'json'
];
$response = file_get_contents($url . http_build_query($query));
$user = json_decode($response, true);

// ユーザーID
echo $user['contactID'];

個別編集(ステータス変更)

詳しいパラメータはこちら

検索で取得したユーザーID(contactID)をもとに、ステータスを変更します。

change.php
// $token['accessToken']には、ログインで得た
// アクセストークンが代入されているものとします

// $user['contactID']には、検索で得た
// ユーザーIDが代入されているものとします

$url = 'https://api.bme.jp/rest/1.0/contact/detail/update';
$change_data = [
    'access_token' => $token['accessToken'],
    'contactID' => $user['contactID'],
    'status' => '配信停止' // 変更後のステータス
];

// curlの設定
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($change_data));
$response= curl_exec($ch);

// 変更失敗
if (!(bool)$response) {
    echo 'ステータスの変更に失敗しました';
}

$responseには0(false)または1(true)が入ります。
ログアウトに成功すればtrueが返ってきます。

登録までの流れをまとめ

メルマガ購読を登録するまでの流れをまとめます。
解除の場合もほぼ同じようなソースで実装ができます。

流れとしては

  1. blastmailにログインし、アクセストークンを取得
  2. 登録ユーザーのメールアドレスを検索
  3. 未登録であれば新規登録
  4. 登録済みであればステータスを「配信中」に変更する
  5. blastmailからログアウトし、アクセストークンを破棄

のようになっています。

mailmagazine.php
// blastmailログイン
$url = 'https://api.bme.jp/rest/1.0/authenticate/login';
$login_data = [
    'username' => 'ログインID',
    'password' => 'ログインパスワード',
    'api_key' => 'API Key',
    'f' => 'json' // responseをjson形式に指定
];

// curlの設定
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); // 取得するURLを指定
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); // POST送信
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 実行結果を文字列で返す
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data)); // POSTする値
$response = curl_exec($ch);
$token = json_decode($response, true); // レスポンスをjsonから配列に変換

if (!isset($token['accessToken'])) {
    // ログイン失敗エラー
}

// ユーザー検索
$url = 'https://api.bme.jp/rest/1.0/contact/detail/search?';
$query = [
    'access_token' => $token['accessToken'],
    'email' => '登録したいメールアドレス',
    'f' => 'json'
];
$response = file_get_contents($url . http_build_query($query));
$user = json_decode($response, true);

if (empty($user)) {
    // 未登録の場合は新規登録
    $url = 'https://api.bme.jp/rest/1.0/contact/detail/create';
    $regist_data = [
        'access_token' => $token['accessToken'],
        'c15' => '登録したいメールアドレス'
    ];
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($regist_data));
    $response= curl_exec($ch);
} else {
    // 過去に登録していた場合はステータス変更
    $url = 'https://api.bme.jp/rest/1.0/contact/detail/update';
    $regist_data = [
        'access_token' => $token['accessToken'],
        'contactID' => $user['contactID'],
        'status' => '配信中'
    ];
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($regist_data));
    $response= curl_exec($ch);
}
if (!(bool)$response) {
    // 登録失敗エラー
}

// ログアウト(アクセストークンの破棄)
$url = 'https://api.bme.jp/rest/1.0/authenticate/logout?';
$query = ['access_token' => $token['accessToken'],];
$response = file_get_contents($url . http_build_query($query));

メモ

ステータスを「削除」にすると管理画面からユーザーは削除されるが、論理削除のためおそらくデータベースには残っている。(そのため削除ユーザーも新規登録できないので、ステータス変更を行う必要がある)

 

以上です!

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

LaravelでS3アクセスが403 Forbiddenエラー

Laraelで以下のようなコードを書いた時に

Storage::disk('s3')->put('hoge.csv', 'あいう');
Error executing "PutObject" on "https://bucket-name.s3.ap-northeast-1.amazonaws.com/hoge.csv"; AWS HTTP error: Client error: `PUT https://bucket-name.s3.ap-northeast-1.amazonaws.com/hoge.csv` resulted in a `403 Forbidden` response: ...

といったエラーが表示された。
S3の権限設定はconfig/filesystems.phpで行うため該当ファイルを見ると、シークレットアクセスキーが間違っていることを確認。修正して再実行。しかしまったく同じエラーが出続けます。
バケットポリシーやIAMの設定を見直しても問題なく、aws cliからPutObjectを試してみるとうまくいくため権限は設定できているようだった。

キャッシュが原因

原因はLaravelのキャッシュ設定で

php artisan cache:clear
php artisan config:clear
php artisan config:cache

上記コマンド実行でLaraelのキャッシュをクリアしたところ問題なくPutObjectができるようになった(おそらくどれか一つのコマンドでいいと思うが未検証)。最初に間違ってシークレットアクセスキーを設定してしまったものをキャッシュしてしまい、永遠にエラーが吐かれていたようだった。

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

【エラー無し】phpMyAdmin ログイン画面が表示されない件 解決

特にエラーが出ている訳ではないのですが、学習中に某記事に沿って進めていると沼にハマりました。

【問題】
phpMyAdminのログイン画面が表示されない

【解決方法】

❶phpMyAdminをダウンロード(HP右側にあるDownload):raised_hand:
https://www.phpmyadmin.net/
スクリーンショット 2020-09-07 14.12.41.png

❷phpMyAdminダウンロードファイルをMAMP内>htdocsファイルに移動:raised_hand:
スクリーンショット 2020-09-07 14.14.48.png

❸Chromeで localhost で検索:raised_hand:
スクリーンショット 2020-09-07 14.16.33.png

❹以下画像のページが表示されるのでphpMyAdminファイルをクリック:raised_hand:
※under_phpは私のMAMP>htdocsファイルに入っている当記事とは関係ないファイルです。

補足:phpMyAdminからダウンロードしたファイル名を短くするため[phpmyadmin]と変更しているだけです。

スクリーンショット 2020-09-07 14.17.35.png

以上4点でたどり着きたかったphpMyAdminページが開きました!

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

LaravelでClass 'Hoge\FooClass' not found

Laravelに限りませんが、Composerを利用していてClass not foundエラーに遭遇することがあります。
まず対応することは

composer dump-autoload

のコマンドを打ってautoloadさせます。

それでもなお

Class 'Hoge\FooClass' not found

が継続する場合は
vendor/composer/autoload_classmap.php ファイルを参照して、上記エラーならFooClassが存在するか確認します。
おそらく存在しないと考えられます。今回は新規追加したディレクトリを読み込めていないことが原因でした。

その場合はcomposer.jsonを確認をすると

composer.json
"autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },

の記述のclassmapに新規追加したディレクトリHogeが存在しないことがわかります。

composer.json
"autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories",
            "app/Hoge"  ←追加行
        ]
    },

これで再度composer dump-autoloadでファイルが読み込まれました。

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

Laravel https環境下でCSSが反映されない

目的

  • Laravelでオリジナルのcssファイルを作成しビューファイルに反映しようとしても一切されない問題を解決した話をまとめる

原因

  • Laravelアプリが可動しているWebサーバがHTTPS化されていたためcssファイルの読み込み方法が異なるため読み込まれなかった。

原因と解決方法

  • 下記の様にasset()で記載するとhttps環境下だとCSSファイルを読み込むことができない。

    <link rel="stylesheet" href="{{ asset('アプリ名ディレクトリ/publicディレクトリからCSSファイルまでのパス') }}">
    
  • 下記の様にsecure_asset()を用いることによりhttps環境下でもセキュアを保ったままCSSを読み込むことができる。

    <link rel="stylesheet" href="{{ secure_asset('アプリ名ディレクトリ/publicディレクトリからCSSファイルまでのパス') }}">
    <!-- 少しだけ具体的に記載する -->
    <link rel="stylesheet" href="{{ secure_asset('/css/CSSファイル名') }}">
    

参考文献

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

Laravel5.5でメール送信ができないよ?

さくらインターネットのレンタルサーバーで、稼働中の Laravel5.5 で作成したサービスが特定のページで突如エラー。
エラーログをたどっていくと、どうやらメール関連でエラーが...

Trying to access array offset on value of type null in /project/vendor/egulias/email-validator/EmailValidator/Parser/Parser.php

だがどうして突然・・・気づいたらレンタルサーバーのPHPが7.4に上がってた。
これが原因か。
じゃぁPHPを7.3固定で!

egulias/email-validator のバージョンが 2.1.3 だったが composer update で 2.1.20 になった事で
解決できた。

こんな状況に遭遇する人少なそうだけど...

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