- 投稿日:2020-09-11T23:39:38+09:00
PHP 、Laravel学習 1
これから学習したことをQiitaに投稿していきます。
非常に中途半端なところからのスタートになりますがご容赦下さい。
●Laravel学習
・MVCモデル
①ブラウザから送られてきた指令(リクエスト)をまずroutingが受け取る
②routingがどこにその指令を飛ばすべきかリクエストの種類を判別する
③controllerで受けとった場合、然るべきアクションを行う
④viewで受けとった場合そのままviewを返す(レスポンス)
⑤ブラウザに反映される※多様なパターンがあり、一概に↑の順とは限らない
routing・・・リクエストを判別し、然るべき場所に信号を送る
controller・・・routingから送られてきたリクエストに大して然るべきアクションをする
view・・・表示するべきUI部分。
Model・・・データベースの前に立ち、操作しやすくするもの(?)Model、view、controller
3つの要素の頭文字をとってMVCモデル・データベース基礎
情報を保存しておくところ
Ex.ユーザーの名前、年齢、性別等まず、データベースを操作する言語(データベース言語)について触れておきます
SQLといい、何種類かある
①MySQL
②PostgreSQL
③SQLite
存在するデータベースにより、どの言語が使われているかは異なるが
LaravelのModelはそれを全て統一して管理してくれるという便利機能付きこの言語を使い、データベースの雛形を作ったり、データを入力したりする
・CRUD処理
①Create・・・作成(タスクを作成したり、ツイートを作成したり)
②Read・・・読み込み(作成したタスクを読み込んだり、ツイートを読み込んだり)
③Update・・・更新(タスクを編集したり、追加する)
④Delete・・・削除(一度作ったデータを削除する)WebアプリケーションではこのCRUD処理が必要不可欠である。
次回は実際に作りながら学んでいきたい
- 投稿日:2020-09-11T21:32:32+09:00
さくらVPSサーバーで作成したWebサービスのSSL化を行うに辺り、詰まった点
前提条件として
さくらVPSで環境構築が完了して、自分で作成したWebサービスの独自ドメインを取得しており
ドキュメントルートを設定して、ドメイン名(○○.com等)でhttp接続が完了しているという条件で
記述していきます。作業環境
CentOS7
Apache2.4.6Let's encryptで無料SSL証明書発行してSSL化
今回は無料でSSL証明書を発行したかったのでLet's encryptを使用しました。
詰まった箇所
https://weblabo.oscasierra.net/letsencrypt-2/
コチラの参考記事の内容を完璧に行ってもhttp接続からhttps接続に切り替わらない。
対策
参考記事に書かれている
Apache 2.4 への設定が上手く反映されていない可能性を考える。$apachectl configtest←このコマンドでssl.confの構文チェックを行う。
すると下記エラーメッセージが出る。
Syntax error on line XX of /path/to/ssl.conf:
SSLCertificateFile: file '/path/to/cert.pem' does not exist or is empty上記エラーメッセージで検索しまくると
コチラの記事に巡り合えた。パーミッションの設定を変更してみると
$ apachectl configtest
Syntax OKApache 2.4 への設定は上手くいったことを確認して再度ブラウザを確認すると今度は接続タイムアウトのエラーが。。
色々調べているとファイアウォールかApacheのエラーが原因ぽかったので
ファイヤーウォールの確認
$ firewall-cmd --list-all --permanent
apacheの確認
$ systemctl status httpd上記コマンドを叩いてみるとファイアウォールの方は問題なさそうなのですが
apacheの方は長文の英文メッセージの中にfailedという文字が。。はい、アパッチが原因ですね。
アパッチのエラーログを確認するとssl.conf内のポート番号443が重複しているというようなエラーメッセージが出力されている。
glepコマンドで443で検索をかけると、バックアップ用にコピーしていた
ssl.old.conf
ssl.oldest.conf上記ファイルが本丸のssl.confと競合していた。。
なのでこれらのファイルを削除して再度アパッチを起動してブラウザを確認すると
接続タイムアウトのエラーが解決されて、https接続もしっかり出来ていました。
バックアップファイルの取り方に問題があったようでOSは拡張子で判断するのでバックアップファイルを取るなら下記のようにするのが正解のようです。
ssl.conf.bak
ssl.conf.old拡張子は完全に盲点でした。。
今回のような訳の分からないエラーが出た時は、今思うと当たり前ですがエラーログをしっかり見てから、解決に向けて行動をした方が良いですね。ていうかプログラミングでエラーにぶつかった時は基本的にエラーログを見るのは当たり前なのですが、環境構築に対する知識が乏しく、アパッチにエラーログがあるという概念すらなかったです。
とはいえ、今回のエラーで環境構築やネットワーク関連の知識がある程度付いたのでエラーに巡り合えて良かったと
ポジティブな結果として終わらそうと思います笑長文失礼致しました!
- 投稿日:2020-09-11T18:41:18+09:00
LaravelでSwift_TransportExceptionが発生した時の対処法(Gmail編)
問題
Laravel
でメール送信しようとしたらSwift_TransportException
というエラーが発生した。Authenticator LOGIN returned Expected response code 235 but got code "534"
が発生した。自分は上記の両方を認証機能のパスワード再発行の際に発生した。
それらを解決できたので、その方法を記載する。解決策
今回は
Gmail
を利用した解決策を書いていく。.env
まずは
env
ファイルの設定を確かめる。MAIL_DRIVER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=465 MAIL_ENCRYPTION=ssl MAIL_FROM_ADDRESS=laravel@admin.com(適当なメールアドレス) MAIL_FROM_NAME=Admin(適当な名前) MAIL_USERNAME=(自分が利用しているGmailアドレス) MAIL_PASSWORD= MAIL_PRETEND=false
MAIL_PASSWORD
の所に何も記入されていないが後で記入する。config/mail.php
config/mail.php
を次のように書き換える。
既に記入されていたコードはコメントアウトなどで保存。config/mail.php// Mail Driver 'driver' => env('MAIL_DRIVER', 'smtp'), // SMTP Host Address 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), // SMTP Host Port 'port' => env('MAIL_PORT', 587), // Global "From" Address 'from' => [ 'address' => env('MAIL_FROM_ADDRESS', null), 'name' => env('MAIL_FROM_NAME', null) ], // E-Mail Encryption Protocol 'encryption' => env('MAIL_ENCRYPTION', null), // SMTP Server Username 'username' => env('MAIL_USERNAME', null), // SMTP Server Password 'password' => env('MAIL_PASSWORD', null), // Sendmail System Path 'sendmail' => '/usr/sbin/sendmail -bs', // Mail "Pretend" 'pretend' => env('MAIL_PRETEND', false),Googleのセキュリティ設定
下記のサイトを参考に
【laravel】メール(gmail)がエラーで送信出来ない問題 | 旅行好き・WEBエンジニアのブログ自分は2段階認証ではエラーが解消しなかったが、アプリパスワードの設定によって解消できた。
アプリパスワードが発行されたら、
.env
のMAIL_PASSWORD=
に入力する。キャッシュの削除
今のままだと
Laravel
の変更前の設定ファイルの記録などが残っているため、$ php artisan config:cache
をターミナルで実行しそれらを削除する。以上の作業が終わったら、自分が操作したいメール送信機能を試してみる。
参考資料
- 投稿日:2020-09-11T17:23:24+09:00
Laravelの配列操作ラッパー、Collectionを単品で使用してみる
概要
Laravelのcollectionが便利なので単品で使いたい
コレクション -Laravelドキュメントinstall
% composer require illuminate/supportcode
sample.php
<?php require_once "vendor/autoload.php"; $array = ['key' => 'value']; $collection = collect($array); var_dump($collection);結果
% php sample.php object(Illuminate\Support\Collection)#3 (1) { ["items":protected]=> array(1) { ["key"]=> string(5) "value" } }できた!
参考
おまけ
docker-compose.yml
version: '3' services: php: container_name: php-collection build: context: . dockerfile: docker/php/Dockerfile volumes: - ./php:/var/www tty: true working_dir: /var/www env_file: - ./.envDockerfile
FROM php:7.4 COPY --from=composer:latest /usr/bin/composer /usr/bin/composer RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \ && apt-get update \ && apt-get install -y zip unzipbuild & 起動 & 実行
docker-compose build php docker-compose up -d docker exec -it php-collection /bin/bash composer require illuminate/support vi ./sample.php php ./sample.php
- 投稿日:2020-09-11T17:08:59+09:00
【PHP】TrueとFalseを出力する
やりたいこと
trueはtrue、falseはfalseと出力したい。
うまくいかなかった方法
配列をtrueとfalseで初期化し、値を出力した。
$tf = array(true,false,true,false); for($i = 0;$i < 4;$i++){ print $tf[$i]."<br>"; }結果
trueは1、falseは""と出力される
1 1うまくいった方法
出力の際にvar_exportを使った。
$tf = array(true,false,true,false); for($i = 0;$i < 4;$i++){ print var_export($tf[$i])."<br>"; }結果
trueはtrue、falseはfalseと出力される。
true false true falseまとめ
PHPはtrueとfalseがそのまま出力されないため、var_exportが必要。
- 投稿日:2020-09-11T14:13:11+09:00
Adminerでoracleに繋げる
Adminerとは
AdminerはPHPで動作するWebSQLクライアントです。
https://www.adminer.org/同じ物に言わずとしれたphpMyAdminですが使えるのはMysqlだけ。
一方AdminerではmysqlのほかにPostgreSQL、SQLite、MS SQL、Oracleなど幅広く扱えます。oracle
本題です。
そんななかoracleに繋げる時だけログインフォームに癖がありこれが毎度忘れるので記事にします。これはDockerでoracleDBをインストールした場合のデフォ情報の場合です。
Serverにはホスト名(TNS名)/サービス名の両方を/で仕切り、入力する必要があります。
User名はログインユーザ
Databaseはスキーマ名となります。大文字小文字が区別されるので注意です。
- 投稿日:2020-09-11T13:18:05+09:00
PHP(Imagick)でイメージをマスクして切り取る
完成形
画像の左右を斜めに切り取っています。
やりたいこととしては、上記の画像の赤枠で囲っている、2つの画像を合わせてその合わさっている場所を切り抜きたい。
元画像とマスク用画像の用意
マスク用の画像(同じサイズで左右の斜めを透過してあります。)
実装
//元画像をURLから呼び出し $thumbnail = file_get_contents("http://ddragon.leagueoflegends.com/cdn/img/champion/loading/Zoe_0.jpg"); $image = new Imagick(); $image->readImageBlob($thumbnail); //アルファチャネルの設定で、黒い部分を透明にする。 $image->setImageAlphaChannel(Imagick::ALPHACHANNEL_RESET); //マスク用の画像を取得 $mask = new Imagick(storage_path("mask.png")); //元画像を重ね合わせてマスクする //COMPOSITE_DSTOUTにすると、重なっている部分が切り抜かれる $image->compositeImage($mask, Imagick::COMPOSITE_DSTIN, 0, 0); //保存 $image->writeImage(storage_path("test.png"));以上で簡単な実装です。
さらにこれに画像を重ね合わせたり、文字を入れたりするとOGP的な画像の動的生成などができるかと思います。
- 投稿日:2020-09-11T11:31:43+09:00
IBM i oci8.so でセグメンテーション障害(core dumped)
IBMiとOracleで嵌り事象に遭遇したので、備忘録として。
突然のセグメンテーション障害(core dumped)
IBMi 環境下のPHP
oci8.so
を使用して、ユーザーのPHPアプリケーションテストをしたところ、ある日突然なんのエラーメッセージも出力されず「セグメンテーション障害(core dumped)」となり、PHPアプリケーションが落ちてしまう様になった。エラー時に出力された、スプールは以下の通り。MCH6801 エスケープ 40 20/09/07 20:04:46.275123 QP2USER2 QSYS *STMT QP2USER2 QSYS *STMT 送信元モジュール. . . . . : QP2API 送信元プロシージャー. . . : runpase_common__FiPvT2 ステートメント. . . . . . : 5 送信先モジュール. . . . . : QP2API 送信先プロシージャー. . . : runpase_common__FiPvT2 ステートメント. . . . . . : 5 メッセージ. . : オブジェクトQPADEV0001USHIDAY 505789のオフセット X'0000000000000018'のオブジェクト・ドメインまたは記憶域保護エラー。 原因--プログラムは,ブロック化された命令を使用しようとしたか,システム・ド メイン・オブジェクトをアクセスしようとしたか,あるいは保護されたページを間 違って使用しようとしました。違反タイプは4です。違反タイプは以下のタイプ のエラーを示します。1-オブジェクト・ドメイン違反。2-テスト・ポインター ・ターゲット・アドレス可能度(TESTPTA)違反。3-読み取り保護エラー。 4-書き込み保護エラー。5-実行保護エラー。空間クラスはX'08'です。空間 クラスは,記憶域保護エラーまたは空間ポインターのTESTPTA違反の空間のタイ プを示します。00- 1次関連空間(空間オブジェクトを含む)。01- 2次関連空 間。02-自動記憶域用の暗黙の処理空間。03-静的記憶域用の暗黙的処理空間。 04-活動化グループに基づくヒープ記憶域の暗黙の処理空間。05-定数空間。 06-ハンドルに基づくヒープ記憶域用の空間。07-テラスペース・オフセット X'0000000000000018'。08- I5/OS PASEメモリー・アドレス X'0000000000000018'のテラスペース。X'80000000000000000000040050000018'は ,保護エラーまたは空間ポインターのTESTPTA違反の記憶域へのポインターです 。一部の違反は,低システム機密保護レベルで抑制されている場合があります。 CPFB9C6 エスケープ 40 20/09/07 20:04:46.438840 QP2FORK QSYS *STMT QP0ZPCPN QSYS *STMT 送信元モジュール. . . . . : QP2FORK 送信元プロシージャー. . . : send_escape__FPcPvUi ステートメント. . . . . . : 11 送信先モジュール. . . . . : QP0ZPCPN 送信先プロシージャー. . . : Qp0zNewProcess ステートメント. . . . . . : 278 メッセージ. . : PASE FOR Iが終了しました。シグナル11,エラー・コード 5770SS1 V7R2M0 140418 ジョブ・ログ CSC2015 20/09/07 20:04:46 JST ページ 2 ジョブ名 . . . . . . . . . : QPADEV0001 ユーザー. . . . : USHIDAY 番号 . . . . . . . . . . . : 505789 ジョブ記述 . . . . . . . . : USHIDAYJD ライブラリー. . : USHIDA MSGID タイプ SEV 日付 時刻 FROM PGM ライブラリー INST TO PGM LIBRARY INST 1。 原因--PASE FOR Iプログラムは,PASE FOR Iシグナル11のため終了しました 。エラー・コード1は,現行ディレクトリーにコア・ファイルが書き込まれたこ とを示しています。このシグナルは,ジョブ・ログに表示される例外メッセージに 対して作成されている可能性があります。回復手順--エラーを訂正して,要求 を再試行してください。エラーの詳細説明--コア・ファイルが書き込まれてい る場合には,PASE FOR I 'DBX'コマンドでそれを調べてください。PASE FOR Iコマンドは,対話式ジョブでプログラムQP2TERMを呼び出すことにより表示され るコマンド行で入力できます。 CPF24A3 エスケープ 40 20/09/07 20:04:46.439263 QMHSNDPM QSYS 0C79 QLEAWI QSYS *STMT 送信先モジュール. . . . . : QLEDEH 送信先プロシージャー. . . : Q LE leDefaultEh2 ステートメント. . . . . . : 175 メッセージ. . : 呼び出しスタックのカウンター・パラメーターの値が正しくな い。 原因--呼び出しスタックのカウンター・パラメーターに指定した値3が正しくあ りません。この値はAPIのパラメーター番号7に指定されました。回復手順- -呼び出しスタックのカウンター・パラメーターの値を訂正して要求を再試行して ください。この値は0以上でなければなりませんが,呼び出しスタックの項目数 より大きくすることはできません。 CEE9901 診断 30 20/09/07 20:04:46.439299 QLEAWI QSYS *STMT QP0ZPCP2 QSYS *STMT 送信元モジュール. . . . . : QLETOOL 送信元プロシージャー. . . : Q LE CPF24A3_handler ステートメント. . . . . . : 9 送信先モジュール. . . . . : QP0ZPCP2 送信先プロシージャー. . . : _CXX_PEP__Fv ステートメント. . . . . . : *N メッセージ. . : アプリケーション・エラー。CPFB9C6は,QP0ZPCPNによっ てステートメント0000000278命令X'0000'で監視されていません。 原因--例外が発生して処理されなかったので,アプリケーションは異常終了しまし た。未処理例外が送られるプログラムの名前はQP0ZPCPN QP0ZPCPN Qp0zNewProcessです。プログラムは,このメッセージが送られた時に高水準言語ス テートメント番号0000000278で停止されました。複数のステートメント番号が表 示された場合には,プログラムは最適化されたILEプログラムです。最適化によ って単一ステートメント番号を判別することはできません。*Nが値として表示さ れた場合には,実際の値が使用できなかったことを意味します。回復手順--前 にリストされた低レベル・メッセージを参照して,例外の原因を突き止めてくださ い。エラーを訂正してから,要求を再試行してください。 CPC1219 完了 50 20/09/07 20:04:46.439427 QWTPITP2 QSYS 0645 *EXT *N メッセージ. . : このジョブは異常終了した。 原因--このジョブが異常終了する原因となるエラーが起こりました。回復手順- -このジョブのジョブ・ログで,以前にリストされているメッセージを参照してく ださい。エラーを訂正して,要求を再試行してください。結果的には、以前ユーザーは、
Oracle 11g
を使用していたのだが、今回から12c
に変更されており、12c
はユーザーに紐付く省略のDefaultプロファイル
のパスワード期限が、180日だった事が原因でした。事象のまとめ
今回の事象をまとめると以下の通り。
- PHP on IBMi アプリケーションで、Oracle DBに接続。
- 接続時には、
セグメンテーション障害(core dumped)
となり、実行カレントディレクトリにcore
のメモリダンプが吐き出されて異常終了となる。- Zend Server,コミュニティ版PHPどちらでも同様の現象となる。
- 開発用Windowsで同様の処理をしても、正常に処理される。
- IBMiからJava(JDBC)経由のアプリケーションでは、正常に処理される。
- 旧Oracle 11gに接続先を向けると、正常に処理される。(この辺りで、ようやく12c固有の問題と判断が付きました)
- IBMi上のSQLPlusでは、正常にログイン出来る。(ムムッ、なにやら不穏なワーニング
ORA-28002: the password will expire within 7 days
が...)./sqlplus user/pwd@hostname:1521/database SQL*Plus: Release 10.2.0.5.0 - Production on Mon Sep 7 21:49:09 2020 Copyright (c) 1982, 2010, Oracle. All Rights Reserved. ERROR: ORA-28002: the password will expire within 7 daysどうも原因は、これのようで、IBMiの
oci8.so
またはOracle Instant Client
の何れかが、このワーニングをハンドリング出来ていないのかな?通常なら、7日間の猶予があるようで、それでlocalやJavaは問題が表面化せず動作しているのかもしれません。解決方法
デフォルトプロファイルのパスワード期限を無期限にするか、対象のプロファイルのパスワードを無期限にします。本来は、デフォルト変えてまうより、アプリケーション接続ユーザー様のプロファイルにするべきでしょうね。
- プロファイルの期限を設定
- アカウントロックを解除/パスワード再設定
# SQLplusで接続する ./sqlplus user/pwd@hostname:1521/database # 無期限設定 alter profile DEFAULT limit PASSWORD_LIFE_TIME unlimited; alter profile プロファイル名 limit PASSWORD_LIFE_TIME unlimited; # 設定確認 SELECT * FROM dba_profiles WHERE PROFILE='DEFAULT' AND RESOURCE_NAME='PASSWORD_LIFE_TIME'; ROFILE -------------------------------------------------------------------------------- RESOURCE_NAME RESOURCE -------------------------------- -------- LIMIT -------------------------------------------------------------------------------- COM INH IMP --- --- --- DEFAULT PASSWORD_LIFE_TIME PASSWORD UNLIMITED NO NO NOOracleのプロではないので、バージョン変わる時に流儀が変わっていると、嵌ることがよくあります。
因みに、明示的にユーザーをロックしたり、パスワードをExpireさせた時は、oci8.soから「~Loked~」など、メッセージが返され、Coredumped で落ちる事はないので、自然と180日で切れて、猶予期間が存在する時だけ起こる事象かもしれません。
- 投稿日:2020-09-11T08:04:14+09:00
sprintf()でSQL文を生成する際、%は%でエスケープできる
何を言っているのかわからねーと思うが、ありのままを話すぜ2020/09/12 追記
コメントにてSQLインジェクションの原因となる脆弱性をご指摘いただきました。
本記事はsprinf()でSQLクエリを作成する事を推奨するものではないとご理解をお願いします。
@tadsan様 ありがとうございます。はじめに
現在私はPHP+MySQLでフルスクラッチ開発をしている会社で働いているのですが、
まだ、入社して1ヶ月ほどなので既存のコードを読むことがほとんどです。
弊社ではphpファイルの中でSQL文を生成する際に
sprintf()を使用して、フォーマットを整えるようにしています。
(これがスタンダードなのかは不明)その中で、いまいちよくわからない記述を調べていくうちに
興味深いルールに出会いましたので、忘れないようQiita残しておきます。sprintf()でSQLの曖昧検索クエリを作る時
$freeword = 'qiita'; $sql = sprintf('SELECT * FROM title LIKE "%%%s%%"', $freeword);このコードはsprintf()の第二引数 $freeword が、第一引数内の "%%%s%%" の部分に
置き換わってフォーマットされるのですがその際に気をつけたいルールがあります。まず真ん中部分の「%s」は変数の値で今回の例ではqiitaに変換されます。
なので、この時点では「%%qiita%%」になる。この段階で、筆者は
「無駄に%の数多くね?」
と、勘違いしていましたがそもそもsprintf()で%という記号はそのまま文字として認識されないので
エスケープして文字とする必要があります。そこで%をエスケープするための記号が%なのです。
つまりは
残った「%」のうち、後ろの%は、それぞれ手前の 「%」でエスケープされるので、結果としてただの「%」と言う「文字列」になります。
① %→「%」qiita %→「%」
② 結果「%qiita%」が残る
③ これがSQLのLIKE文に残ることで、結果として、
$sql = 'SELECT * FROM title LIKE %qiita%';
と言うSQL文の完成。わかりやすい参考記事
下記ブログ記事の解説が初心者にも大変わかりやすかったので
記事作成の大部分に引用させていただきました。ありがとうございます。