読者です 読者をやめる 読者になる 読者になる

プログラミングノート

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

トップページ

最新記事

homework.hatenablog.jp

おすすめ記事

homework.hatenablog.jp

記事紹介

 

Git

homework.hatenablog.jp

homework.hatenablog.jp

homework.hatenablog.jp

homework.hatenablog.jp

homework.hatenablog.jp

homework.hatenablog.jp

 

Googleドキュメント

homework.hatenablog.jp

homework.hatenablog.jp

homework.hatenablog.jp

 

Google API

homework.hatenablog.jp

homework.hatenablog.jp

homework.hatenablog.jp

homework.hatenablog.jp

homework.hatenablog.jp

 

Webアプリケーション開発環境

homework.hatenablog.jp

homework.hatenablog.jp

 

 

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回

Google API

作成済みの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

PHP Data Object (PDO)でトランザクションを利用する 第3回

PDO

 PHP Data Object (PDO)を使ってデータベースのデータを操作します。データベースのデータの整合性を保つため、トランザクションを利用します。

 PDOは、PHPの拡張モジュールでデータベースを操作するためのインタフェースです。PDOを使ってトランザクションを利用するには、トランザクションをサポートしているデータベースが必要です。

 

トランザクション

 トランザクションは、データベースのデータの整合性を保つための方法です。

 トランザクション内でデータを変更するためのSQLを実行します。その後、変更の確定(コミット)を行い、データベースに変更を反映させます。

 トランザクション開始から変更確定までの間、他の接続は、確定前の変更結果を見ることができません。また、確定前のデータを変更することができません。

 このようにして、データベースに矛盾したデータが生成されないように、他の接続からデータを守ります。

 

補足

 変更の確定前であれば、データの変更をデータベースに反映させず、取り消すこと(ロールバック)ができます。

 

自動コミットモード

  自動コミットモードは、データベース固有のPDOドライバがトランザクションをサポートしているか否かにより、トランザクションを利用するか否かが決まるモードです。

 PDOドライバはデータベース固有で、データベースごとに異なります。

 使用するPDOドライバがトランザクションをサポートしていない場合は、トランザクションを使用せずに、SQLが実行されます。

 使用するPDOドライバがトランザクションをサポートしている場合は、暗黙的なトランザクションで、SQLが実行されます。

 最初にPDOでデータベースに接続した時、自動コミットモードの接続となります。

 

事前準備

  1. PHPをインストールします。
  2. トランザクションをサポートしているデータベースをインストールします。
  3. 2でインストールしたデータベースのPDOドライバが使えるように、php.iniファイルを設定します。

php.iniファイルの設定に関しては PHP Data Object(PDO)拡張モジュールの導入とPDOインスタンスの作成 第1回 - プログラミングノート をご覧ください。

 

手順

1.トランザクションを開始する

2.データを変更するためSQLを実行する

3.変更の確定・取消を行う

 

1.トランザクションを開始する

 PDOクラスのbeginTransactionメソッドを使って、トランザクションを開始します。

 データベース固有のPDOドライバがトランザクションをサポートしていない場合、PDOExceptionが発生します。

 MySQL データベースの MyISAM テーブルではトランザクションを利用できませんが、エラーが発生することなく、beginTransaction()は True を返します。これは、PDOがデータベース固有のPDOドライバで、トランザクションのサポートをチェックしているためです。

 詳しくは、PHP: PDO::beginTransaction - Manual をご覧ください。

 

2.データを変更するためSQLを実行する

 トランザクションの開始後、クエリ実行、登録・更新・削除のSQLを実行します。

 例えば、クエリを実行してデータを抽出し、そのデータをもとにデータを更新するなどの処理を行います。
 

3.変更の確定・取消を行う

 最初に、トランザクション内で行った処理が成功か失敗を判定します。

 成功の場合は、PDOクラスのcommitメソッドを使って、変更の確定(コミット)を行います。コミットを行うと、トランザクション内で行ったすべての変更がデータベースに反映されます。

 失敗の場合は、PDOクラスのrollbackメソッドを使って、変更の取消(ロールバック)を行います。ロールバックを行うと、トランザクション内で行ったすべての変更が取り消され、データベースに反映されません。

 詳しくは、PHP: PDO::commit - Manual PHP: PDO::rollBack - Manual をご覧ください。 

 

補足

トランザクション内の変更に対して確定・取消が行われずに、スクリプトが終了したり接続が閉じられる場合、PDOはそのトランザクション内の変更の取消(ロールバック)をします。

 

注意

MySQLなど一部データベースでは、トランザクション内でデータベース定義SQL

(CREATE TABLE など)が実行されると、自動で確定(コミット)されます。

 

try {
  $dbh->beginTransaction(); // トランザクションの開始

  // トランザクション内で、クエリ実行、登録・更新・削除のSQL実行
 
$dbh->commit(); // 変更の確定
} catch (
Exception $e) { 
  
$dbh->rollBack(); // 変更の取消 
}

 

 

記事一覧

第1回 PHP Data Object(PDO)拡張モジュールの導入とPDOインスタンスの作成

第2回 PHP Data Object (PDO)でプリペアステートメントを使う

第3回 PHP Data Object (PDO)でトランザクションを利用する

 

参照

PHP: トランザクションおよび自動コミット - Manual

 

PHP Data Object (PDO)でプリペアステートメントを使う 第2回

PDO

 PHP Data Object (PDO)を用いて、プリペアステートメントを使います。

 プリペアステートメントを使ってSQLを作成しデータベース操作を行うと、セキュリティの向上や処理の効率化が期待できます。

 

1.プリペアステートメントを使うメリット

1-1.セキュリティの向上

 Webページで不正な入力を行い想定外のSQLを生成させて、データベースを不正に操作する攻撃(SQLインジェクション)を防ぐ効果があります。

1-2.処理の効率化

 SQLを実行する時、SQLの解析、コンパイル、最適化といった準備が行われます。プリペアステートメントを使ってSQLを作成すると、1回目はこれらの準備を行いますが、2回目以降はこれらの準備を省きます。(SQL文に埋め込む変数を指定することで、SQL文の値を変えることができます。)

 

 

2.プリペアステートメントの使用

 PDOのプリペアステートメントを使用します。PDOの導入とPDOインスタンスの作成については、PHP Data Object(PDO)拡張モジュールの導入とPDOインスタンスの作成 第1回 - プログラミングノート をご覧ください。

 

2-1.PDOインスタンスの作成

 データベースのDNS、ユーザー、パスワードをPDOクラスのコンストラクタに渡して、PDOインスタンスを作成します。

 データベースのDNS、ユーザー、パスワードはご利用環境に合わせてください。

コンストラクタの詳細は PHP: PDO::__construct - Manual をご覧ください。

 

$dsn = 'mysql:dbname=testdb;host=testhost';
$user = 'testuser';
$password = 'testpass';
$dbh = new PDO($dsn, $user, $password);

 

 

2-2.SQL文の指定

 prepareメソッドを使いSQL文を指定します。SQL文は変数を埋め込む箇所にプレースホルダを挿入し作成します。

 プレースホルダとは、SQL文の変数を埋め込む箇所を示すマークです。後から、プレースホルダに変数を関連づける必要があります。

 プレースホルダには、名前つきプレースホルダと「?」プレースホルダの2種類があります。

 prepareメソッドの詳細は PHP: PDO::prepare - Manua をご覧ください。

 

名前つきプレースホルダ

 「VALUES」の後の「:no」と「:name」がプレースホルダとなります。

$stmt = $dbh->prepare("INSERT INTO TEST (no, name) VALUES (:no, :name)");

 

「?」プレースホルダ

 「VALUES」の後の「?」2つがプレースホルダとなります。

$stmt = $dbh->prepare("INSERT INTO TEST (no, name) VALUES (?, ?)");

 

 

2-3.プレースホルダと変数を関連付ける

 どのプレースホルダにどの変数の値を入れるのか指定するため、bindParamメソッドを使って、プレースホルダと変数を関連付けます。

 bindParamメソッドの詳細は PHP: PDOStatement::bindParam - Manual をご覧ください。

 

名前つきプレースホルダを使用した場合

 bindParamメソッドの引数は、1つ目が「'」で囲んだプレースホルダの名前(例:':no')で、2つ目が変数となります。

$stmt->bindParam(':no', $no);

$stmt->bindParam(':name', $name);

 

「?」プレースホルダを使用した場合

 bindParamメソッドの引数は、1つ目がプレースホルダの順番で、2つ目が変数となります。

 1つ目のプレースホルダの順番と2つ目の変数がずれないように注意します。

$stmt->bindParam(1, $no);

$stmt->bindParam(2, $name);

 

 

2-4.SQLの実行

 executeメソッドを使ってSQLを実行します。

 executeメソッドの詳細は PHP: PDOStatement::execute - Manual をご覧ください。

 

$stmt->execute();

 

 また、executeメソッドの引数でプレースホルダと変数の関連付けを行い、SQLを実行することもできます。

 executeメソッドの引数は配列である必要があります。配列の要素の1つ目から順にプレースホルダに関連付けられます。

$stmt = $dbh->prepare("SELECT * FROM TEST where name = ?");

$stmt->execute(array($name));

 

 

2-5.抽出結果を取得

 クエリで抽出した結果を1行ずつ取得するにはfetchメソッドを使います。

fetchメソッドの詳細は PHP: PDOStatement::fetch - Manual をご覧ください。

 

while ($row = $stmt->fetch()) {
    print_r($row);
}

 

 

補足

 WHERE句にLIKEと%を含むSQL文を作成する場合、SQL文のWHERE句は「WHERE xxxxx LIKE ?」となります。

 プレースホルダには変数を関連付けないといけません。そのため、変数と「%」を連結した値を変数に代入し、その後、代入した変数をプレースホルダと関連付けます。

 

$stmt = $dbh->prepare("SELECT * FROM TEST where name LIKE ?");

$keyword_name = "%".$name."%";

$stmt->bindParam(1, $keyword_name);

$stmt->execute();

 

 

記事一覧

第1回 PHP Data Object(PDO)拡張モジュールの導入とPDOインスタンスの作成

第2回 PHP Data Object (PDO)でプリペアステートメントを使う

第3回 PHP Data Object(PDO)でトランザクションを利用する

 

 

参考

PHP: プリペアドステートメントおよびストアドプロシージャ - Manual