SQLの窓

2017年04月15日


PHP の関数で規定されているキャッシュコントロールの無効 : session_cache_limiter( 'nocache' )

session_start() を実行しないと有効にならないので、セッションが必要無い場合は header を直書きすればいいと思いますが、セッションを有効にしても損は無いので以下のようにとておくと簡単です。

session_cache_limiter
<?php
session_cache_limiter('nocache');
session_start();
?>


header を直接書くと以下のようになります
<?php
header( "Expires: Thu, 19 Nov 1981 08:52:00 GMT" );
header( "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0" );
header( "Pragma: no-cache" );
?>

▼ 以下は、Cache-Control の値についての解説です
HTTP キャッシュ
「no-store」はもっと単純です。返されたレスポンスのバージョンにかかわらず、ブラウザのキャッシュやすべての中間キャッシュはそのレスポンスを一切格納できません。たとえば、個人の機密データや銀行データが含まれているレスポンスなどです。ユーザーがこのアセットをリクエストするたびに、リクエストがサーバーに送信され、完全なレスポンスが毎回ダウンロードされます。
※ 一部引用
posted by lightbox at 2017-04-15 15:02 | Comment(0) | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2017年04月11日


PHP : ${'日本語表示'} という可変変数と、${hello . "X"} という連結可変変数

※ hello という定数が無いという通知が出る環境では、error_reporting 関数で抑制できます
※ 結果が PHP の認識できる文字列であればいいので、"hello" . (10 * 4) もありです。
※ PHP の可変変数

以下のコードは全て正しく動作しますが、最後の連想配列を除いて、変数名を可変で表現する可変変数のサンプルです。

PHP が変数として許している文字は制限がありますので、$2011/07/08 と言う変数はエラーになりますが、${'2011/07/08'} という変数は正しく動作します。
JavaScript で var a = {}; a["2017/01/01"] = "001"; として、参照が a.2017/01/01 ができないのと同様で、JSON を PHP 内で変換して使う時にも意識するといいです
つまり、日本語を変数として使いたい場合は、${'日本語表示'} という書き方で確実に使える事になります。 日本語は、その構成文字が「キャラクタセット」によって変わるので、どの文字が実際 PHP で変数として使えるかどうかは、はっきり言えませんが、実際使えるものもたくさんあります。しかし、確実では無いので${'日本語表示'}という表現は選択肢のうちの一つです。 また、PHP のマニュアルの投稿内容にありましたが、${文字 . "文字列"} という書き方が何故か正常に動作します。
<?php
error_reporting(E_ALL ^ E_NOTICE);

// $a に値をセット
$a = 'hello';

// $a を変数名として利用
${$a} = 'world (1)';

// world (1) が表示されます
print $hello . "<br>";


// ★ もう少し複雑な場合(1)

// $b[1] に値をセット
$b[1] = 'hello';

// $b[1] を変数名として利用
${$b[1]} = 'world (2)';

// world (2) が表示されます
print $hello . "<br>";


// ★ もう少し複雑な場合(2)

// $c に値をセット
$c = 'hello2';

// $c を変数名として利用
${$c}[1] = 'world (3)';

// world (3) が表示されます
print $hello2[1] . "<br>";


// ★ 文字列の接続

${hello . "X"} = 'world (4)';

// world (4) が表示されます
print $helloX . "<br>";


// ★ エラーにならない特殊な変数
// ※ $2011/07/08 という変数は作れません

$d = '2011/07/08';
${$d} = 'world (5)';

// world (5) が表示されます
print ${'2011/07/08'} . "<br>";


// ★ 日本語変数
// キャラクタセットによって、PHPが使える文字なら
// $日本語表示 でもエラーにはなりません 

$e = '日本語表示';
${$e} = 'world (6)';

// world (6) が表示されます
print ${'日本語表示'} . "<br>";

${'日本語表示'} .= " 追加OK";
print $$e . "<br>";

// ★ 連想配列による日本語表現

$f['日本語表示'] = 'world (7)';

// world (7) が表示されます
print $f['日本語表示'] . "<br>";

?> 




posted by lightbox at 2017-04-11 15:22 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2017年02月28日


cp932 の SQLServer に対して、PHP の ODBC 関数に対して UTF8 変換で地道に対応し、特殊なUncode文字は、HTML 数値エンティティで保存する。

Microsoft のドライバで自動的に対応させる方法もありますが、かつて切り替え時期に Microsoft 純正を使ってえらい目にあった経緯があり、全て SHIFT_JIS で現在も運用していますが、jQuery の ajax を使用するに当たってどうしても通信部分は UTF-8 になるため、以下のようにしています。

また、国際化のためどうしても SHIFT_JIS に無い文字に対応する必要も出てきました。

まず、以下のソースは SHIFT_JIS で書かれており、mb_convert_encoding が不可欠なので、先頭で内部コードを UTF-8 に設定しています。
<?php
mb_internal_encoding("UTF-8");
require_once( "../db.php" );

// *************************************
// キャラクタセット
// *************************************
header( "Content-Type: application/json; charset=utf-8" );
// *************************************
// キャッシュ無効
// *************************************
session_cache_limiter('nocache');
session_start();

// ajax の為、入力値は UTF-8
foreach( $_POST as $Key => $Value ) {

	if ( $Key == "name" || $Key == "name2" ) {
		$_POST[$Key] = mb_encode_numericentity( $Value, array(0x0, 0x2FFFF, 0, 0xFFFFF) );
	}
	else {
		$_POST[$Key] = mb_convert_encoding( $Value, "cp932", "UTF-8" );
	}
}

// *************************************
// 処理
// *************************************
$SQL = new DBSS( $COMMON_DB, "sa" );

$query = "update SQLServerのテーブル set";
$query .= " 姓 = '{$_POST["name"]}'";
$query .= " ,名 = '{$_POST["name2"]}'";

$query .= " where 番号 = {$_POST["no"]}";


$_POST['query'] = $query;

$ret = $SQL->Execute( $query );

if ( $ret === false ) {
	$_POST['status'] = 0;
}
else {
	$_POST['status'] = 1;
}


// *************************************
// PHP の結果を result キーで
// JSON としてブラウザに返す
// *************************************
foreach( $_POST as $Key => $Value ) {
	$_POST[$Key] = mb_convert_encoding( $Value, "UTF-8", "cp932" );
}
print json_encode($_POST);

?>

この処理は、jQuery から呼び出された更新処理です。name と name2 に、HTML 数値エンティティに変換すべき文字列が入っています。全て変換する必要は無いのですが、SHIFT_JIS と Unicode の云々の詳細を省く為に array(0x0, 0x2FFFF, 0, 0xFFFFF) となっています。

0x0 〜 0x2FFFF : オフセット 0、マスク 0xFFFFF

ここでは、サンプルとしてのコードなので、入力文字列が name と name2 しかないので、mb_convert_encoding( $Value, "cp932", "UTF-8" ) が実行されませんが、一般的な SHIFT_JIS の文字列のデータに対して必要です。

print する場合は、jQuery の中に戻るので、再度 UTF-8 に変換する必要があります。

以下は同様の処理で、読み出すだけのコードです。
<?php
mb_internal_encoding("UTF-8");
require_once( "../db.php" );

// *************************************
// キャラクタセット
// *************************************
header( "Content-Type: application/json; charset=utf-8" );
// *************************************
// キャッシュ無効
// *************************************
session_cache_limiter('nocache');
session_start();

// ajax の為、入力値は UTF-8
foreach( $_POST as $Key => $Value ) {
	$_POST[$Key] = mb_convert_encoding( $Value, "cp932", "UTF-8" );
}

// *************************************
// 処理
// *************************************
$SQL = new DBSS( $COMMON_DB, "sa" );

$query = "select * from SQLServerのテーブル where 番号 = {$_POST["no"]}";
$column = $SQL->QueryEx( $query );

if ( $column ) {

	foreach( $column as $Key => $Value ) {
		$fld = mb_convert_encoding( $Key, "UTF-8", "cp932" );

		if ( $Key == "姓" || $Key == "名" ) {
			$column2[$fld] = mb_decode_numericentity( $Value, array(0x0, 0x2FFFF, 0, 0xFFFFF) );
		}
		else {
			$column2[$fld] = mb_convert_encoding( $Value, "UTF-8", "cp932" );
		}

	}


	$_POST['exist'] = 1;
}
else {
	$_POST['exist'] = 0;
}


// *************************************
// PHP の結果を result キーで
// JSON としてブラウザに返す
// *************************************
foreach( $_POST as $Key => $Value ) {
	$_POST[$Key] = mb_convert_encoding( $Value, "UTF-8", "cp932" );
}
$_POST['data'] = $column2;
print json_encode($_POST);

file_put_contents("debug.log", print_r($_POST, true));

?>

ここで、一番重要なのは、HTML 数値エンティティ を mb_decode_numericentity で元の文字列に戻す事です。これでブラウザから貼り付けれる文字であれば、DB には HTML 数値エンティティ で保存されて、表示すると元に戻るはずです。

※ ただ、DB 側の列の文字列サイズがかなり大きくなります。

ちなみに、Excel への変換は、IE を使用してブラウザからの Excel オフジェクト呼び出しでまかなっています。
▼ 
IE11 で VBScript を使う場合の注意事項 ( 古い社内アプリ移行時必見 )


posted by lightbox at 2017-02-28 22:03 | Comment(0) | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2016年06月28日


PHP のファイルアップロードで画像ファイルを限定で行う為のテンプレートと注意事項と解説

Webアプリのサンプルソースとして基本的な事

● キャラクタセットは utf-8 で、http ヘッダも meta 要素も統一してどちらも記述します
● イザと言う時の為に、jquery のライブラリは読み込んでいます。これは、デベロッパーツールのコンソールで何かしたい時にとても有効です。
● スマホ表示用として、meta 要素の viewport は記述しておきます。
● デバッグ表示は、print_r( $変数, true ) を pre 要素で挟んで表示します
● コメントを好きな場所に書いて、結果が消えるように <?php // コメントの記述 ?> というような記述方法を使っています。

ブラウザキャッシュについて

PHP の関数として用意されている session_cache_limiter('nocache'); を使用しています。ただ、これを使うには、セッションを開始する必要があります。ここでは、セッションは使用していませんが、いつでも使用できるようにしても損はありません。

ファイルのアップロード処理として2アクションを使用

画面には、アップロードする為の UI に記述を限定しています。実装としてはHTML でも良いのですが、後々の事や、キャッシュやキャラクタセット、そして PHP コメントの使用を考えれば、PHP で記述するほうが得です。但し、機能としてはほぼ、クライアントの処理のみに限定しています。

さらに、IFRAME を使用して、結果によって画面を崩さないようにしています。実用的に考えた場合、この画面自体を IFRAME にして、自由に開いたり閉じたりする UI を想定しています。その場合、3階層のウインドウになりますが、同一ドメインであれば相互の処理は jQuery で容易に行えるので、現在デバッグ情報を表示している最下層の IFRAME で jQuery を出力すれば、フォーム画面の表示調整は容易です。

2アクション目の、upload.php の役目も、ファイルの処理のみに限定でき、メンテナンスや拡張も容易になるはずです。

ファイルアップロード時のエラーコード

PHP のドキュメントを参照して下さい。通常、2(MAX_FILE_SIZE オーバー) か 4 のエラーになると思います

$_FILES 情報の type のウソについて

この情報は正確ではありません。拡張子より決定しているようなので、exif_imagetype で正しいフォーマットを決定して使用しています。Windows 環境では、php.ini で php_exif.dll を有効にする必要があるので注意して下さい。

日本語ファイル名について

日本語部分を urlencode する事によって、一般的に WEB環境のディスクに保存できるようになります。但し、その文字のまま、WEB で呼び出そうとすると Not Found となるので注意して下さい。ブラウザ等から呼び出す場合、urlencode 部分が元に戻ってサーバに渡されます。なので、WEBアプリのクライアント側で扱う文字列としては、もう一度 urlencode しておく必要があります。

同一ファイルのアップロードについて

簡単に uniqid() の結果を頭に付けてファイル名を決定しています。ブラウザ側で、ギャラリーとして表示する場合は、uniqid() 部分を取り除いて表示する事によってオリジナルファイル名となります。しかし、ここでもしそのファイルが日本語の場合、urlencode されているので、urldecode する必要がありますが、そのままでは Windows 環境からアップロードされたものは、SHIFT_JIS のままだという事に注意して下さい。ギャラリーのページのキャラクタセットが SHIFT_JIS 以外の場合は、mb_convert_encoding で変換が必要になります

未実装の処理について

このままでは、ファイルがアップロードされて images フォルダに増えて行くばかりとなります。画像という前提の為、『ギャラリー』を作成する必要がありますが、画像の表示には、メモリを圧迫しない小さな画像ファイル(サムネイル)が必要になります。その為には、GD を使用してアップロードが成功した後に、縮小したファイルを作成する必要があります。

サムネイルが作成されれば、一覧表示をファイルシステム関数を使用して表示するだけですが、オリジナル画像を参照する為に、ポピューラーな Lightbox2 ライブラリ等を実装して使用する事となります。

アップロードフォーム
▼ file_upload.php
<?php
// *************************************
// キャラクタセット
// *************************************
header( "Content-Type: text/html; charset=utf-8" );
// *************************************
// キャッシュ無効
// *************************************
session_cache_limiter('nocache');
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<?php // キャラクタセット ?>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<?php // スマホ用 ?>
<meta name="viewport" content="width=device-width,initial-scale=1.0">

<?php // イザと言う時の為 ?>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>

<style>
body {
	margin: 0;
	padding: 30px;
	background-color: #d0d0d0;
}
body,pre,input {
	font-size: 16px;

<?php // よくある(ポピュラーな)設定 ?>
	font-family: "ヒラギノ角ゴPro W3","Hiragino Kaku Gothic Pro","メイリオ",Meiryo,"MS Pゴシック",Verdana,Arial,Helvetica,sans-serif;
}
</style>

</head>

<body>
<form
<?php // ファイルアップロードで必須 ?>
	enctype="multipart/form-data"
	method="post"

<?php // ファイルがアップロードされる php ?>
	action="upload.php"

<?php // 結果が表示される IFRAME の名称 ?>
	target="result_window">

<?php // php の画像サイズ制限の設定 ?>
	<input type="hidden" name="MAX_FILE_SIZE" value="1000000">

<?php // ローカルファイル参照用 ?>
	<input type="file" id="file" name="file" size="40">
	<br>
	<br>
	<input
		type="submit"
		name="send"
		value="開始">
	<br>
	<br>
</form>

<?php // 結果が表示される IFRAME ?>
<iframe
	name="result_window"
	frameborder="1"
	scrolling="yes"
	width="100%"
	height="400"
	style='background-color:white;'
></iframe>


</body>
</html>


アップロードされたファイルの処理
▼ upload.php
<?php
// *************************************
// キャラクタセット
// *************************************
header( "Content-Type: text/html; charset=utf-8" );
// *************************************
// キャッシュ無効
// *************************************
session_cache_limiter('nocache');
session_start();

// ファイルを移動するフォルダ
$target_folder = "./images/";

// *************************************
// アップロードされたファイル
// *************************************
$ok = ( $_FILES['file']['error'] == 0 );
if ( $ok ) {

	// *************************************
	// 以降、アップロードそのものは成功
	// *************************************

	// *************************************
	// 1) 画像フォーマットの取得
	// *************************************
	$type_string = image_type_to_mime_type( exif_imagetype( $_FILES['file']['tmp_name'] ) );

	// *************************************
	// 2) オリジナルファイル名の取得
	// *************************************
	$file = explode(".", $_FILES['file']['name']);

	// *************************************
	// 3) 日本語ファイル名対応
	// *************************************
	$file_name = urlencode( $file[0] );

	// *************************************
	// 4) 保存ファイル名を作成
	//   a) 拡張子決定
	//   b) uniqid() でファイル目をユニーク
	// *************************************
	$target = "";
	if ( $type_string == "image/jpeg" ) {
		$target = uniqid() . "_{$file_name}.jpg";
	}
	if ( $type_string == "image/gif" ) {
		$target = uniqid() . "_{$file_name}.gif";
	}
	if ( $type_string == "image/png" ) {
		$target = uniqid() . "_{$file_name}.png";
	}
	if ( $target == "" ) {
		$result = "アップロードできないフォーマットです\n";
	}
	else {
		// *************************************
		// アップロードファイルの保存
		// *************************************
		if ( @move_uploaded_file( $_FILES['file']['tmp_name'], $target_folder . $target ) ) {
			$result = "アップロードに成功しました\n";
		}
		else {
			// なんらかの環境エラー
			$result = "アップロードに失敗しました\n";
		}
		
	}
}
else {
	$result = "ファイルはアップロードされていません";
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>

<style>
body {
	margin: 0;
	padding: 40px;
	background-color: #ffffff;
}
body,pre {
	font-size: 16px;
	font-family: "ヒラギノ角ゴPro W3","Hiragino Kaku Gothic Pro","メイリオ",Meiryo,"MS Pゴシック",Verdana,Arial,Helvetica,sans-serif;
}
</style>

</head>

<body>
<h3><?= $result ?></h3>

<?php // 情報を最も簡単に表示する方法 ?>
<pre>
<?= print_r( $_FILES, true ) ?>
<?= print_r( $_POST, true ) ?>
</pre>
<?php // urlencode は、日本語のファイル名に必要です ?>
<img src="<?= $target_folder . urlencode( $target ) ?>" style='width:90%;'>
</body>
</html>


オリジナルファイル名については、. がファイル名に含まれないように考慮しています。


posted by lightbox at 2016-06-28 18:06 | Comment(0) | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2016年06月12日


pChart2 に JKゴシックとラノベポップを使ってサンプルを作りました



良く使われると想定される、折れ線グラフの最もシンプルなサンプルで各実行単位の解説をコメントで付加しています。
(ソースコードは UTF-8N)
<?php

// *************************************
// ライブラリの読み込み
// *************************************
require_once("../pchart/class/pData.class.php");
require_once("../pchart/class/pDraw.class.php");
require_once("../pchart/class/pImage.class.php");

$main_font = "./JKG-L_3.ttf";
$ttl_font = "./lightnovelpop.ttf";

$w = 600;
$h = 250;

// *************************************
// データ作成
// *************************************
$MyData = new pData();

// *************************************
// 座標設定
// ※ 最後の文字列は凡例用
// *************************************
$MyData->addPoints(array(-4,VOID,VOID,12,8,3),"凡例 壱");
$MyData->addPoints(array(3,12,15,8,5,-5),"凡例 弐");
$MyData->addPoints(array(2,7,5,18,19,22),"凡例 参");

// *************************************
// X 座標の表示内容
// *************************************
$MyData->addPoints(array("1月","2月","3月","4月","5月","6月"),"横軸の月");
// 後から設定する
$MyData->setAbscissa("横軸の月");	// 表示名

// *************************************
// ライン設定
// *************************************
$MyData->setSerieTicks("凡例 弐",4);	// 間隔 4 の点線
$MyData->setSerieWeight("凡例 参",2);	// 線幅

// デフォルトは 0
$MyData->setAxisName(0,"縦軸1");


// *************************************
// 画像のサイズ指定
// *************************************
$myPicture = new pImage($w,$h,$MyData);

// *************************************
// 画像の枠線指定
// *************************************
$myPicture->drawRectangle(0,0,$w-1,$h-1,array("R"=>0,"G"=>0,"B"=>0));

// アンチエイリアス
$myPicture->Antialias = TRUE;
 
// *************************************
// 使用するフォント
// *************************************
$myPicture->setFontProperties(array("FontName"=>$ttl_font,"FontSize"=>12));
// *************************************
// タイトル
// drawText($X,$Y,$Text,$Format="")
// *************************************
$myPicture->drawText(10,35,"ラノベポップは太めです",array("FontSize"=>20,"Align"=>TEXT_ALIGN_BOTTOMLEFT));

// *************************************
// 使用するフォント
// *************************************
$myPicture->setFontProperties(array("FontName"=>$main_font,"FontSize"=>12));

// *************************************
// グラフエリアの定義
// setGraphArea($X1,$Y1,$X2,$Y2)
// *************************************
 $myPicture->setGraphArea(60,40,$w-70,$h-50);

// *************************************
// スケールの設定
// *************************************
$scaleSettings = 
	array(
		"XMargin"=>10,
		"YMargin"=>10,
		"Floating"=>TRUE,			// 座標外(マージン)をクリア
		"GridR"=>100,"GridG"=>100,"GridB"=>100,	// グリッド線の色
		"DrawSubTicks"=>TRUE,		// 目盛の中心に目盛
		"CycleBackground"=>TRUE		// 交互に色を付ける
	);

// *************************************
// スケールの描画
// *************************************
$myPicture->drawScale($scaleSettings);

// *************************************
// グラフの描画
// *************************************
$myPicture->drawLineChart();

// *************************************
// 凡例の描画
// drawLegend($X,$Y,$Format="")
// *************************************
$myPicture->drawLegend(350,20,array("Style"=>LEGEND_NOBORDER,"Mode"=>LEGEND_HORIZONTAL));

// *************************************
// 表示
// *************************************
$myPicture->stroke();
?>

ちなみに、画像として img 要素に記述する場合は、php の最後に ? を付けておくと、右クリックで画像保存する際に .png として名前付けされました( Google Chrome で確認 )


posted by lightbox at 2016-06-12 22:10 | Comment(0) | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2015年05月23日


PHP の ImageMagick で作成した PNG 画像にオフセットが設定されてしまった場合の対応方法


 

GIMP でこのような表示がされてしまいました。無視すれば意図した状態にはなりますが、適用すると妙な事になります。( WEB上で表示するぶんには問題なさそうです )

何故このような事が起こるのかは解りませんが、背景を透過した時に画像の全体のサイズが調整されてしまってこのようになってしまいました。同様のトラブルも発見しましたが、それはコマンドラインの ImageMagick のお話でした。

ただ、リンク先の情報から、『+repage』というキーワードを知る事ができたので、それで調べると PHP のマニュアルの Imagick::trimImage というメソッドの User Contributed Notes に解答がありました。
<?php 
$im->trimImage(0); 
$im->setImagePage(0, 0, 0, 0); 
?>
上記処理で出なくなりました。



posted by lightbox at 2015-05-23 22:04 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2014年10月05日


PHP : 連想配列を「オブジェクト」に変換(キャスト)するとうまく動きますが、通常配列では参照できないようです

これは、連想配列云々では無く、プロパティ名が数字だと参照できないようです。( 0、a、2 という連想配列でテストしました )

PHP では、特別な文字列のプロパティ参照として、以下のような記述が可能です。
$z1->{'2011/07/08'}
$z1->{'日本語表示'}

※ ついでなので、可変変数でオブジェクトのプロパティを参照してみました
$v = '日本語表示';
print $z1->$v;
<?
header( "Content-Type: text/plain; Charset=shift_jis" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// ***********************************************
// 連想配列のテスト
// ***********************************************
$x['2011/07/08'] = 2;
$x['next'] = '2011/07/15';
$x['日本語表示'] = 'ここは SHIFT_JIS です';

$z1 = (object)$x;

print "\n";
print $z1->{'2011/07/08'} . "\n";
print "{$z1->next}\n";
print "{$z1->{'日本語表示'}}\n";

// 可変変数でオブジェクトのプロパティ
$v = '日本語表示';
print $z1->$v  ."\n";

print "\n";

var_dump($z1);

// ***********************************************
// 通常配列のテスト
// ***********************************************
$y[] = 2;
$y[] = '2011/07/15';
$y[] = 'ここは SHIFT_JIS です';

$z2 = (object)$y;

// 単独では表示されません??
print "\n";
print $z2->{0} . "\n";
print $z2->{'0'} . "\n";
print $z2->{"0"} . "\n";
$v = 0;
print $z2->$v . "\n";
$v = "0";
print $z2->$v . "\n";
print "\n";


// 中には入っているようですが・・・
var_dump($z2);


// ***********************************************
// その他の変換( マニュアル通りです )
// ***********************************************
$z3 = (object)'日本語表示';

print "\n";
print $z3->scalar . "\n";
print "\n";

var_dump($z3);

?>


2
2011/07/15
ここは SHIFT_JIS です
ここは SHIFT_JIS です

object(stdClass)#1 (3) {
  ["2011/07/08"]=>
  int(2)
  ["next"]=>
  string(10) "2011/07/15"
  ["日本語表示"]=>
  string(21) "ここは SHIFT_JIS です"
}







object(stdClass)#2 (3) {
  [0]=>
  int(2)
  [1]=>
  string(10) "2011/07/15"
  [2]=>
  string(21) "ここは SHIFT_JIS です"
}

日本語表示

object(stdClass)#3 (1) {
  ["scalar"]=>
  string(10) "日本語表示"
}
全く表示されません
最後に文字列を OBJECT に変換していますが、scalar と言うプロパティが作成されています。 ちなみに、説明の吹き出しは画像ですが、中の文字は普通の文字列で、PRE の枠の position を relative にして以下のようにして表示しています。
<img src="http://winofsql.jp/image/fd02.png" style='border:solid 0 #000;width:300px;position:absolute;left:220px;top:80px;box-shadow:none' /><div style='position:absolute;left:280px;top:160px;width:200px;font-size:20px;font-weight:bold'>全く表示されません</div>



posted by lightbox at 2014-10-05 11:44 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2014年09月04日


PHP のバージョンを 5.2 から 5.4 へ変更したところ、個別に date_default_timezone_set を実行するように言われました。

もっと前に、php.ini でタイムゾーンを設定する必要があったのを経験しましたが、先日 WEBサーバの PHP バージョンを 5.2 から 5.4 へバージョンアップしたところ、date 関数を使うだけで以下のようなワーニングが出ました。
Warning:  date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone.
なんか英語は今イチ理解しづらいですが、要するに、php.ini に設定されているタイムゾーンでは不十分だという事に読めたので、警告の出たソースコードに date_default_timezone_set を書くと消えました。
date_default_timezone_set('Asia/Tokyo');



タグ:トラブル
posted by lightbox at 2014-09-04 00:38 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2014年08月05日


PHP でエラーが表示されない場合の ini_set( 'display_errors', "1" ) 使用時の注意事項

PHP のオンラインマニュアルでは以下のように書かれています。
注意:
display_errors は実行時にも設定可能(ini_set() 関数を用いて)ですが、スクリプトが致命的(fatal)なエラーを発生した場合は その設定は反映されません。なぜなら、要求されたアクションは 実行されなかったからです。
経験と記憶から言うと、PHP のバージョンアップのどこかのタイミングでこうなったようなのですが、PHP のマニュアルにそういう記述は無く、上記のような記述になっています。ですから、実際の記述は include してその中に書く事になります。( php.ini で設定できる場合はその限りではありません )
<?php 
error_reporting(E_ALL); 
ini_set("display_errors", 1); 
include("file_with_errors.php"); 
?>

エラーの内容に関して言えぱ、error_reporting 関数を併用する事が多いと思います。


タグ:PHP
posted by lightbox at 2014-08-05 17:00 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2014年06月25日


PHP : 指定ファイル名でダウンロード 『application/octet-stream』 と 『Content-disposition: attachment』

application/octet-stream を使う事によって、通常はブラウザに表示されてしまうようなファイルをダウンロードさせる事ができます。

また、保存時のファイル名を正しくする為に Content-disposition を使用しています。

PHP のオンラインマニュアル にはそのものズバリのサンプルが readfile のページにあります。

例1 readfile() によるダウンロードの強制
<?php
$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}
?>
リンク先のマニュアルでも説明されていますが、readfile はそもそもこのような目的で使われる事を想定しているようで、『メモリに関する問題はなく、 巨大なファイルを送ってもかまいません。』とあります。特殊な目的で出力する為に内容に加工を加えるような場合は、後述のような内容で読み込めばいいはずです。

但し、キャッシュ制御が有効の場合は際限なく読み込んでしまって out of memory エラーが出る場合があるので、ob_end_clean であらかじめキャンセルしておくといいと思います。

システム書き込みバッファの内容を出力したい場合、キャッシュ制御が有効の場合は flash と ob_flush の両方が必要です

ファイルサイズは無くてもダウンロード可能ですが、ただ、存在しないとクライアント側で何パーセント処理済みかの表示が不可能になります。

fread を使用して読み込む
<?
header( "Content-Type: application/octet-stream" );
header( "Content-disposition: attachment; filename={$_GET['download_target']}" );

$path = '../download/' . $_GET['download_target'];

$size = filesize( $path );

header( "Content-Length: $size" );

$fp = fopen( $path, 'rb' );

if ( $fp ) {

	while( TRUE ) {
		if ( feof( $fp ) ) {
			break;
		}
		$ret = fread( $fp, 1024 );
		print $ret;
	}

	fclose( $fp );
}

?>


ファイルの取得方法では、小さいファイルならば、file_get_contents で十分ですが、大きなファイルではメモリが大量に消費させる可能性を考慮する必要があります。さらに、大きなファイルでは PHP 側のタイムアウトの設定も必要になる可能性があります。また、他のサーバーから取り込む場合は、ファイルサイズを取得するのに cURL 関数が必要になります。( PHP 5.0.0 以降 では filesize がそのまま使えるようなニュアンスですが、stat() を http がサポートしていないので使えません )

※ 参考 : max_execution_time (30/PHP_INI_ALL)

▼ PHP マニュアルの投稿の引用
<?php
$remoteFile = 'http://us.php.net/get/php-5.2.10.tar.bz2/from/this/mirror';
$ch = curl_init($remoteFile);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //not necessary unless the file redirects (like the PHP example we're using here)
$data = curl_exec($ch);
curl_close($ch);
if ($data === false) {
  echo 'cURL failed';
  exit;
}

$contentLength = 'unknown';
$status = 'unknown';
if (preg_match('/^HTTP\/1\.[01] (\d\d\d)/', $data, $matches)) {
  $status = (int)$matches[1];
}
if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
  $contentLength = (int)$matches[1];
}

echo 'HTTP Status: ' . $status . "\n";
echo 'Content-Length: ' . $contentLength;
?>
cURL を使ったサンプル

PHP : WEBでもコマンドラインでもHTTPでファイルをダウンロードする


タグ:fread readfile PHP
posted by lightbox at 2014-06-25 17:32 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2014年06月07日


特に変更しても支障の無い error_append_string php.ini ディレクティブを使用して PHP 全体のデバッグに利用する

PHP 全体のお話になるので、個人の開発環境を想定してはいますが、本番時には $debug = false; とすれば良いので運用のルールさえ確実であれば、いろいろ利用価値があると思います。
$debug = ini_get( "error_append_string" );
if ( $debug == "" ) {
	$debug = true;
}
else {
	$debug = false;
}

関連する PHP のドキュメント

php.ini ディレクティブのリスト


posted by lightbox at 2014-06-07 14:27 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2014年04月16日


PHP の chm マニュアルが文字化けしなくなっています(現在2014/4/11ビルド)が、トップページは出ません

ダウンロードページ

とにかく、化けなくなったのでリコンパイルしなくていいようになりました。ただし、スタイルはありません。おまけにトップページは以下のようにエラーとなります(英語版はエラーになりません)。



長年困らされて来ましたが、いつのまにか文字化けは改善されていました。実際問題これで十分ですが、見栄えはイマイチではあります。



HTML Help file (with user notes) をダウンロードするのがお勧めです。



が、少しでも軽くしたい場合は HTML Help file でも十分です。



今となっては常識ですが、ブロックの解除は必要です。

If you are using Windows XP SP2 or later and you are going to download the documentation in CHM format, you need to "unblock" the file after downloading it by right-clicking on it in Windows Explorer and selecting the "Properties" menu item, then clicking on the "Unblock" button (on Windows Vista this is within the "Security" options). Failure to unblock the documentation file may result in error messages including "Navigation to the webpage was canceled" due to Windows security restrictions.
タグ:PHP
posted by lightbox at 2014-04-16 02:12 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2013年11月29日


PHP : 日本語を使った変数( 特殊文字列で変数 ) / 変数名を文字列として扱う

そのような需要が無かったので気付かなかったのですが、JSON 文字列を OBJECT に変換すると、日付フォーマットがプロパティで指定されていたので、PHP で参照する方法を調べたところ、json_decode のページのサンプルコードにそれがありました。

print $obj->{'foo-bar'}; // 12345

もともと、PHP では、$GLOBALS で、変数名を文字列として与えて参照できるのでこういう事なのだろうとテストをしてみました。
( 可変変数に文字列定数を使う )
<?

$var_name = array(
	"睦月", "如月", "弥生",
	"卯月",	"皐月", "水無月",
	"文月", "葉月", "長月",
	"神無月", "霜月", "師走"
	);

for( $i = 0; $i < count($var_name); $i++ ) {
	${$var_name[$i]} = $i+1;

}

print ${"睦月"} . "<br>";
print ${"如月"} . "<br>";
print ${"弥生"} . "<br>";
print ${"卯月"} . "<br>";
print ${"皐月"} . "<br>";
print ${"水無月"} . "<br>";
print ${"文月"} . "<br>";
print ${"葉月"} . "<br>";
print ${"長月"} . "<br>";
print ${"神無月"} . "<br>";
print ${"霜月"} . "<br>";
print ${"師走"} . "<br>";

${"表示"} = "SHIFT_JIS テスト";
${"山 田 太 郎"} = "スペースを含む";
${"2010/10/28"} = "日付";

print "${"表示"}<br>";
print "${"山 田 太 郎"}<br>";
print "{${"2010/10/28"}}<br>";

// 以下可変変数の説明
$a = "hello";
$$a = 'world';
echo "$a ${$a}" . "<br>";
echo "$a $hello" . "<br>";

print ${"hello"} . "<br>"; // この部分追加(特殊文字変数に使用可能)
print ${$a} . "<br>";
print $hello . "<br>";

?>


関連する記事

PHP : 可変変数を使用した特殊文字列による変数と JSON との関係  


タグ:PHP 変数
posted by lightbox at 2013-11-29 09:09 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2011年06月07日


PHPの真偽値

PHP: PHP 型の比較表 - Manual

以下のソースコードは、通常の「値」を条件文で一般的に扱う場合の簡単なサンプルです。
<pre>
<?php

// 一括代入
$x[0] = $x[1] = $x[2] = 10;

print_r( $x );

// 一つ一つ代入
$x[0] = 1;
$x[1] = 2;
$x[2] = 3;

print_r( $x );

// 一般的な値が「入っている状態」は 真
if ( $x[0] ) {
	print $x[0] . "\n";
}
if ( $x[1] ) {
	print $x[1] . "\n";
}
if ( $x[2] ) {
	print $x[2] . "\n";
}


function tf( $a ) {
	return $a;
}

if ( tf( 10 ) ) {
	print "関数の戻り値で判断\n";
}

// 関数の戻り値を使用したい場合
if ( $a = tf( 10 ) ) {
	print "$a : 関数の戻り値で判断\n";
}

// 最終的な左辺値で判断
if ( $a = $x[0] = $x[1] = $x[2] = tf( 100 ) ) {
	print "$a : 関数の戻り値で判断\n";
	print_r( $x );
}

// 0 は 偽( PHP 型の比較表 を参照 )
if ( 0 ) {
	print "ここは処理されません\n";
}
else {
	print "ここは処理されます\n";
}


?>
</pre>

▼ オンラインによる実行テスト
http://rextester.com/NLV33049


posted by lightbox at 2011-06-07 08:46 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2010年06月10日


PHP : include_path の設定

注意事項

1) Windows と Unix で違う部分を吸収する為に PATH_SEPARATOR を使う
2) 既に設定されている include_path を上書きしない

※ 以下は TCPDF のライブラリ参照です
$path = "C:\user\lightbox\web\tcpdf_5_3_005";
set_include_path(get_include_path() . PATH_SEPARATOR . $path);



posted by lightbox at 2010-06-10 11:35 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します


Windows
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり