tag:blogger.com,1999:blog-5121662396666783812024-03-07T12:35:52.963+09:00プログラムしたいねん!ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.comBlogger381125tag:blogger.com,1999:blog-512166239666678381.post-29362707782880859022023-10-05T19:00:00.009+09:002023-10-05T19:00:00.152+09:00MySQL 8でAES暗号モードをaes-256-ofbに変更する方法
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSmRXDgfr9Lkrk46kkFeueoXmnGwej6i0-Mx9SZGdFzvV7FbMwVBq9HPoIIoABO6UWL6Z57Zr9JVL-bEa4mz61UGKrSi0Gp33J1GT31PPMNaauFFOllWCZebwxm_MfH7leB_Fzx7mNeO9mpUXJJ9YAYQRq4rKpwIpWtF4cDy-JJGmGD_rDYoIr4Xyw7qtE/s892/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202023-10-05%20105502.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="283" data-original-width="892" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSmRXDgfr9Lkrk46kkFeueoXmnGwej6i0-Mx9SZGdFzvV7FbMwVBq9HPoIIoABO6UWL6Z57Zr9JVL-bEa4mz61UGKrSi0Gp33J1GT31PPMNaauFFOllWCZebwxm_MfH7leB_Fzx7mNeO9mpUXJJ9YAYQRq4rKpwIpWtF4cDy-JJGmGD_rDYoIr4Xyw7qtE/w640-h204/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202023-10-05%20105502.png" width="640" /></a></div><br /><h2 style="text-align: left;">現在の設定を確認する方法</h2>
<p>MySQLでAES暗号モードの設定を確認するには、以下のクエリを使用します。</p>
<pre class="sql" name="code"> SHOW VARIABLES LIKE 'block%';
SHOW GLOBAL VARIABLES LIKE 'block%';</pre><pre>上記はそれぞれ結果が異なる場合がありますので、両方を確認する事をおすすめします。
</pre>
<h2>AES暗号モードを変更する方法</h2>
<h3>方法 1: セッション内でのみ変更する</h3>
<p>次のコマンドを使用して、現在のセッション内でのみAES暗号モードを変更できます。変更はセッション終了時にリセットされます。</p>
<pre class="sql" name="code"> SET block_encryption_mode = 'aes-256-ofb';
</pre>
<h3>方法 2: グローバルな設定を変更する</h3>
<p>次のコマンドを使用して、グローバルなMySQLサーバー設定を変更し、すべての接続に影響を与えます。ただし、この変更はMySQLサーバーを再起動するまで永続的に反映されません。</p>
<pre class="sql" name="code"> SET @@GLOBAL.block_encryption_mode = 'aes-256-ofb';
</pre>
<h3>方法 3: 永続的な設定を変更する</h3>
<p>次のコマンドを使用して、MySQLサーバーの永続設定を変更し、再起動しても設定が保持されます。</p>
<pre class="sql" name="code"> SET PERSIST block_encryption_mode = 'aes-256-ofb';
</pre>
<p>注意: グローバルな設定および永続的な設定を変更する場合は、セキュリティとパフォーマンスへの影響を検討し、必要な対策を講じることが重要です。また、変更を行う前にデータベースのバックアップを取得し、変更後にテストを行うことをお勧めします。</p>
ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-12877669612752330602023-09-06T19:00:00.031+09:002023-09-06T19:00:00.138+09:00CakePHP4 DBの複数レコード情報を一気に取得するとメモリーが足りないのでに少しずつ取得する<p>今回はCSV出力する際にレコード数が多くてメモリー不足にならない方法を考えていました。</p><p>CakePHP 4では、`<b>enableBufferedResults</b>`を利用してメモリー不足を発生させないようにすることができます。この設定は、データベースから大量のデータを取得する場合など、メモリーを効率的に管理するために役立ちます。</p><p>まずは公式ドキュメントの紹介<br /><a href="https://book.cakephp.org/4/ja/orm/retrieving-data-and-resultsets.html#id16">https://book.cakephp.org/4/ja/orm/retrieving-data-and-resultsets.html#id16</a></p><p>`<b>enableBufferedResults</b>`を有効にすると、CakePHPはデータベースのクエリ結果をメモリーに全て読み込むのではなく、イテレータを使用してデータを一部ずつ取得できるようになります。これにより、大規模なデータセットを取り扱う場合でもメモリー不足の問題を回避できます。</p><p>以下は、CakePHP 4で`<b>enableBufferedResults</b>`を設定する方法です。</p><p>1. コントローラーまたはモデルのアクション内で、`<b>enableBufferedResults</b>`を有効にします。たとえば、以下のように設定できます。</p>
<pre class="php" name="code">// コントローラーのアクション内で
public function getData() {
// データベースから大量のデータを取得するクエリ
$query = $this->Table->find()->enableBufferedResults();
// データを取得
foreach ($query as $row) {
// データの処理
}
}
</pre>
<p>2. 上記の例では、`<b>enableBufferedResults</b>`をクエリオブジェクトに適用し、`foreach`ループを使用してデータを一つずつ処理しています。この方法を使用することで、メモリー不足を回避できます。</p><h4 style="text-align: left;">注意事項:</h4><p>- `<b>enableBufferedResults</b>`を有効にしてループしてる時などは別のクエリーを投げる事はできません。(多分。。)DBコネクションを追加して対応する方法もありますが、接続数をその分消費してしまうため可能であれば避けたい方法ではあります。</p><p>- `<b>enableBufferedResults</b>`を有効にすると、イテレータが内部で使用され、データベースの接続がクローズされると自動的にクリーンアップされます。</p><p>- 大規模なデータセットを処理する場合、`<b>enableBufferedResults</b>`を有効にしても、パフォーマンスの問題が発生する可能性があるため、適切なインデックスやクエリの最適化も検討してください。</p><p>- メモリーの使用状況に注意し、必要な場合には適切なタイミングで不要なリソースを解放することをお勧めします。</p>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-74081227618204241252023-07-11T07:00:00.032+09:002023-07-11T10:15:49.329+09:00PHP5.3 環境でcomposer self-update して動かなくなった時<p>RHEL6 ELS の環境で composer self-update をしてしまったようで、アップデートされたけど同時に comopser が壊れてしまった。。<br />$data が何やら invalid foreach だの。。<br /><br />前にもあったが composer は環境の phpのバージョンを見てアップデートした良いかを判別しておらず、動かなくても更新しちゃうクールなやつ♪</p><p>って事で</p><p>$ composer self-update 1.7.2<br /></p><p>を行うが <br /></p><p><span style="background-color: red;"><span style="color: white;">[ErrorException]<br />Invalid argument supplied for foreach() </span></span></p><p>チーン。。<br /></p><p>って事で削除してインストールしなおす。</p><p>$ cd ~/<br />$ rm ./bin/comopser<br />$ cd ./bin<br />$ curl -sS https://getcomposer.org/installer | php -- --version=1.7.2<br />$ mv ./composer.phar composer</p><h2 style="text-align: left;">composer とは</h2><div><div>Composerは、PHPプログラミング言語向けの依存関係管理ツールです。PHPのパッケージやライブラリのインストール、更新、バージョンの管理を容易に行うことができます。</div><div><br /></div><div>Composerは、PHPアプリケーションの開発において、外部のライブラリやパッケージを利用する場合に特に便利です。通常、PHPのプロジェクトでは、複数のライブラリやパッケージが必要となることがあります。それらのライブラリやパッケージの依存関係を手動で管理するのは困難で時間がかかるため、Composerを使用することで効率的に管理することができます。</div><div><br /></div><div>Composerは、プロジェクトのルートディレクトリに配置される`<b>composer.json</b>`と呼ばれる設定ファイルを使用して、必要なパッケージやライブラリを指定します。Composerは、指定された依存関係を解決し、自動的に必要なパッケージをダウンロードしてインストールします。</div><div><br /></div><div>Composerは、PHPコミュニティで広く使用されており、多くのPHPフレームワークやプロジェクトで標準的な依存関係管理ツールとして採用されています。</div></div><div><br /></div><h2 style="text-align: left;">composer をアップグレードする方法</h2><div><div>Composer自体のアップデートは、コマンドラインで簡単に行うことができます。以下の手順に従って、Composerを最新バージョンにアップデートする方法を説明します。</div><div><br /></div><div>1. ターミナルまたはコマンドプロンプトを開きます。</div><div>2. Composerがグローバルにインストールされている場合は、以下のコマンドを実行します:</div><div><br /></div><div> $ composer self-update</div><div><br /></div><div> Composerがローカルにプロジェクトごとにインストールされている場合は、プロジェクトのルートディレクトリで上記のコマンドを実行します。</div><div> </div><div> Composerがアップデートされ、最新バージョンに更新されます。</div><div><br /></div><div>3. コマンドが正常に実行された場合、Composerは自動的に最新バージョンに更新されます。</div><div><br /></div><div>なお、Composerをアップデートするにはインターネット接続が必要です。アップデート後は、最新の機能や修正が適用されたComposerを使用することができます。</div></div><div><br /></div><h2 style="text-align: left;">comopser をダウングレードする方法</h2><div><div>Composerを特定のバージョンにダウングレードするには、次の手順に従ってください。</div><div><br /></div><div>1. ターミナルまたはコマンドプロンプトを開きます。</div><div><br /></div><div>2. Composerの現在のバージョンを確認します。以下のコマンドを実行します:</div><div><br /></div><div>$ composer --version</div><div><br /></div><div> 現在のバージョンが表示されます。</div><div><br /></div><div>3. ダウングレードしたいバージョンを指定してComposerをインストールします。以下のコマンドを実行します:</div><div><br /></div><div>$ composer self-update <version></div><div><br /></div><div> `<version>`の部分に、ダウングレードしたいバージョン番号を指定します。例えば、Composerを1.10.10にダウングレードする場合は次のようにします:</div><div><br /></div><div>$ composer self-update 1.10.10</div><div><br /></div><div>4. コマンドが正常に実行された場合、指定したバージョンのComposerがインストールされます。</div><div><br /></div><div>ダウングレード後は、指定したバージョンのComposerを使用することができます。ただし、Composerをダウングレードする場合、そのバージョンに関連する制約や制限があるかもしれないことに注意してください。最新バージョンを使用することが推奨される場合もあります。</div></div>
<div style="text-align: center;"><iframe frameborder="0" marginheight="0" marginwidth="0" sandbox="allow-popups allow-scripts allow-modals allow-forms allow-same-origin" scrolling="no" src="//rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=unlax06-22&language=ja_JP&o=9&p=8&l=as4&m=amazon&f=ifr&ref=as_ss_li_til&asins=B09372PSG7&linkId=42811a75d144fff471284cfb3e224502" style="height: 240px; width: 120px;"></iframe></div>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-29501094743647795362023-06-05T10:42:00.003+09:002023-06-05T10:42:26.178+09:00Windows 10,11 でファイル拡張子を再帰的に一括更新する方法<p>Windowsでファイルの拡張子を一括置換するには、次の手順を実行します。</p><p>1. ファイルをバックアップします。一括置換操作を行う前に、重要なファイルを保護するためにバックアップを作成することを強くおすすめします。</p><p>2. PowerShellを開きます。スタートメニューから「PowerShell」を検索して開くか、Shift + 右クリックでフォルダ内の空白スペースをクリックし、「PowerShellウィンドウをここで開く」を選択します。</p><p>3. 次のコマンドを使用して、指定されたディレクトリ内のファイルの拡張子を一括置換します。以下のコマンドをPowerShellウィンドウに貼り付けて実行します。</p><p><br /></p><p><b>powershell</b></p><p>Get-ChildItem -Recurse -Filter "*.tpl" | Rename-Item -NewName { $_.Name -replace '\.tpl$', '.php' }</p><p>※ 上記は .tpl のファイルを再帰的に .php に置換する。<br /></p><p><br /></p><p>上記のコマンドは、指定されたディレクトリ(およびそのサブディレクトリ)内のすべての.tplファイルを検索し、それらの拡張子を.phpに置換します。</p><p>置換する拡張子を変更したい場合は、上記のコマンドの「.tpl」および「.php」を適切な拡張子に変更してください。</p><p>注意:この操作はファイルの拡張子を変更するため、慎重に行ってください。誤って重要なファイルの拡張子を変更すると、ファイルが正常に動作しなくなる可能性があります。</p>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-67778631015581238722023-05-26T20:00:00.001+09:002023-05-26T20:00:00.149+09:00[Git] ログ、履歴から特定のファイルを削除する<h2 style="text-align: left;"> 経緯</h2><p>テストデータだが、メールアドレスなどを含むファイルを間違ってコミットしてしまったので、ログからも削除したい。</p><p>早速調べたが、どうやらGitには最初からこれに対応するコマンドは用意されておらず拡張機能を追加してやる必要があるようだ。</p><p>以下に今回の対応方法をメモする。</p><span></span><span><a name='more'></a></span><p><br /></p><h2 style="text-align: left;">対応方法</h2><p>「<b>git filter-branch</b>」で対応もできるようだが、どうやらこれはもう古い対応方法なようで、今は「<b>git filter-repo</b>」で対応する方がスマートなようだ。</p><h4 style="text-align: left;">1. Python のインストール</h4><h4 style="text-align: left;">既にPythonがインストールされているかを確認。</h4><p>コマンドプロンプトやPowerShellで以下コマンドを実行する。</p><p>> py --version</p><p>インストールされているPythonのバージョンが表示されれば、Pythonが正常にインストールされています。</p><h4 style="text-align: left;">Pythonをインストールしていない場合</h4><p>公式のPythonウェブサイト(<a href="https://www.python.org/downloads/windows/" target="_blank">https://www.python.org/downloads/windows/</a>)から最新の安定版をダウンロードし、インストーラーを実行してPythonをインストールしてください。インストール時に「Add Python to PATH」オプションを有効にすることを忘れないでください。</p><h3 style="text-align: left;">2. Gitのインストール</h3><p>Gitをまだインストールしていない場合は、Git公式のウェブサイト(<a href="https://git-scm.com/downloads">https://git-scm.com/downloads</a>)からGitをダウンロードしてインストールしてください。</p><h4 style="text-align: left;">3. コマンドプロンプトまたはPowerShellを開きます</h4><h4 style="text-align: left;">4. git filter-repoのインストール:</h4><p>インストールにはpipコマンドを使用します。以下のコマンドを入力してgit filter-repoをインストールします。</p><p>>pip install git-filter-repo</p><p>インストールが完了すると、git filter-repoが使用可能になります。</p><h4 style="text-align: left;">5. インストールの確認:</h4><p>インストールが成功したかどうかを確認するには、コマンドプロンプトまたはPowerShellで以下のコマンドを入力します。</p><p>> git filter-repo --version</p><div><div>バージョン情報が表示されれば、git filter-repoが正常にインストールされています。</div><div><br /></div><div>これでWindowsにgit filter-repoがインストールされました。以降は、git filter-repoコマンドを使用してリポジトリのフィルタリングを行うことができます。</div></div><h2 style="text-align: left;">`git filter-repo`を使用してGitの履歴からファイルを削除</h2><p style="text-align: left;">`git filter-repo`を使用してGitの履歴からファイルを削除するには、次の手順を実行します。</p><div><div><ol style="text-align: left;"><li> `git filter-repo`をインストールします。公式のGitHubリポジトリ(https://github.com/newren/git-filter-repo)にアクセスして、インストール手順に従ってください。</li><li>削除したいファイルを含むリポジトリのディレクトリに移動します。</li><li>`git filter-repo`コマンドを実行します。以下のような形式でコマンドを入力します。<br /><br />> git filter-repo --path <file-path> --invert-paths<br /><br />`<file-path>`には削除したいファイルのパスを指定します。このコマンドは、指定したファイルを含まない新しいリポジトリを作成します。<br /><br />例: > git filter-repo --path docker/db/dump/all.sql --invert-paths --force<br /><br /></li><li>`git filter-repo`が実行されると、履歴から指定したファイルが削除されます。</li><li>必要に応じて、新しいリポジトリをリモートにプッシュするなど、適切な操作を行います。</li></ol></div><div>注意: `git filter-repo`は非常に強力なツールです。ファイルの削除などの操作を行う前に、操作の影響や結果を理解し、バックアップを取ることを強くお勧めします。</div></div><div><br /></div><div>git filter-repo --path docker/db/dump/all.sql --invert-paths --force</div>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-61458514923197344582023-04-27T19:00:00.003+09:002023-04-27T19:00:00.147+09:00[CakePHP4] Controller から コマンドを実行する方法<pre class="php" name="code">$commandRunner = new CommandRunner(new Application(ROOT . DS . 'config'), 'cake');
$commandRunner->run([
'bin' . DS . 'cake',
'command_name',
'param1',
'param2,
]);
</pre>
<p>上記は</p><p>$ bin/cake command_name param1 param2</p><p>と同等。
</p>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-16717654328702830362023-03-06T19:00:00.004+09:002023-03-06T19:00:00.198+09:00[PHP Code Sniffer] The closing parenthesis and the opening brace of a multi-line function declaration must be on the same line<h2 style="text-align: left;">エラー内容</h2><p>ERROR | [x] The closing parenthesis and the opening brace of a multi-line function declaration must be on the same line</p><p>) と { は同一行に書きなさい!!</p><p><br /></p><h3 style="text-align: left;">修正前</h3><p>public function sampleFunc(</p><p> int $bookId,</p><p> string $bookName</p><p>): ?BookEntity</p><p>{</p><p> // ...</p><p>}</p><p><br /></p><h3 style="text-align: left;">修正後</h3><p>public function sampleFunc(</p><p> int $bookId,</p><p> string $bookName</p><p>): ?BookEntity {</p><p> // ...</p><p>}</p>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-9397898979990741362022-04-21T18:30:00.001+09:002022-04-21T18:30:00.171+09:00[Windows] Tera Term などを使わずにクリックしたらトンネル接続開始にする方法<h2 style="text-align: left;"> 今回参考にしたサイト</h2><p></p><ul style="text-align: left;"><li>Windows 10 - コマンドでポートフォワード(SSHトンネル)<br /><a href="https://blog.y-yuki.net/entry/2021/04/11/100000" rel="nofollow" target="_blank">https://blog.y-yuki.net/entry/2021/04/11/100000</a></li><li>PowerShell起動時、文字コードをUTF-8に変える方法<br /><a href="https://qiita.com/s4i/items/75c19c9feb10b54c1ce9" rel="nofollow" target="_blank">https://qiita.com/s4i/items/75c19c9feb10b54c1ce9</a></li></ul><p></p><p><br /></p><h2 style="text-align: left;">トンネル接続する</h2><div>まずは Windows の PowerShell だけを使ってトンネル接続をします。</div><div><br /></div><div>> ssh [username]@[from_host] -i [secret_file_path] -L [from_port]:[to_host]:[to_port]<br /><br />例:<br />ポート:2022 の場合は fhost.com サーバー経由で thost.com サーバーに ポート:22 で接続したいという場合。<br /><br />fhost.com の 接続アカウントは<br />host: fhost.com<br />username: user<br />key_file: C:\Users\user\.ssh\id_rda.pem<br /><br /></div><div>> ssh user@fhost.com -i C:\Users\user\.ssh\id_rda.pem<br /> -L 2022:thost.com:22</div><div><br /></div><div>鍵ファイルがユーザーディレクトリ以下(もしくはユーザーを限定的に設定)でなければ警告が出てうまく接続できないので、それについて困ったらこちらを参考にしてください。</div><div><br />PowerShell で sshすると UNPROTECTED PRIVATE KEY FILE</div><div><a href="https://blog.y-yuki.net/entry/2021/04/11/100000" rel="nofollow" target="_blank">https://blog.y-yuki.net/entry/2021/04/11/100000</a></div><h2 style="text-align: left;">ショートカットを作成</h2><div>好きなところでショートカットを新規作成する</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjqCo7F-2eLtqhCVtimLXEgKIHfHkJ0-HD_3mOr3Tg4qODuR4jjPiN7VkjkS9xITC3FoE2ZxHNxU-QEO_6sVmhWhEGWl43SbfLk6dsqIMs_iJnNUrf_TnTI2qPPsfYrwrNRKNmMjp2mXG2lCL69UHVso7S9i1Wwt2lZI4LO3jT4N1_fk4_RCFyA6H1YOQ" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="319" data-original-width="617" height="165" src="https://blogger.googleusercontent.com/img/a/AVvXsEjqCo7F-2eLtqhCVtimLXEgKIHfHkJ0-HD_3mOr3Tg4qODuR4jjPiN7VkjkS9xITC3FoE2ZxHNxU-QEO_6sVmhWhEGWl43SbfLk6dsqIMs_iJnNUrf_TnTI2qPPsfYrwrNRKNmMjp2mXG2lCL69UHVso7S9i1Wwt2lZI4LO3jT4N1_fk4_RCFyA6H1YOQ" width="320" /></a></div><br />"項目の場所を入力してください(T)" に以下を入力する。</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjCKyXcjBoUaCOIY62W7uzSn_c2EOh8Zx_6sPwzlvWGZ4MnTKlQZLlBAEuxB_AC8a8G3S8X8M8bODQ7bNHPLzXpfQ0Stuk_mawKBuNytuHnlPWHd1Tx_63Wg9spue8DO1jGWQaFzFyTfYexsBuOFdXqnmER8Va9YTqj4vbmRpkKgIziSkC6bbHDOKLisQ" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="330" data-original-width="610" height="173" src="https://blogger.googleusercontent.com/img/a/AVvXsEjCKyXcjBoUaCOIY62W7uzSn_c2EOh8Zx_6sPwzlvWGZ4MnTKlQZLlBAEuxB_AC8a8G3S8X8M8bODQ7bNHPLzXpfQ0Stuk_mawKBuNytuHnlPWHd1Tx_63Wg9spue8DO1jGWQaFzFyTfYexsBuOFdXqnmER8Va9YTqj4vbmRpkKgIziSkC6bbHDOKLisQ" width="320" /></a></div><br />%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -NoExit -Command "ssh user@fhost.com -i C:\Users\user\.ssh\id_rda.pem -L 2022:thost.com:22"</div><div><br /></div><div>"次へ" をクリックするとショートカットの名前を確認されるので好きな名前を入力する。</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjTjaYYz08Xno0z77MxL8md-Vt8E8AKYQV22u0kezBWzweQjPKFQw5nx0BuWPMoSSH7xksYg2kpJCUg3eXKbodpucBgdG1vQ-rtutpERlkJFyqsIt76WgGzprIDxLLgzyOyd_NQrX0pyF5oo9D9Uf8QfBxySf3bA93yAJeCiGfSsFNh4kJh8Y0mQgJUUA" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="443" data-original-width="621" height="228" src="https://blogger.googleusercontent.com/img/a/AVvXsEjTjaYYz08Xno0z77MxL8md-Vt8E8AKYQV22u0kezBWzweQjPKFQw5nx0BuWPMoSSH7xksYg2kpJCUg3eXKbodpucBgdG1vQ-rtutpERlkJFyqsIt76WgGzprIDxLLgzyOyd_NQrX0pyF5oo9D9Uf8QfBxySf3bA93yAJeCiGfSsFNh4kJh8Y0mQgJUUA" width="320" /></a></div><br />"完了" をクリックして完了。</div><div><br /></div>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-88727832256910573152022-03-15T20:00:00.001+09:002022-03-15T20:00:00.176+09:00[Laravel] Windowsにはcronが無いので、タスク スケジューラにscheduleを設定する<p>Windowsにはcronが無いので、タスク スケジューラに設定するんですが、単純に設定するとコマンドプロンプトのウィンドウが一分毎に立ち上がって文字入力の邪魔をする。。</p><p>なので、もうVBSファイルからコマンドプロンプトを実行するようにしてこれを回避。</p><p>ついでにPHPのバージョン変更もするように。</p><p><br /></p><h2 style="text-align: left;">手順</h2><p></p><ol style="text-align: left;"><li>VBSファイルを作成<br /></li><li>タスク スケジューラに設定</li></ol><h2 style="text-align: left;">VBSファイルを作成</h2><div>VPSファイルはどこに置いても大丈夫です。</div><div>ただのテキストファイルなのでメモ帳で作成可能です。</div><div>拡張子は .vbs</div><div><br /></div><div>記載内容はこちら</div><div><br /></div><div><div>Set ws = CreateObject("Wscript.Shell") </div><div>ws.run "cmd /k set PATH=D:\app\php-8.0.14-nts-Win32-vs16-x64;%PATH% & cd D:\prjects\sample & php artisan schedule:run", 0, false</div></div><div><br /></div><div>記載内容の説明</div><div>ws.run で 3つのパラメータを指定しています。</div><div><br /></div><div>1つ目 実行するコマンド</div><div>2つ目 ウィンドウオプション 0=表示しない</div><div>3つ目 同期指定 false=非同期</div><div><br /></div><div>つまり 1つ目のコマンドは非表示で勝手に実行しといてくださいって感じです。</div><div><br /></div><div>run メソッドについて詳しくはこちら</div><div><a href="https://win.just4fun.biz/?WSH/%E5%A4%96%E9%83%A8%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%83%BBRun%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89" target="_blank">https://win.just4fun.biz/?WSH/%E5%A4%96%E9%83%A8%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%83%BBRun%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89</a></div><div><br /></div><div><div>コマンドは & 区切りで複数実行できますので、今回は</div><div><ol><li>PATH の更新</li><li>ディレクトリの移動</li><li>scheduleの実行</li></ol></div><div>をやっています。</div><div><br /></div></div><div><br /></div><p></p>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-84165926021894889832021-10-28T15:12:00.001+09:002021-10-28T15:12:30.197+09:00CakePHP4 Validation:: add() rule で利用できる値一覧<p>notBlank</p><p>alphaNumeric</p><p>notAlphaNumeric</p><p>asciiAlphaNumeric</p><p>notAsciiAlphaNumeric</p><p>lengthBetween</p><p>creditCard</p><p>numElements</p><p>comparison</p><p>compareWith</p><p>compareFields</p><p>containsNonAlphaNumeric</p><p>custom</p><p>date</p><p>datetime</p><p>iso8601</p><p>time</p><p>localizedTime</p><p>boolean</p><p>truthy</p><p>falsey</p><p>decimal</p><p>email</p><p>equalTo</p><p>extension</p><p>ip</p><p>minLength</p><p>maxLength</p><p>minLengthBytes</p><p>maxLengthBytes</p><p>money</p><p>multiple</p><p>numeric</p><p>naturalNumber</p><p>range</p><p>url</p><p>inList</p><p>uuid</p><p>luhn</p><p>mimeType</p><p>getFilename</p><p>fileSize</p><p>uploadError</p><p>uploadedFile</p><p>imageSize</p><p>imageWidth</p><p>imageHeight</p><p>geoCoordinate</p><p>latitude</p><p>longitude</p><p>ascii</p><p>utf8</p><p>isInteger</p><p>isArray</p><p>isScalar</p><p>hexColor</p><p>iban</p>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-10170762582246254452021-07-05T15:53:00.013+09:002021-07-29T17:18:21.759+09:00FriendsOfCake / search の使い方メモ<p></p><h2 style="text-align: left;">FriendsOfCake/search</h2><a href="https://github.com/FriendsOfCake/search" target="_blank">https://github.com/FriendsOfCake/search</a><p></p><h2 style="text-align: left;">インストール</h2><div><a href="https://github.com/FriendsOfCake/search#readme" target="_blank">https://github.com/FriendsOfCake/search#readme</a></div><p>composerをインストールした環境で</p><p>$ php composer.phar require friendsofcake/search</p><p>プラグインを追加したらソースから利用できるように</p><p>$ bin/cake plugin load Search</p><h2 style="text-align: left;">利用方法</h2><p><a href="https://github.com/FriendsOfCake/search/tree/master/docs">https://github.com/FriendsOfCake/search/tree/master/docs</a></p><p>Tableの <span color="var(--color-prettylights-syntax-entity)" face="ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace" style="font-size: 13.6px;">initialize() で</span>ビヘイベアを追加<br /><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_TD2uNXV_V2fpUG2_WV4h5TF-gC7p8yYacZOPb7JWsmMmQ8Q4vXZ5QexlHet0JcLQWv3qJEof_WGuKnw4AoOBcCldbwwQj0vaalfqa9kFLMXtZ6XB1Zl8A9FjMymYkGyzOa4t0tWlsd_5/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="50" data-original-width="288" height="56" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_TD2uNXV_V2fpUG2_WV4h5TF-gC7p8yYacZOPb7JWsmMmQ8Q4vXZ5QexlHet0JcLQWv3qJEof_WGuKnw4AoOBcCldbwwQj0vaalfqa9kFLMXtZ6XB1Zl8A9FjMymYkGyzOa4t0tWlsd_5/" width="320" /></a></div><br />同じく Table の <span face="ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace" style="font-size: 13.6px;">initialize() に検索条件のテンプレートのようなもので コレクション を記載する。<br /><br /></span><p></p><p><span face="ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace" style="font-size: 13.6px;"></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiuFV4jFyyqSHBJg9lXDFRaHwvpznL5mB4JbCTpTf-vvNUVfQpwQ2LOSIf7dm4icCMj6INmArfWG1baZ4XNrAj5371RRRx4DHN_Tnl_OioWXh3lXs0LVKqMWeCkzq6ft0zbcirXZPtcgWt/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="283" data-original-width="289" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiuFV4jFyyqSHBJg9lXDFRaHwvpznL5mB4JbCTpTf-vvNUVfQpwQ2LOSIf7dm4icCMj6INmArfWG1baZ4XNrAj5371RRRx4DHN_Tnl_OioWXh3lXs0LVKqMWeCkzq6ft0zbcirXZPtcgWt/" width="245" /></a></div><br />解りにくいけど <span color="var(--color-prettylights-syntax-entity)" face="ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace" style="font-size: 13.6px;">useCollection() から次の </span><span color="var(--color-prettylights-syntax-entity)" face="ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace" style="font-size: 13.6px;">useCollection() までが1つのコレクションとなるみたい。<br /><br />add() で追加できる1検索条件は色々なタイプが用意されている。</span><div><span color="var(--color-prettylights-syntax-entity)" face="ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace" style="font-size: 13.6px;"><br /></span></div><div><span color="var(--color-prettylights-syntax-entity)" face="ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace" style="font-size: 13.6px;">add() の第2パラメーターで、指定する他、メソッドからも検索タイプを指定可能。</span></div><div><span color="var(--color-prettylights-syntax-entity)" face="ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace" style="font-size: 13.6px;">この方が phpstorm とかなら候補で出てくるので解りやすい。</span></div><div><h3 style="text-align: left;"><span color="var(--color-prettylights-syntax-entity)" face="ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace" style="font-size: 13.6px;">フィルター</span></h3><p></p><div style="text-align: left;"><ol style="text-align: left;"><li><span face="ui-monospace, SFMono-Regular, SF Mono, Consolas, Liberation Mono, Menlo, monospace"><span><span style="font-size: 13.6px;"><b>value()</b><br /></span></span></span>完全一致で検索をする。</li><li><b>like()</b><br />LIKE検索をする。</li><li><span style="font-size: 13.6px;"><b>boolean()</b><br />結果を true または false で検索をする。<br />※true にはデフォルトで 1、true、 '1'、 'true'、 'yes'、 'on' を含む。</span></li><li><span style="font-size: 13.6px;"><b>exists()</b><br />対象カラムがNOT NULLかを検索する。</span></li><li><span style="font-size: 13.6px;"><b>finder()</b><br />finder****() という関数を使用して検索する。<br />https://book.cakephp.org/3/ja/orm/retrieving-data-and-resultsets.html#custom-find-methods<br /></span></li><li><span style="font-size: 13.6px;"><b>compare()</b><br />比較演算子(>, <= など)を使って検索する。</span></li><li><span style="font-size: 13.6px;"><b>callback()</b><br />コールバック関数を使って検索する。<br /><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-a4RK2QYMySSaHDFFbmMbuUX4YLwd-gFkuZqeVG7oKA5bS7BuoEJsBqBZyo0jzeCWqRyCeruk0DImb8vFK6VcdhGz_baqAnWZ5R15HPd8M8vCPEBQuNupdXf9iDXxL8J9-d7sf5CuFyGt/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="101" data-original-width="772" height="42" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-a4RK2QYMySSaHDFFbmMbuUX4YLwd-gFkuZqeVG7oKA5bS7BuoEJsBqBZyo0jzeCWqRyCeruk0DImb8vFK6VcdhGz_baqAnWZ5R15HPd8M8vCPEBQuNupdXf9iDXxL8J9-d7sf5CuFyGt/" width="320" /></a><br /></div><br /><br /></span></li></ol></div><h3 style="text-align: left;">対応オプジョン</h3><div><h4 style="text-align: left;">共通で利用できるオプジョン</h4><div style="text-align: left;"><ol style="text-align: left;"><li> <b>fields </b>(array)<br />検索に使用するフィールドの名前を指定する。</li><li><b>name </b>(string、デフォルトでは、add filterメソッドの最初の引数に渡された名前になります)<br />フィルターの名前をフィールドとは別にしたい場合に利用する。</li><li><b>alwaysRun </b>(bool、デフォルトはfalse)<br />存在するかどうかに関係なく、フィルタを常に実行するかどうかを定義する。</li><li><b>filterEmpty </b>(bool、デフォルトはfalse)<br />空の場合に、フィルターを実行しないかどうかを定義する。</li><li>flatten (bool、デフォルトはtrue)<br />入力フォームから配列として渡される値をフラット化するかどうかを定義する。</li><li><b>beforeProcess </b>(callable、デフォルトはnull)<br />$queryと$argsを引数として受け取ります。たとえば、クエリに結合または包含を設定するためにコールバックを使用。</li><li><b>aliasField </b>(bool、デフォルトはtrue)<br />フィールド名にエイリアスを設定する場合に利用する。</li><li><b>defaultValue</b> (mixed、デフォルトはnull)<br />デフォルト値を指定する。</li></ol></div><h3 style="text-align: left;">Boolean</h3><div style="text-align: left;"><ol style="text-align: left;"><li><b>mode</b> (string、デフォルトはOR)<br />複数のフィールドと照合するときに使用する条件付きモード。<br />有効な値は、ORとAND。</li></ol></div><h4 style="text-align: left;"> Exists</h4><div style="text-align: left;"><ol style="text-align: left;"><li><b>mode</b> (string、デフォルトはOR)<br />複数のフィールドと照合するときに使用する条件付きモード。<br />有効な値は、ORとAND。</li><li><b>nullValue </b>(stringまたはnull、デフォルトはnull)<br />null許容でない列に使用できます。<br />=/の!=代わりにIS NULL/を介してチェックするには、空の文字列に設定しIS NOT NULLます。</li></ol></div><h4 style="text-align: left;">Compare</h4><div style="text-align: left;"><ol style="text-align: left;"><li><b>operator</b> (string、デフォルトは>=)<br />比較に使用する演算子。有効な値は>=、<=、>と<。</li><li><b>mode</b> (string、デフォルトはAND)<br />複数のフィールドと照合するときに使用する条件付きモード。<br />有効な値は、ORとAND。</li></ol></div><h4 style="text-align: left;">Like</h4><div><ol style="text-align: left;"><li><b> multiValue</b> (bool、デフォルトはfalse)<br />フィルターが複数の値を受け入れるかどうかを定義します。<br />無効になっていて、複数の値が渡されている場合、フィルターは defaultValue オプションで定義されたデフォルト値の使用にフォールバックします。</li><li><b>multiValueSeparator</b> (string、デフォルトはnull)<br /> 特定の区切り文字列を使用して、フィルターが複数の値を自動トークン化するかどうかを定義します。無効にした場合、データは配列の形式である必要があります。</li><li><b>colType </b>(array)<br />連想配列。実際の型に関係なく、文字列列として扱う必要がある列のカスタム型を設定するために使用します。これは、整数フィールドが検索対象のフィールドの一部である場合など、整数フィールドにとって重要です。使用例: 'colType' => ['id' => 'string']</li><li><b>before </b>(bool、デフォルトはfalse)<br />検索語の前にワイルドカードを自動的に追加するかどうか 。</li><li><b>after </b>(bool、デフォルトはfalse)<br />検索語の後にワイルドカードを自動的に追加するかどうか 。<br /></li><li><b>fieldMode </b>(string、デフォルトはOR)<br />複数のフィールドと照合するときに使用する条件付きモード。有効な値は、ORとAND。</li><li><b>valueMode </b>(string、デフォルトはOR)<br />複数の値を検索するときに使用する条件付きモード。有効な値は、ORとAND。</li><li><b>comparison</b> (string、デフォルトはLIKE)<br />使用する比較演算子。</li><li><b>wildcardAny </b>(string、デフォルトは*)<br />として扱われるべき文字列を定義する任意のそれは検索用語に遭遇している場合にワイルドカードを。この動作により、これは内部的に適切なSQL互換のワイルドカードに置き換えられます。これは、検索語内で実際のワイルドカード文字を使用して用語の一部として扱われるようにしながら、検索語内でワイルドカードを渡したい場合に役立ちます。たとえば、の検索語* has reached 100%はに変換され% has reached 100\%ます。さらに、オプションを参照してくださいescapeDriver。</li><li><b>wildcardOne</b> (string、デフォルトは?)<br />検索語で検出された場合に1つのワイルドカードとして扱われる文字列を定義します。と同様に動作しwildcardAnyます_。つまり、検索語が使用された場合、実際のSQL互換ワイルドカード()はエスケープされます。</li><li><b>escaper</b> (stringへのデフォルトnull)<br />エスケープする必要がありエスケー定義%とは_。エスケープ機能が設定されていない場合(escapeDriver => 'null')、エスケープ機能はデータベースドライバによって設定されます。ドライバがある場合 に使用される(エスケープするとします)。他のすべての場合に (エスケープに使用されるにし、に)。と設定にエスケープを追加することで、独自のエスケープを追加できます。SqlserverSqlserverEscaper%[%]_[_]DefaultEscaper%\%_\_App\Model\Filter\Escaper\OwnEscaper'escaper' => 'App.Own'</li></ol></div><h4 style="text-align: left;">Value</h4><div style="text-align: left;"><div><ol style="text-align: left;"><li><b>multiValue</b> (bool、デフォルトはfalse)<br />フィルターが複数の値を受け入れるかどうかを定義します。無効になっていて、複数の値が渡されている場合、フィルターはdefaultValueオプションで定義されたデフォルト値の使用にフォールバックします。</li><li><b>multiValueSeparator </b>(string、デフォルトはnull)<br />特定の区切り文字列を使用して、フィルターが複数の値を自動トークン化するかどうかを定義します。無効にした場合、データは配列の形式である必要があります。</li><li><b>mode</b> (string、デフォルトはOR)<br />複数のフィールドと照合するときに使用する条件付きモード。有効な値は、ORとAND。</li><li><b>negationChar (string、デフォルトはnull)</b><br />multiValue特に値が多い場合は、の代替。フィルタは任意の文字列を受け入れますが、理想的には、検索値のプレフィックスとして単一の一意の文字である必要があります。たとえば!、文字列値または-数値の場合。有効にすると、フィルターはこの値の式を無効にします。</li></ol></div></div><h3 style="text-align: left;">Finder</h3><ol style="text-align: left;"><li><b>finder </b><span style="font-weight: normal;">(string、デフォルトはフィルター名)<br /> 使用する検索タイプ。</span></li><li><b>map</b><span style="font-weight: normal;"> (array、デフォルトは[])<br /> フィールドをファインダーキー('to_field' => 'from_field')にマップする必要がある場合は、配列を構成します。</span></li><li><b>options</b> (array、デフォルトは[])<br /><span style="font-weight: normal;">ファインダーに渡す追加オプション。</span></li></ol><div> </div></div><div><br /></div></div>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-68286681845318373612021-05-27T18:29:00.004+09:002021-05-27T18:29:34.921+09:00[Flutter] flutter doctor で Android Studio が入っているのに認識してくれない時<p>Android Studio をインストールしてるのに</p><p>> flutter doctor</p><p>で確認すると</p><p>[!] Android Studio (not installed)</p><p>となる。。</p><p>そんな時は</p><p> > flutter config --android-studio-dir="C:\Program Files\Android\Android Studio"</p><p>とインストール場所を教えてやると解決!!</p><p>[√] Android Studio</p><div><br /></div><p><br /></p>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-43300516274183850282021-05-22T10:09:00.008+09:002021-05-22T10:09:00.246+09:00[CakePHP4] 翻訳ファイルの作成まで<div style="text-align: left;"><div>翻訳辞書ファイル(.po)を作成するまでの手順</div><div><br /></div><div><div>PS D:\prj\example.com\www.example.com> ./bin/cake i18n</div><div>I18n Shell</div><div>-------------------------------------------------------------------------------</div><div>[E]xtract POT file from sources</div><div>[I]nitialize a language from POT file</div><div>[H]elp</div><div>[Q]uit</div><div>What would you like to do? (E/I/H/Q)</div><div>> E</div><div>Current paths: None</div><div>What is the path you would like to extract?</div><div>[Q]uit [D]one</div><div>[D:\prj\example.com\www.example.com\src\] ></div><div><br /></div><div>Current paths: D:\prj\example.com\www.example.com\src\</div><div>What is the path you would like to extract?</div><div>[Q]uit [D]one</div><div>[D:\prj\example.com\www.example.com\templates\] ></div><div><br /></div><div>Current paths: D:\prj\example.com\www.example.com\src\, D:\prj\example.com\www.example.com\templates\</div><div>What is the path you would like to extract?</div><div>[Q]uit [D]one</div><div>[D] ></div><div><br /></div><div>Would you like to extract the messages from the CakePHP core? (y/n)</div><div>[n] > y</div><div>What is the path you would like to output?</div><div>[Q]uit</div><div>[D:\prj\example.com\www.example.com\resources\locales\] ></div><div><br /></div><div><br /></div><div>Extracting...</div><div>-------------------------------------------------------------------------------</div><div>Paths:</div><div> D:\prj\example.com\www.example.com\src\</div><div> D:\prj\example.com\www.example.com\templates\</div><div> D:\prj\example.com\www.example.com\vendor\cakephp\cakephp\src\</div><div>Output Directory: D:\prj\example.com\www.example.com\resources\locales\</div><div>-------------------------------------------------------------------------------</div><div>==========================================================================> 100%</div><div>default.pot is unchanged. Skipping.</div><div>cake.pot is unchanged. Skipping.</div><div><br /></div><div>Done.</div><div><br /></div><div><span style="color: red;">ここまでで .po ファイルの雛形となる .pot ファイルが作成される。</span></div><div><br /></div><div>What would you like to do? (E/I/H/Q)</div><div>> I</div><div>Please specify language code, e.g. `en`, `eng`, `en_US` etc.</div><div>> ja_JP</div><div>What folder?</div><div>[D:\prj\example.com\www.example.com\resources\locales\] ></div></div><div><br /></div><div><span style="color: red;">.po が ja_JP 以下に作成される。</span></div></div>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-18781302646126406082021-05-18T14:42:00.006+09:002021-05-18T14:42:49.060+09:00[CakePHP4] bake template で index,view,add,edit 以外を追加自分は<div><ul style="text-align: left;"><li>add.php</li><li>edit.php</li><li>index.php</li><li>view.php</li></ul><div>以外にも form.php を作成していて、 add.php, edit.php からそれを呼び出して共通かしています。</div><div>なので、bakeコマンドで form.php も作ってほしい。</div><div><br /></div><div>あと基本的には Bootstrap を利用しているので、テーマを自作してと。。</div><div><ul style="text-align: left;"><li>plugins/BootstrapTheme/templates/bake/Template/add.twig</li><li>plugins/BootstrapTheme/templates/bake/Template/edit.twig</li><li>plugins/BootstrapTheme/templates/bake/Template/index.twig</li><li>plugins/BootstrapTheme/templates/bake/Template/view.twig</li><li>plugins/BootstrapTheme/templates/bake/Template/form.twig</li></ul></div></div><div>こんな感じ。</div><div><br /></div><div>作成して </div><div><br /></div><div>$ ./bin/cake bake template</div><div><br /></div><div>とするけど。。</div><div><br /></div><div>いつも通り</div><div><ul><li>add.php</li><li>edit.php</li><li>index.php</li><li>view.php</li></ul></div><div>ができるだけ。。</div><div><br /></div><div>form.php だけを追加するのは以下のようなコマンドでできるので、自分のそれで追加しています。。</div><div><br /></div><div>$ ./bin/cake bake template samples form</div><div><br /></div><div><br /></div>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-17438856702574774862019-12-26T14:10:00.000+09:002019-12-27T17:01:23.633+09:00[PHP] Amazon MWS API Feed のXMLをXSDファイルを利用してバリデート(検証)する<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT4pCVlSvwmjpmu8KqtrCSuzEeFP9fYdeCdpp8CVkhyphenhyphenFpv2KS3dhA4PEdcyhtz9PhN5G5lQBlAN3TZVtpqVVWjO0X9HNy-CvpT8N5FtxGj-UB_sB5275ffuW9gwqu5lUkGT6LWhBrlZFkH/s1600/665d50adefa4404378b00aef4276669c_s.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="427" data-original-width="640" height="425" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT4pCVlSvwmjpmu8KqtrCSuzEeFP9fYdeCdpp8CVkhyphenhyphenFpv2KS3dhA4PEdcyhtz9PhN5G5lQBlAN3TZVtpqVVWjO0X9HNy-CvpT8N5FtxGj-UB_sB5275ffuW9gwqu5lUkGT6LWhBrlZFkH/s640/665d50adefa4404378b00aef4276669c_s.jpg" width="640" /></a></div><div style="text-align: right;"><a href="https://www.photo-ac.com/profile/2072741">gontora</a>さんによる<a href="https://www.photo-ac.com/">写真AC</a>からの写真 </div><br />
Amazon MWS API を利用して出品する際にXMLで一覧を生成するのだが、その生成したXMLが正しいかを判別するために Amazon MWS API のドキュメントサイトで配布されている XSD を利用した。<br />
<br />
http://docs.developer.amazonservices.com/ja_JP/feeds/Feeds_FeedType.html<br />
<br />
<blockquote class="tr_bq">注: XMLフィードの作成方法によっては、商品情報フィードではなく、アイテムフィードスキーマを使用するよう、出品者に求められます。</blockquote><br />
ほんまAmazon紛らわしいな。。<br />
こんな紛らわしいのに開発環境提供してくれないし。。。<br />
<br />
Item フィード<br />
<a href="https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/Item.xsd" target="_blank">https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/Item.xsd</a><br />
<br />
Product フィード<br />
<a href="https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/Product.xsd" target="_blank">https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/Product.xsd</a><br />
<br />
XSDを利用してのXML検証方法<br />
<br />
<br />
<pre class="php" name="code">$xml = new DOMDocument();
libxml_use_internal_errors(true);
$xml->load('./sample.xml');
if ($xml->schemaValidate('./validate.xsd')) {
echo "Success \n";
}
else {
echo "Error \n";
$errors = libxml_get_errors();
foreach ($errors as $error) {
echo display_xml_error($error, $xml);
}
libxml_clear_errors();
}
function display_xml_error($error, $xml)
{
$return = $xml[$error->line - 1] . "\n";
switch ($error->level) {
case LIBXML_ERR_WARNING:
$return .= "Warning $error->code: ";
break;
case LIBXML_ERR_ERROR:
$return .= "Error $error->code: ";
break;
case LIBXML_ERR_FATAL:
$return .= "Fatal Error $error->code: ";
break;
}
$return .= trim($error->message) .
"\n Line: $error->line" .
"\n Column: $error->column";
if ($error->file) {
$return .= "\n File: $error->file";
}
}
</pre>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-37236220849272365242019-11-20T18:27:00.000+09:002019-11-20T18:45:52.654+09:00composer 削除方法$ composer remove --no-update phpoffice/phpexcel<br />
$ composer update --dry-run<br />
<br />
<blockquote class="tr_bq">
Loading composer repositories with package information<br />Updating dependencies (including require-dev)<br />Package operations: 0 installs, 0 updates, 1 removal<br /> - Uninstalling phpoffice/phpexcel (1.8.2)</blockquote>
<br />
- Uninstalling *** をアップデートで削除<br />
<br />
$ composer update phpoffice/phpexcel<br />
<br />
<h2>
複数該当する場合</h2>
Loading composer repositories with package information<br />
Updating dependencies (including require-dev)<br />
Package operations: 0 installs, 0 updates, 1 removal<br />
- Uninstalling phpoffice/phpexcel (1.8.2)<br />
- Uninstalling phpoffice/hoge (1.8.2)<br />
Package phpunit/phpunit-mock-objects is abandoned, you should avoid using it. No replacement was suggested.<br />
<br />
$ composer update phpoffice/phpexcel phpoffice/hoge<br />
<br />ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-44414312374730532442019-07-25T18:30:00.000+09:002019-07-25T18:30:01.035+09:00MySQL Workbench 8.0.17 では MySQL 5.1.73 に接続できない<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJkPc0lSVh_6RaHKSenlu4cXvz-oUIxxCIHxzbbRrYpLDyyyJ6eRwMCLTVzK6QR-wzcKfn-z6GiJv6La5KqFWDA4sU_INNC2TB5_eymgdJhypyOyEFD9CR0ohkbrS_J09YJI6jPl9oNcxK/s1600/MySqlWorkBench.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="602" data-original-width="913" height="261" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJkPc0lSVh_6RaHKSenlu4cXvz-oUIxxCIHxzbbRrYpLDyyyJ6eRwMCLTVzK6QR-wzcKfn-z6GiJv6La5KqFWDA4sU_INNC2TB5_eymgdJhypyOyEFD9CR0ohkbrS_J09YJI6jPl9oNcxK/s400/MySqlWorkBench.png" width="400" /></a></div>
<br />
<br />
MySQL Workbench 8.0.17<br />
<a href="https://dev.mysql.com/downloads/workbench/8.0.html">https://dev.mysql.com/downloads/workbench/8.0.html</a><br />
<br />
MySQL Workbench 8.0.17 にアップデートしてさあ繋げようと思ったら繋がらない。。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCxy_4RNMiNgjWdwndTmaPKjWaP5qSjqnB_EejBjINhIo2XrZE1n8gZp4_tfLonljz5ux7LM7Gu1OGTvriI-9R7Zo4-H6nZ5Zj5crvh2DuBRhNlCEX-Lb48C5f8uuFBUXf8ccttV7FKo59/s1600/MySQL-BadHandshake.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="344" data-original-width="395" height="278" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCxy_4RNMiNgjWdwndTmaPKjWaP5qSjqnB_EejBjINhIo2XrZE1n8gZp4_tfLonljz5ux7LM7Gu1OGTvriI-9R7Zo4-H6nZ5Zj5crvh2DuBRhNlCEX-Lb48C5f8uuFBUXf8ccttV7FKo59/s320/MySQL-BadHandshake.png" width="320" /></a></div>
<br />
「Bad handshake」やってさ。<br />
<br />
で、何でやろって調べてたらこんな記事発見<br />
<br />
<a href="https://www.urtech.ca/2019/01/solved-bad-handshake-mysql-workbench-failed-to-connect-to-sql/">https://www.urtech.ca/2019/01/solved-bad-handshake-mysql-workbench-failed-to-connect-to-sql/</a><br />
<br />
どうやら、MySQL Workbench 8.0.17 では MySQL 5.1.73 に接続できないみたい。<br />
<br />
で、解決策は古いバージョンを使いなさいと。<br />
<br />
MySQL Workbench 6.3.10<br />
<a href="https://dev.mysql.com/downloads/workbench/6.3.html">https://dev.mysql.com/downloads/workbench/6.3.html</a><br />
<br />
で入れたら動いたとさ。<br />
<br />
<table><thead>
<tr>
<th style="text-align: left;">Ver</th>
<th style="text-align: left;">期限</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;">5.7</td>
<td style="text-align: left;">2020年10月</td>
</tr>
<tr>
<td style="text-align: left;">5.6</td>
<td style="text-align: left;">2018年2月</td>
</tr>
<tr>
<td style="text-align: left;">5.5</td>
<td style="text-align: left;">2015年12月</td>
</tr>
<tr>
<td style="text-align: left;">5.1</td>
<td style="text-align: left;">2013年12月</td>
</tr>
<tr>
<td style="text-align: left;">5.0</td>
<td style="text-align: left;">2011年12月</td>
</tr>
</tbody>
</table>
<br /><div>
サポートも切れてるし仕方ないね。。</div>
ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-6755224305193605632019-07-11T07:00:00.000+09:002019-07-11T10:15:57.649+09:00[PhpStorm] 2019にバージョンアップしたらフォントが小さくて見にくくなった。。特にドットが酷い。。自分はできるだけツールはデフォルトの設定で使うようにしている。<br />
<br />
理由は環境の構築の時に設定が大変だから。。<br />
頑張って設定してもバージョンアップしたらその設定ができるとは限らないから。。<br />
作者がこのツールではこの設定が良いと思っているものがデフォルトだろうから。。<br />
<br />
と、まー理由はどうでもいいけどライセンス更新と合わせて phpstorm 2019にアップデート。<br />
<br />
2018の時は特にカラースキーマの変更だけで使えたんだけど、phpstorm 2019 にアップデートして明らかにフォント小さくなった。。<br />
<br />
.(ドット) と [半角スペース] の区別ができない。。<br />
<br />
それでも我慢した。。<br />
もう無理。。。<br />
<br />
って事で数ヶ月頑張ったけどやっぱり変更します。。<br />
<br />
カラースキーマ: Monokai<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoSNgB-RPT0gOnCS7FD_o36RKqck2DtwmhDG06qTisbqg-EJ1kLtXgsa1UOat6vz7r_WbhqlSFvwWIiC3XIlIo7qGtnvAlfapMwrUZycvpwqRbBgWoqroSDrgWM26dHzryWjWVDWg35khl/s1600/phpstorm_settings_schema.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="789" data-original-width="1017" height="310" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoSNgB-RPT0gOnCS7FD_o36RKqck2DtwmhDG06qTisbqg-EJ1kLtXgsa1UOat6vz7r_WbhqlSFvwWIiC3XIlIo7qGtnvAlfapMwrUZycvpwqRbBgWoqroSDrgWM26dHzryWjWVDWg35khl/s400/phpstorm_settings_schema.png" width="400" /></a></div>
<br />
<br />
フォント: Source Code Pro<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQBRX7lnZmqv1jlT2smOQ9zCrIpAp7nZtM14ylEPr5IKWZkxgHYzpWkyosHtI5OtsDkhG-MRp6UEaUGVVY0A44-jgqK2rzLpDfOO3CKl21qUb9-oUBKJVPZIfoKpqY4ZAb9Ej9FJnVBwOK/s1600/phpstorm_settings_font.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="789" data-original-width="1017" height="310" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQBRX7lnZmqv1jlT2smOQ9zCrIpAp7nZtM14ylEPr5IKWZkxgHYzpWkyosHtI5OtsDkhG-MRp6UEaUGVVY0A44-jgqK2rzLpDfOO3CKl21qUb9-oUBKJVPZIfoKpqY4ZAb9Ej9FJnVBwOK/s400/phpstorm_settings_font.png" width="400" /></a></div>
<br />
<br />
あ~ スッキリ♪ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-289667119897216402019-05-08T09:23:00.001+09:002019-05-08T09:23:15.337+09:00PhpStorm 割引販売のご紹介<div class="separator" style="clear: both; text-align: center;">
<img border="0" data-original-height="1600" data-original-width="937" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuedo4_GtTjYeQUu98c_n0sVxRtIYZ3izxWvXqE3UnxMHuoktxw4f0Umb40hSmM_vFXHCYqB2IKGi6pzupFVdE1pr7-DyKqkZGo4yauAj5Umy5q0Rve7J0fxMcMfTIyoq-Gw84genTOLFb/s640/screencapture-secure-samuraism-referral-8BAEF98D2EE87690D23BB03ED3A7F393-2019-05-08-09_18_48.png" width="374" /></div>
<br />
<a data-saferedirecturl="https://www.google.com/url?q=https://secure.samuraism.com/referral/8BAEF98D2EE87690D23BB03ED3A7F393&source=gmail&ust=1557360848712000&usg=AFQjCNGtMBTw71muN8zRcKIVbLzdBOdpWA" href="https://secure.samuraism.com/referral/8BAEF98D2EE87690D23BB03ED3A7F393" rel="noreferrer" style="background-color: white; color: #1155cc; font-family: Arial, Helvetica, sans-serif; font-size: small;" target="_blank">https://secure.samuraism.com/r<wbr></wbr>eferral/8BAEF98D2EE87690D23BB0<wbr></wbr>3ED3A7F393</a><br />
<br />
PhpStorm は300円しか割引ありませんが、無いよりは良いですしね。<br />
サムライズムって会社は2018年8月くらい(?)からの日本正規代理店みたいです。ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-44179013290121094802019-03-26T13:30:00.000+09:002019-03-26T13:30:13.002+09:00PHPソースからフロー図の自動作成 Visustin以外で以前 Visustin というツールを利用してPHPのソースからフロー図を作成しようとしただけど、何かしっくり来ない。。<br />
<br />
そして別のツールが無いかなと探していたらこんなブラウザアプリを発見した。<br />
<br />
<b>code2flow</b><br />
<a href="https://code2flow.com/" target="_blank">https://code2flow.com/</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkSUCpxCEEI7OEyH9xKo6XY7hbD078TFIX3XG96lEAjg6lzxt9XQpNbDBNE4x1ceXuCG8MY_QHU2R4TGf6ngRL9PClFKYfonKFr2Z37fEXZWReorTIyEXXtCLv6ruyftW1E8BIJWsIpC1L/s1600/code2flow01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="924" data-original-width="1411" height="209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkSUCpxCEEI7OEyH9xKo6XY7hbD078TFIX3XG96lEAjg6lzxt9XQpNbDBNE4x1ceXuCG8MY_QHU2R4TGf6ngRL9PClFKYfonKFr2Z37fEXZWReorTIyEXXtCLv6ruyftW1E8BIJWsIpC1L/s320/code2flow01.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
無料プランもあるみたい。</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw4i3MDK41DBq5EHu1E8Gb-wfaFLH6L6wkYLoEiyCL8m7cqndhStNMFdZtgwiz1QwfEyeJp6Pa3-aXQikccZGRydQdnJRhbokCkNHn5R-9KGeOZhrUqFYk3OZ9saGqfyjPXOIIVQhd7IK6/s1600/code2flow06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1039" data-original-width="1253" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw4i3MDK41DBq5EHu1E8Gb-wfaFLH6L6wkYLoEiyCL8m7cqndhStNMFdZtgwiz1QwfEyeJp6Pa3-aXQikccZGRydQdnJRhbokCkNHn5R-9KGeOZhrUqFYk3OZ9saGqfyjPXOIIVQhd7IK6/s320/code2flow06.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
早速トップページ画面右上の GET STARTED から試してみた。</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA2u3X4tWcMEDrHF5yoB2YYdQ0iv1z5_oSw9zpn6F4oVxxLR82MZTqi0uC0rfa61wq2APmB_Bd_tpLcQpe7-RioTulOHERp_XdC1tBIZEKGXefhCNX_fC9Atee-GJUBUPrmnhYplf64aCt/s1600/code2flow02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="910" data-original-width="1066" height="273" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA2u3X4tWcMEDrHF5yoB2YYdQ0iv1z5_oSw9zpn6F4oVxxLR82MZTqi0uC0rfa61wq2APmB_Bd_tpLcQpe7-RioTulOHERp_XdC1tBIZEKGXefhCNX_fC9Atee-GJUBUPrmnhYplf64aCt/s320/code2flow02.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1AqIP16pDqkYQUblW-ZIMHBbPfvGD6MRbdcVO8seSKInmoDXCDhMmn3bO3TUb3jOH0C5HXCw0jmaPIoC7C0kYzPTahyphenhyphenju6loZISbrsAPbPFuz4p4ECUbwM3afyk_vWxxuBGrtb7BM3BhO/s1600/code2flow03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="916" data-original-width="1035" height="283" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1AqIP16pDqkYQUblW-ZIMHBbPfvGD6MRbdcVO8seSKInmoDXCDhMmn3bO3TUb3jOH0C5HXCw0jmaPIoC7C0kYzPTahyphenhyphenju6loZISbrsAPbPFuz4p4ECUbwM3afyk_vWxxuBGrtb7BM3BhO/s320/code2flow03.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
自分は今、メインで CakePHP3 を利用しているので、サンプルソースに ブックマークチュートリアル を利用した。<br />
<br />
ブックマークチュートリアル<br />
<a href="https://book.cakephp.org/3.0/ja/tutorials-and-examples/bookmarks/intro.html" target="_blank">https://book.cakephp.org/3.0/ja/tutorials-and-examples/bookmarks/intro.html</a><br />
<br />
Gut Hub<br />
<a href="https://github.com/cakephp/bookmarker-tutorial" target="_blank">https://github.com/cakephp/bookmarker-tutorial</a><br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4toroTiTO2b8zU3Q0WkeDBoM5duNYE2LjRkrtjk3_Lcv4u4FMnXlwRwg5sQYEIb9t_PiQIwzmnVghP_ALzy4_wbkiQfM60peruHtlsIWwgnGkOKg4SUjVrSKmNQtrsi3daY50o3N6xIuV/s1600/code2flow04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="919" data-original-width="1347" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4toroTiTO2b8zU3Q0WkeDBoM5duNYE2LjRkrtjk3_Lcv4u4FMnXlwRwg5sQYEIb9t_PiQIwzmnVghP_ALzy4_wbkiQfM60peruHtlsIWwgnGkOKg4SUjVrSKmNQtrsi3daY50o3N6xIuV/s320/code2flow04.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglo6_uaFasJJ8qgwtA0XLPHh8nGwAXvmdVN4KemgtDQC2mr5L-mZi02bEx9Xfq27KhWB32vGfDn4HJ-0VMJu-OsYJdUVlnAhj0NnTIt_Gcs9mB-gV6ougdQCq4lPfGObgoIzT4ThY_Z4u-/s1600/code2flow05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="889" data-original-width="1600" height="177" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglo6_uaFasJJ8qgwtA0XLPHh8nGwAXvmdVN4KemgtDQC2mr5L-mZi02bEx9Xfq27KhWB32vGfDn4HJ-0VMJu-OsYJdUVlnAhj0NnTIt_Gcs9mB-gV6ougdQCq4lPfGObgoIzT4ThY_Z4u-/s320/code2flow05.png" width="320" /></a></div>
<br />
早速ソースをコピペしてみるとこんな感じに。<br />
ん~ さすがに見やすい! とはならないけど、コメントもオレンジで表示されてて便利だ。<br />
ソースやフロー図のところをマウスオーバーすると対となる箇所にガイドが付いて解りやすい。<br />
<br />
ソースレビューなどを行う時にこれは便利な気がする。<br />
<br />
なかなかこまめに使う場面が自分には無いけども、良いものを見つけたかな。<br />
<br />ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-6357962710003982942018-11-21T19:00:00.000+09:002018-11-21T19:00:13.715+09:00[CakePHP3] 管理画面とそれ意外でCSRF用のCookieName(クッキー名)を変更したい/src/Application.php のデフォルト指定をまず削除。<br />
本当は設定を更新したかったが、方法が見つからず。。<br />
<br />
$middlewareQueue->get(3) からできるかなと思ったけど無理だよね。。<br />
てか名前も指定できるようになってたらいいのに。。<br />
->add した瞬間にこれ実行してるのかな。。<br />
<br />
まーとりあえず以下の方法で対応しました。<br />
<br />
<pre class="php" name="code">public function middleware($middlewareQueue)
{
$middlewareQueue
// Catch any exceptions in the lower layers,
// and make an error page/response
->add(ErrorHandlerMiddleware::class)
// Handle plugin/theme assets like CakePHP normally does.
->add(AssetMiddleware::class)
// Add routing middleware.
// Routes collection cache enabled by default, to disable route caching
// pass null as cacheConfig, example: `new RoutingMiddleware($this)`
// you might want to disable this cache in case your routing is extremely simple
->add(new RoutingMiddleware($this, '_cake_routes_'))
// Add csrf middleware.
->add(new CsrfProtectionMiddleware([
'cookieName' => 'csrf',
'secure' => true,
'httpOnly' => true,
]));
return $middlewareQueue;
}
</pre><br />
上記がデフォルトの内容となりますが、これから<br />
<br />
<pre class="php" name="code">// Add csrf middleware.
->add(new CsrfProtectionMiddleware([
'cookieName' => 'csrf',
'secure' => true,
'httpOnly' => true,
]));
</pre><br />
の部分を削除します。<br />
<br />
<pre class="php" name="code">public function middleware($middlewareQueue)
{
$middlewareQueue
// Catch any exceptions in the lower layers,
// and make an error page/response
->add(ErrorHandlerMiddleware::class)
// Handle plugin/theme assets like CakePHP normally does.
->add(AssetMiddleware::class)
// Add routing middleware.
// Routes collection cache enabled by default, to disable route caching
// pass null as cacheConfig, example: `new RoutingMiddleware($this)`
// you might want to disable this cache in case your routing is extremely simple
->add(new RoutingMiddleware($this, '_cake_routes_'));
return $middlewareQueue;
}
</pre><br />
するとこうなる。<br />
<br />
/src/Application.php で分岐させても良いけど、Pluginのための分岐なので、<br />
分岐はPlugin側でやる事に。<br />
/plugins/Manage/config/bootstrap.php<br />
<br />
ちなみに /plugins/Manage は管理画面用に作成したプラグイン。<br />
<br />
plugins/Manage/config/bootstrap.php を更新。<br />
<br />
以下の分岐を作成していたので、その中で<br />
<br />
<pre class="php" name="code">use Cake\Event\EventManager;
use Cake\Http\Middleware\CsrfProtectionMiddleware;
$cookieName = 'csrf';
if (!empty($_SERVER['REQUEST_URI']) && preg_match('/^\/manage*/', $_SERVER['REQUEST_URI'])) {
$cookieName = 'mcsrf';
}
EventManager::instance()->on(
'Server.buildMiddleware',
function ($event, \Cake\Http\MiddlewareQueue $middlewareQueue) use ($cookieName) {
$middlewareQueue->add(new CsrfProtectionMiddleware([
'cookieName' => $cookieName,
'secure' => true,
'httpOnly' => true,
]));
});
</pre><br />
のように更新すればOK。<br />
<br />
で、確認してたらどうも csrf、mcsrf の両方が登録されてしまう。<br />
<br />
何故なんだろうとハマっていたら DebugBar のAjax?で呼んでいる様子。<br />
なので、 DEBUG false にして確認したら無事 /manage 以下では mcsrf だけが利用されており、 /manage と それ以外 で別のクッキー値を参照するようになりましたとさ。<br />
ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-57765706430298939252018-11-20T08:00:00.000+09:002018-11-21T10:35:46.514+09:00[CakePHP3] セッション(Session)のモデル(テーブル)を通常と特定ディレクトリで分ける方法SessionのストレージをDatabaseとしている事として以下をメモしています。<br />
<br />
管理画面(/manage/*) と その他(/manage/*以外) でセッションデータを保存するDBテーブルを分ける方法。<br />
<br />
管理画面(/manage/*) はプラグイン(Plugin)機能を利用して作成。<br />
<br />
config/bootstrap.php からプラグインを呼び出す。<br />
<br />
<pre class="php" name="code">Plugin::load('Manage', ['bootstrap' => true, 'routes' => true]);
</pre><br />
この時に 'bootstrap' => true を忘れないように。<br />
<br />
plugins/Manage/config/bootstrap.php ファイルを作成し、中身は<br />
<br />
<pre class="php" name="code"><?php
use Cake\Core\Configure;
if (!empty($_SERVER['REQUEST_URI']) && preg_match('/^\/manage*/', $_SERVER['REQUEST_URI'])) {
Configure::write('Session.handler.model','ManageSessions');
Configure::write('Session.cookiePath','/manage/');
}</pre><br />
DBテーブルは分けるので<br />
デフォルトの sessions と manage_sessions を用意する事を想定する。<br />
<br />
<pre class="sql" name="code">CREATE TABLE `sessions` (
`id` char(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
`created` datetime DEFAULT CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+
`modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+
`data` blob DEFAULT NULL, -- for PostgreSQL use bytea instead of blob
`expires` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `manage_sessions` (
`id` char(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
`created` datetime DEFAULT CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+
`modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+
`data` blob DEFAULT NULL, -- for PostgreSQL use bytea instead of blob
`expires` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
</pre>ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-87156278832061236322018-11-07T19:54:00.002+09:002018-11-07T19:57:27.323+09:00[CakePHP3] オリジナルのログイン認証を作成ちょっとややこしい要件が発生した。<br />
<br />
ログインIDが1つでユニークではなく、店舗コード+社員コード という感じで2つのカラムでユニークとなる内容でした。<br />
<br />
DBテーブルはこんな感じとする。<br />
<br />
table: users<br />
columns: id, shop_id, code, password<br />
<br />
table: shops<br />
columns: id, shop_id, code<br />
<br />
そして、リクエスト値はこんな感じとする。<br />
<br />
code, shop_code, password<br />
<br />
<br />
やりたいSQLとしては<br />
<br />
SELECT * <br />
FROM users<br />
INNER JOIN shops ON users.shop_id = shops.id<br />
WHERE users.code = :code AND shops.code = :shop_code;<br />
<br />
で取得してからパスワードチェックするというイメージ。<br />
<br />
<pre class="php" name="code">$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login',
],
'authenticate' => [
'Form' => [
'userModel' => 'Users',
'fields' => [
'username' => 'username',
'password' => 'password',
],
'contain' => 'Shops', // 3.1 で非推奨
'scope' => [], // 3.1 で非推奨
'finder' => 'login',
],
],
'authError' => 'ログインをして、ご利用ください。',
'loginRedirect' => [
'controller' => 'Users',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Users',
'action' => 'login'
]
]);
</pre><br />
って感じでやりたいけど、shop_id を渡せない。。<br />
scope や finder 使ってWHEREに固定した条件を追加する事はできるけど username を追加みたいな事ができない。。<br />
<br />
で仕方ないので、オリジナルの Authenticate クラスを作成する事にする。<br />
<br />
/src/Auth/UserAuthenticate.php<br />
<br />
を作成。<br />
<br />
中身は<br />
<br />
<pre class="php" name="code"><?php
namespace App\Auth;
use Cake\Auth\BaseAuthenticate;
use Cake\Http\ServerRequest;
use Cake\Http\Response;
/**
* Class UserAuthenticate
* @package App\Auth
*/
class UserAuthenticate extends BaseAuthenticate
{
/**
* @param ServerRequest $request
* @param Response $response
*
* @return array|bool|mixed
*/
public function authenticate(ServerRequest $request, Response $response)
{
$userTable = $this->getTableLocator()->get('Users');
$user = $userTable->query()
->contain(['Shops'])
->where([
'Users.code' => $request->getData('code', ''),
'Shops.code' => $request->getData('shop_code', ''),
])
->first();
$password = $request->getData('password', '');
if ($this->passwordHasher()->check($password, $user->password)) {
return $user->toArray();
}
return false;
}
}
</pre><br />
作成したら、<br />
<br />
<pre class="php" name="code">$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login',
],
'authenticate' => [
'Form' => [
'userModel' => 'Users',
'fields' => [
'username' => 'username',
'password' => 'password',
],
'contain' => 'Shops', // 3.1 で非推奨
'scope' => [], // 3.1 で非推奨
'finder' => 'login',
],
],
'authError' => 'ログインをして、ご利用ください。',
'loginRedirect' => [
'controller' => 'Users',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Users',
'action' => 'login'
]
]);
</pre><br />
の記述を<br />
<br />
<pre class="php" name="code">$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login',
],
'authenticate' => [
'User' => [],
],
'authError' => 'ログインをして、ご利用ください。',
'loginRedirect' => [
'controller' => 'Users',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Users',
'action' => 'login'
]
]);
</pre><br />
と修正して完了。ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-14304090715357126382018-11-06T13:30:00.001+09:002018-11-07T19:54:43.982+09:00[CakePHP3] パスワードのバリデート (入力 値チェック)基本的には bake で追加されるメソッド名でのバリデート形式の指定を行うが、正規表現を2回利用したい場合。<br />
<br />
<pre class="php" name="code">$validator
->minLength('password', 8, __('6文字以上を入力してください。'))
->maxLength('password', 50, __('20文字以下を入力してください。'))
->alphaNumeric('password', 'alphaNumeric', __('半角英数字のみ入力可能です。'))
->regex('password', '/[a-zA-Z]+/', __('半角英字を1文字以上利用してください。'))
->regex('password', '/[0-9]+/', __('半角数字を1文字以上利用してください。'))
->requirePresence('password', 'create')
->notEmpty('password');</pre>
<br />
こんな場合は上書きされてしまって、半角英字チェックは動かないので、<br />
こういう場合のみ add で名前を変えて指定するようにして重複を回避する。<br />
<br />
<pre class="php" name="code">$validator
->minLength('password', 8, __('6文字以上を入力してください。'))
->maxLength('password', 50, __('20文字以下を入力してください。'))
->alphaNumeric('password', 'alphaNumeric', __('半角英数字のみ入力可能です。'))
->add('password', [
'inAlpha' => [
'rule' => ['custom', '/[a-zA-Z]+/'],
'message' => __('半角英字を1文字以上利用してください。'),
],
'inNumber' => [
'rule' => ['custom', '/[0-9]+/'],
'message' => __('半角数字を1文字以上利用してください。'),
],
])
->requirePresence('password', 'create')
->notEmpty('password');
$validator
->notEmpty('password_conf')
->sameAs('password_conf', 'password', __('異なるパスワードが入力されています。'))
->requirePresence('password', 'create')
->notEmpty('password');</pre>
<br />
最初からこの記述を基本にすれば良いと思っていたけどやっぱり bake を基本にした方が効率が良い場面が多いので、<br />
必要な場合のみ利用するようにしました。<br />
<br />
regex メソッドの中を見ると解るけど rule としては custom という落とし穴に注意。<br />
<br />ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0tag:blogger.com,1999:blog-512166239666678381.post-24197145992616598092018-11-06T13:30:00.000+09:002018-11-07T19:54:55.416+09:00[CakePHP3] function _setPassword() が思ったタイミングで動いてくれない$entity = $this->Samples->get($id);<br />
$entity->password = '12345678';<br />
$this->save($entity);<br />
<br />
$entity である<br />
<br />
class Sample extends Entity<br />
<br />
に<br />
<br />
protected function _setPassword($password)<br />
<br />
があれば、実行されるのかと思ったいたけどダメでした。。<br />
<br />
$entity->set('password', '12345678');<br />
<br />
でもダメ。。<br />
<br />
で、色々試すとここで実行されました。<br />
<br />
$this->Samples->patchEntity($entity, ['password' => '12345678'])<br />
<br />
何故この場合だけにしているかは謎ですが、とにかく値を更新する時は必ずこれを利用するようにした方が、<br />
バグが減りそうというメモでした。ひさっさんhttp://www.blogger.com/profile/07334111009247481134noreply@blogger.com0