プログラミングノート

プログラミングの備忘録です

Cakephp データベース

はじめてCakephpでデータベースのデータを扱いました。

いろいろと戸惑いましたので、まとめておきます。

 

データベース設定

config/app.phpにデータベース情報を入力します。

 

'Datasources' => [
        'default' => [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Mysql',
            'persistent' => false,
            'host' => ホスト名,
            'port' => ポート番号(必要に応じて),
            'username' => ユーザ名,
            'password' => パスワード,
            'database' => データベース名,
            'encoding' => 'utf8',
            'prefix' => '',

            'timezone' => 'Asia/Tokyo',
            :
        ], 

 

timezoneを「Asia/Tokyo」にする場合

Mysqlホームページから「timezone_posix.sql」をダウンロードし、下のコマンドでダウンロードしたファイルのsqlを実行します。

mysql -u (ユーザー名) mysql -p < (timezone_posix.sql格納ディレクトリ)」

 

1.テーブルクラスの作成

src/Model/Tableディレクトリに作成します。

データベースへのインターフェースとなります。

 

Testsテーブルのテーブルクラスとして、

src/Model/Table/TestsTable.phpを作成します。

 

namespace App\Model\Table;

use Cake\ORM\Table;

class TestsTable extends Table {
}

テーブルオブジェクトは、
クラス名を小文字とアンダースコア区切りにした名前のテーブルを使用することになります。
上の例の場合、テーブルオブジェクトは「Tests」となります。


1-1.テーブル名の指定

テーブルクラス名が上の命名規則に従わない場合、initializeメソッドで使用するテーブルを指定します。
public function initialize(array $config) {

     $this->setTable('tbl_test');

     // 3.4 より前

     $this->table('tbl_test');

}

1-2.主キーの指定

それぞれのテーブルには、id列があり主キーであることになっています。
主キーがid列でない場合、initializeメソッドで主キーを指定します。
public function initialize(array $config) {

     $this->setPrimaryKey('no');

     // 3.4 より前

     $this->primaryKey('no');
}

 

1-3.エンティティクラスの指定

テーブルオブジェクトの命名規則に従ったエンティティクラスを使います。

テーブルクラスが「TestsTable」だとエンティティクラスは「Test」になります。

命名規則に従わない場合は、initializeメソッドでエンティティクラスを指定します。

public function initialize(array $config)

    {

        $this->setEntityClass('App\Model\Entity\Testttest');

        // 3.4 より前
        $this->entityClass('App\Model\Entity\Testttest');
  }

また、エンティティクラスをカスタマイズしたい場合のみ、エンティティクラスを作る必要があります。

 

2.テーブルインスタンスを取得

テーブルにクエリを実行する前に、テーブルインスタンスを作成します。TableRegistryクラスを使って取得します。

 

コントローラーやテーブルのメソッドにて
use Cake\ORM\TableRegistry;
$tests = TableRegistry::get('Tests');

 

3.クエリー実行

クエリを実行するとエンティティオブジェクトとして、それぞれのレコードを取得することができます。

3-1.findメソッド

findメソッドですべてのデータを取得を指定します。(クエリはまだ実行されません)

$query = $tests->find('all');

 

3-2.allメソッド

allメソッドはクエリを実行し結果セットを返します。
$results = $query->all();

 

3-3.結果セットを配列として取得

結果セットがあれば すべての行を配列として取得します。

$data = $results->toArray();

 

3-4.コントローラーからビューへ渡す

$this->set('list', $data);

 

3-5.ビューで出力

foreachなどを使って$listを出力します。

 

 

 参考

データベースの基本

テーブルオブジェクト

エンティティ

データの取り出しと結果セット

 

CSS clearfixについて

 CSSでブロック要素を横に並べた後、floatプロパティの指定を解除しないと、レイアウトが崩れてしまうことがあります。

 floatプロパティの指定を解除するために、clearfixを使うことができます。

 

 今回は、clearfixに関しまして、Nicolas Gallagher さんが考案されました A new micro clearfix hack – Nicolas Gallagher を使わせていただきます。

 

 CSSでブロック要素を横に並べるに関しましては、CSS ブロック要素を横に並べる - プログラミングノート をご参照ください。

 

手順

1.CSSでclearfixを定義します。

2.HTMLでclearfixクラスを呼び出します。

  floatプロパティを指定した要素の外側の要素でclearfixクラスを呼び出します。

 

サンプル

 ▼HTMLファイル

<div class="cf">

    <img src="img-test1.png" />

    <img src="img-test2.png" />

</div>

 

CSSファイル

/* 外側のブロック */

.cf:before,
.cf:after {
    content: " ";
    display: table;
}
.cf:after {
    clear: both;
}

 

/* 内側の画像 */

#test img {

    display: block;

     float:left;

}

 

▼before擬似要素

:before擬似要素は、要素の最初の子要素となる擬似要素を生成します。

 

▼after擬似要素

:after擬似要素は、要素の最後の子要素となる擬似要素を生成します。

 

cfクラスの:after疑似要素にclear:bothを指定することで、cfクラスを指定したdivタグの最後に子要素として<div style="clear:both"></div>を追加したのと同じようになります。

 

参照

::before (:before) - CSS | MDN

::after (:after) - CSS | MDN

floatを解除する手法のclearfix と 次世代のレイアウトの話|Web Design KOJIKA17

(こちらのページが大変役に立ちました。わかりやすかったです。)

CSS ブロック要素を横に並べる

CSSをまとめる機会がありませんでしたので、少しずつまとめていこうと考えています。

今回の目当ては、「インライン要素をブロック要素として扱い、そのブロック要素を横に並べる」です。

 

◆インライン要素とブロック要素

▼インライン要素

 テキスト、imgタグなど

 インライン要素は、左から右へと並びます。

▼ブロック要素

 divタグ、pタグ、h3タグなど

 ブロック要素は、上から下へと並びます。

 

◆インライン要素の整列・改行による空白表示

 HTMLのソースファイルで、インライン要素の中に改行を入ると、余分な空白が表示されます。一方、ブロック要素の中に改行を入れても、余分な空白は表示されません。そのため、インライン要素をブロック要素として扱いたい場合があります。

 

◆インライン要素をブロック要素として扱い、左から右へ並べる

 ▼HTMLファイル

<div id="test">

    <img src="img-test1.png" />

    <img src="img-test2.png" />

</div>

 

CSSファイル

/* 外側のブロック */

#test {

    overflow:hidden;

}

/* 内側の画像 */

#test img {

    display: block;

     float:left;

}

▼displayプロパティとは

 ブロック要素、インライン要素のそれぞれの表示形式(ブロック・インライン)を指定します。

 表示形式を指定することにより、インライン要素をブロック要素として扱うことができます。

 

▼floatプロパティとは

 指定された要素を左または右に寄せて配置します。 その要素の後に続く内容は、その反対側に回り込みます。

 

▼overflowプロパティとは

 ボックスの範囲内に内容が入りきらない場合に、はみ出た部分の表示の仕方を指定します。

 overflowプロパティでvisible以外を指定すると、新しいブロックのコンテキストが確立され、floatを解除するために使えるそうです。(参考:floatを解除する手法のclearfix と 次世代のレイアウトの話|Web Design KOJIKA17

  clearプロパティ(※)を使う方法もあります。

 

※clearプロパティとは

floatプロパティで指定された要素に対する回り込みを解除します。

<使用例>

.clear {

    clear:both; /* 左寄せまたは右寄せされた全ての要素に対する回り込みを解除 */

}

 

参照

overflow-スタイルシートリファレンス

display-スタイルシートリファレンス

float-スタイルシートリファレンス

floatを解除する手法のclearfix と 次世代のレイアウトの話|Web Design KOJIKA17

 

PHP CSS 表示枠からはみ出した文字列を省略して表示する

表示枠からはみ出した文字列を省略して表示します。文字列は全角文字と半角文字が混在しているとします。

(たまに同じような処理を書きますが、いつもいつも忘れてしまいます。今回はメモを残します。)

 

1.使用するPHPのマルチバイト文字列関数

下の2つの関数のパラメータで、エンコーディングを指定することが大切です。

 

▼mb_strwidth

「文字列 str の幅を返します。マルチバイト文字は、通常はシングルバイト文字の倍の幅となります。」(PHP: mb_strwidth - Manual より引用)

 

▼mb_substr

「文字数に基づきマルチバイト対応の substr() 処理を行います。位置は、 str の始めから数えられます。 最初の文字の位置は 0、2 番目の文字の位置は 1、といったようになります。」(PHP: mb_substr - Manual より引用)

 

 

2.手順

  1. 表示枠(divタグ内)に最大何文字のシングルバイト文字が表示できるか調べます。
  2. シングルバイト文字の最大文字数を文字列の最大幅とします。
  3. 文字列の幅が最大幅より大きい場合、後ろから1文字削ります。
  4. 1文字削った文字列の幅を最大幅と比較します。
  5. 文字列の幅が最大幅より小さくなるまで繰り返します。
  6. 最後に省略マーク「...」をつけます。

 

3.サンプルソース

下の例では、$text の最大幅を12としています。

$n = 0;
while (mb_strwidth($text, mb_internal_encoding()) > 12) {
    $label_text = mb_substr($text, 0, 12-$n, mb_internal_encoding());
    $n++;

}
if ($n > 0) {
    $text .= '...';
}

 

4.cssで

CSSで、表示枠からはみだした文字列を省略して表示することができます。

表示枠が1行の場合に使えます。

 

手順

表示枠のブロック要素(divタグ、pタグなど)に下のプロパティを付けます。

▼ width 表示枠の幅
▼ overflow "visible" 以外のものを指定
▼ white-space: nowrap;

(IE, WebKit (Safari, Chrome), Firefox 7, Opera 11)
▼ text-overflow: ellipsis;

(Opera 9-10)
-o-text-overflow: ellipsis;

div .test {
width: 60%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
}

 

参照

PHP: マルチバイト文字列 関数 - Manual

text-overflow - CSS | MDN

CSSではみ出した文字を省略する「text-overflow: ellipsis;」がいつの間にかPCでも使えるようになってた! - tacamy.blog

初心者向け cakephp cakephpフレームワークの導入 第1回

Windowsマシンにcakephp v4.3.2を導入します。

 

1.プロジェクトを作成

Composerと使ってCakePHPアプリケーションのプロジェクトを作成します。

コマンドプロンプトで下のコマンドを実行すると、コマンドを実行したディレクトリに、プロジェクト名のディレクトリが作成されます。(ここで作成しましたプロジェクト名のディレクトリをプロジェクトディレクトリと呼びます。)

php composer.phar create-project --prefer-dist cakephp/app プロジェクト名」

 

補足

1.cakephpは、php拡張モジュールのopensslとmbstringとintlを必要とします。

  • 「The openssl extension is required for SSL/TLS protection but is not availab
     le.」が表示された場合は、php.iniで、extension=extension=php_openssl.dllの行頭の「;」を削除し、opensslを有効にします。
  • 「the requested PHP extension intl is missing from your system.」が表示された場合は、php.iniで、extension=php_intl.dllの行頭の「;」を削除し、intlを有効にします。
  • 「the requested PHP extension mbstring is missing from your system.」が表示された場合は、php.iniで、extension=php_mbstring.dllの行頭の「;」を削除し、mbstringを有効にします。

 2.Set Folder Permissionsの設定

上のコマンドを実行すると、途中で「Set Folder Permissions ? (Default to Y) [Y,n]? 」が表示されましたので、「Y」と入力しました。その後「Updated Security.salt value in config/app.php」が表示されました。

 

2.cakephpコンソールを起動

  1. コマンドプロンプトで、プロジェクトディレクトリに移動して、コマンド「php bin/cake.php」を実行します。
  2. 正常に起動した場合、「Welcome to CakePHP v3.4.2 Console」が表示されます。

 

3.cakephpビルトインサーバを起動

  1. コマンドプロンプトで、カレントディレクトリをプロジェクト名のフォルダに移動して、コマンド「php bin/cake.php server」を実行します。
  2. 正常に起動した場合、「Welcome to CakePHP v3.4.2 Console」が表示されます。
  3. ブラウザを開き「http://localhost:8765/」にアクセスすると、cakephpのページが表示されます。

 

補足

  1. ビルトインサーバは開発サーバとして使用し公開しません。
  2. ホスト名やポートを指定する場合は、下の例のようなコマンドを実行します。すると「http://127.0.0.1:5973」でアクセスできるようになります。
(例)「php bin/cake.php server -H 127.0.0.1 -p 5673」

 

4.Apachecakephpを使う

1.URLリライティングができるように設定

cakephpはデフォルトでmod_writeを使用する設定になっています。そのためmod_writeが使用できるようにApacheを設定します。

 

1-1.mod_rewrite がロードされるように設定

Apachehttpd.confの下の行の先頭の「#」を削除します。

LoadModule rewrite_module modules/mod_rewrite.so

 

1-2..htaccessで設定の上書きができるように設定

プロジェクトを使用するドキュメントルートディレクトリの設定を、.htaccessで上書きできるように、 Apachehttpd.confで「AllowOverride All」を設定します。

(例)

<Directory />

  Options FollowSymLinks

  AllowOverride All

# Order deny,allow

# Deny from all

</Directory>

 

1-3.Apachehttpd.confを変更後、Apacheを再起動

 

 2..htaccessの設定

2-1.プロジェクトディレクトリの.htaccess

<IfModule mod_rewrite.c>

 RewriteEngine on

 RewriteRule ^$ webroot/ [L]

 RewriteRule (.*) webroot/$1 [L]

</IfModule>

 

2-2.ドキュメントルートディレクトリの.htaccess

<IfModule mot_write.c>

 RewriteEngine On

 RewriteCond %{REQUEST_FILENAME} !-f

 RewriteRule ^ index.php [L]

</IfModule>

 


プロジェクトディレクトリのindex.phpにアクセスします。
cakephpページが表示されます。

 

参考

https://book.cakephp.org/3.0/ja/

インストール

Windowsマシンに Smarty 3.1.30 を導入

 SmartyPHPのテンプレートエンジンです。Smartyを使うと画面表示処理とデータ操作処理を分けて記述することができます。これによりソースファイルの可読性が向上すると思います。

 

1.ダウンロード

  1. Download | Smarty の「Download」>「Smarty 3 latest」にある「3.1.30」リンクをクリックします。
  2. GitHubのページが表示されますので、「Release 3.1.30」>「Download」にある「source code(zip)」リンクをクリックします。
  3. Smarty-3.1.30.zip」を開くウィンドウが表示されますので、ファイルを保存するを選択して、「OK」ボタンをクリックします。

 

2.インストール

  1. ダウンロードしたzipファイルを解凍します。
  2. libs ディレクトリを作成します。
  3. 解凍してできた「Smarty-3.1.30」をlibs ディレクトリに配置します。

 例: c:\webroot\libs\Smarty-v.e.r\

 (例の絶対パスは、利用環境に合わせて調整してください。)

 

 

3.Smarty.class.php ファイルの場所を指定

アプリケーションがSmarty.class.php ファイルを見つられるように設定します。

 

その1 PHP定数SMARTY_DIRに定義

PHPの定数「SMARTY_DIR」に、Smartylibsディレクトリへの絶対パスを指定します。絶対パスを指定するとき、最後に / を含める必要があります。

 例:define('SMARTY_DIR', 'C:\webroot\libs\smarty-3.1.30\libs/');

 (例の絶対パスは、利用環境に合わせて調整してください。)

 

その2 php.iniのinclude_pathに定義

php.iniのinclude_pathに、Smartylibs ディレクトリへの絶対パスを指定します。絶対パスを指定するとき、最後に \ を含める必要があります。

 例:include_path = ".;c:\php\includes;c:\webroot\libs\Smarty-3.1.30\libs\"

 (例の絶対パスは、利用環境に合わせて調整してください。)

その3 PHPスクリプトの ini_set() に定義

PHPスクリプトにini_set()を使用して、include_pathでSmartylibs ディレクトリへの絶対パスを指定します。絶対パスを指定するとき、最後に \ を含める必要があります。

 例:ini_set('include_path', 'c:\webroot\libs\Smarty-3.1.30\libs\');

 (例の絶対パスは、利用環境に合わせて調整してください。)

 


4.Smartyディレクトリを 作成

templatesディレクトリtemplates_cディレクトリconfigsディレクトリ、cacheディレクトリを作成します。

  • Smartyディレクトリは Smarty ライブラリによってのみアクセスされますので、ドキュメントルートの ディレクトリを作成することが推奨されています。
  • ディレクトリの名前は、Smarty クラスのプロパティ $template_dir、$compile_dir、$cofig_dir、$cache_dirに定義して変更することができます。

 

 

 5.テンプレートの作成

テンプレートファイル (拡張子が.tplのファイル) を作成し、template_dirディレクトに配置します。

(テンプレートファイルの文字コードをuft8としました。)

 

▼テンプレートファイルの内容

  • 画面に出力する内容(HTMLなど)を記述します。
  • 「{変数名}」と記述すると、変数値を表示します。

 例:「こんにちは、{$name}さん」

 

 

6.index.phpの作成

ドキュメントルートの下に任意のディレクトリを作成し、そのディレクトリにindex.php を配置します。

 

▼index.phpの内容

下の例は利用環境に合わせて調整してください。

 

// 1.Smarty.class.phpの読み込み

require_once(SMARTY_DIR . 'Smarty.class.php');

 

// 2.Smartyオブジェクトの生成

$smarty = new Smarty();

// 3.(任意)SmartyディレクトリをSmartyクラスのプロパティに設定
$smarty->template_dir = "c:/test/templates/";
$smarty->compile_dir  = "c:/test/templates_c/";
$smarty->config_dir   = "c:/test/configs/";
$smarty->cache_dir    = "c:/test/cache/";

 

// 4.(任意)変数に値の割り当て
$smarty->assign('name','テスト');

 

// 5.テンプレートの指定
$smarty->display('index.tpl');

 

7.テンプレート表示

 index.phpのURLにアクセスすると、テンプレートの内容が表示されます。

 

 

参照

PHP Template Engine | Smarty

Smarty3 マニュアル | Smarty

Google APIをPHPウェブアプリケーションから呼び出す(APIキー) 第7回

作成済みのAPIキーを使って、公開されているGoogle カレンダーから祝日のデータを取得します。

 

APIキーの作成については、Google APIを使用するための設定(APIキーの作成) 第3回 - プログラミングノート をご覧ください。

 

概要

  リクエストURLにデータ取得先のカレンダーIDを埋め込み、パラメータでAPIキーとデータの抽出条件を指定します。

 作成したリクエストURLとパラメータを、PHPのfile_get_contentsメソッドの引数に指定し実行すると、カレンダーのデータ(JSON形式)を取得することができます。

 

手順

  1. リクエストURLを作成
  2. 抽出条件のパラメータを作成
  3. URLとパラメータを指定してカレンダーデータを取得
  4. 取得したJSON形式のカレンダーデータをデコード

 

1.リクエストURLを作成

 下のURLで、Google カレンダーからイベントデータを取得します。

https://www.googleapis.com/calendar/v3/calendars/(カレンダーID)/events

このURLはEvents:listページの「Request」>「HTTP Request」に書かれています。

 

 上のURLに、データ取得先のカレンダーのカレンダーIDを埋め込みます。

日本の祝日カレンダーのカレンダーIDは、「japanese__ja@holiday.calendar.google.com」です。

 

補足

 リクエストURLは、API Reference  |  Google Calendar API  |  Google Developers のメソッドページに書かれています。それぞれのメソッドページの「Request」>「HTTP Request」をご覧ください。

 

 日本の祝日カレンダーのカレンダーIDを誤って、「ja.japanese#holiday@group.v.calendar.google.com」と指定したとき、「401 Login Required」エラーが発生しました。

 

 2.抽出条件のパラメータを作成

 Events:list の主なパラメータについて書きます。

 詳しくは、Events: list  |  Google Calendar API  |  Google Developers のParametersをご覧ください。

 

APIキー(必須)

 key = APIコンソールで作成したAPIキー

 

▼並び順(任意)

 orderBy=startTime 

 startTime(開始日時) または updated(更新日時)が指定できます。

 startTimeを指定する場合は、singleEventsがtrueである必要があります。

 

▼シングルイベント(任意)

 singleEvents=true

 繰り返しイベントの抽出に関して指定します。

 初期値はfalseです。

 

タイムゾーン(任意)

 timeZone=Asia/Tokyo

 指定がない場合は、カレンダーのタイムゾーンが使われます。

 

▼取得開始日時(任意)

 timeMin=2017-01-01T00:00:00Z

 RFC3339形式で指定します。

 

▼取得終了日時(任意)

 timeMax=2017-12-031T00:00:00Z

 RFC3339形式で指定します。

 

▼1ページの最大件数(任意)

 maxResults=10

 初期値は250件です。

 2500件以下で指定します。

 

補足

 ブラウザのアドレスバーにURLとパラメータを入力しアクセスしたとき、パラメータの指定に誤りがあれば、エラーメッセージが表示されます。

 

3.URLとパラメータを指定してカレンダーデータを取得

PHPのfile_get_contentsメソッドの引数でURLとパラメータを指定し、file_get_contentsメソッドを実行します。
$results = file_get_contents($url);

 

4.取得したJSONデータをデコード

PHPjson_decodeメソッドを使って取得したカレンダーデータ(JSON形式)をデコードします。
$json = json_decode($results, true);

 

注意

 APIキーを安全に保管するため、ソースファイルとは別のファイルにAPIキーを記述し、APIキーを記述したファイルはソースツリーの外に保管することが推奨されています。

 

記事一覧

第1回 Google APIを使用するための設定(プロジェクトの作成・使用するAPIの設定)

第2回 Google APIを使用するための設定(認証情報の登録)

第3回 Google APIを使用するための設定(APIキーの作成)

第4回 Google APIをPHPウェブアプリケーションから呼び出す

第5回 Google APIをPHPウェブアプリケーションから呼び出す(サービスアカウント)

第6回 Google APIへの問い合わせ状況と割り当てを確認する方法

第7回 Google APIPHPウェブアプリケーションから呼び出す(APIキー)

 

参照

Setting up API keys - API Console Help

Best practices for securely using API keys - API Console Help