SQLの窓

2016年05月05日


レンタルサーバで PHP のバージョンを 5.4 から 5.6 に変更する時の注意事項

PHP 5.4 までは default_charset に値が入っていませんでした。しかし、5.6 では default_charset = UTF-8 となるので日本語が化ける可能性がとても多くなります。そこで、php.ini の中に以下のように設定を追加します
default_charset = 

こうすると、PHP 5.4 と同じ no_value 設定になります( phpinfo 関数で確認します )



但し、その php ファイルが参照できる範囲に別の個別の php.ini があると、その設定で全て上書きされるので注意して下さい。



posted by lightbox at 2016-05-05 14:36 | Comment(0) | PHP | このブログの読者になる | 更新情報をチェックする

2015年06月25日


【3大手法】 PHP で変数を埋め込んだ画面定義を外部ファイルにして、ループ内で展開する

外部ファイルを読み込む手段としては二つあって、一つは一般的な require で行います。もう一つはテキストファイルとして file_get_contents を使用します。

以下のサンプルソースの実行時の環境としては、データベースに対して接続した後、select 文を実行して行データをループで取得しているという前提です。

require 使った標準的な手法

この方法は PHP のあたりまえの記述で、想定通りの結果になる手法です。ただ、外部ファイルの埋め込み方法の記述も一般的になる為、変数埋め込みの記法が面倒で、画面作成やメンテナンスに時間がかかりますし、他の目的への転用は全くできません。
// 画面作成
print "<table>";
while ($row = $result->fetch_array(MYSQLI_BOTH)) {

	// 行の繰り返し
	require("view_row.php");

}
print "</table>";

<tr>
	<td class="left"><?= $row["社員コード"] ?></td>
	<td class="right"><?= $row["氏名"] ?></td>
</tr>


file_get_contents 使った手法

この方法は、画面定義用の文字列を単純に外部ファイルにして、テキストデータ内の変数を eval を使って置き換える手法です。この場合、変数部分以外も単純な文字列なので、正規表現による置換や単純な置換の対象となりますし、利用方法はいろいろな場面であらわれると思います。( SQL 文の定義にも有効です )

ただ、変数の記述部分のルールとして、連想配列部分の文字列はシングルクォートで書く必要があります
// 画面作成
print "<table>";
while ($row = $result->fetch_array(MYSQLI_BOTH)) {

	// 行の繰り返し
	$view_row = file_get_contents("view_row.txt");
	$view_row = str_replace('"', '\\"', $view_row );
	eval("\$view_row = \"$view_row\";");
	print $view_row;

}
print "</table>";

<tr>
	<td class="left">{$row['社員コード']}</td>
	<td class="right">{$row['氏名']}</td>
</tr>



require の中で、ヒアドキュメントを使う方法

この方法が一番簡単で単純で、本来のヒアドキュメントの目的をしっかり使ったものです。難しい問題は全く無く、自然に使える方法です。

ここでは、print を外に出して使っていますが、view_row.php 内で print してしまってもかまいません。
// 画面作成
print "<table>";
while ($row = $result->fetch_array(MYSQLI_BOTH)) {

	// 行の繰り返し
	require("view_row.php");
	print $view_row;

}
print "</table>";

<?php
$view_row = <<<VIEW_ROW
<tr>
	<td class="left">{$row["社員コード"]}</td>
	<td class="right">{$row["氏名"]}</td>
</tr>
VIEW_ROW;
?>

いずれも関数化する事は可能ですが、テキストを外部に定義して管理するという目的においては、file_get_contents を使う方法が最も優れています。( 画面作成の場合、文字列を取得するだけで後で使うという選択肢のほうが現実的です )

require は、その場で書いてしまう場合において、一般的なメンテナンス性が向上するはずです。

関数化する場合は、埋め込む変数にスーパーグローバルの $GLOBALS を使うといいです。


タグ:PHP
posted by lightbox at 2015-06-25 11:14 | PHP | このブログの読者になる | 更新情報をチェックする

2015年06月23日


PHP で pathinfo と mime 情報やその他を合体した、get_finfo 関数を使って、opendir からファイル一覧を出力

ファイルの一覧から、ファイル情報を配列でまとめたものを一括で取得できるようにしました。

※ Windows では、php.ini の extension=php_fileinfo.dll を有効にする必要があります
<?php
header( "Content-Type: text/html; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

print "<pre>";

$target = ".";
print realpath($target) . "\n";

$dir_handle = @opendir($target);
if ( $dir_handle ) {
	// ディレクトリハンドルの取得成功

	while (false !== ($entry = readdir($dir_handle))) {
		// 対象外は読み飛ばし
		if ( $entry == '.' || $entry == '..' ) {
			print  "対象外=>{$entry}\n";
			continue;
		}

		print  "{$entry}\n";
		print_r( get_finfo($target.DIRECTORY_SEPARATOR.$entry) );


	}
}

print "</pre>";

function get_finfo($path) {

	$finfo = finfo_open(FILEINFO_MIME);
	$mime = finfo_file($finfo, $path);
	$mime2 = explode( "; ", $mime );
	$mime3 = explode( "=", $mime2[1] );
	$pathinfo = pathinfo(realpath($path));
	$path_parts = pathinfo($pathinfo["dirname"]);
	$pathinfo["parent"] = $path_parts["basename"];
	$pathinfo["mime"] = $mime2[0];
	$pathinfo["charset"] = $mime3[1];
	if ( $pathinfo["charset"] == "" ) {
		unset($pathinfo["charset"]);
	}
	$pathinfo["size"] = filesize($path);
	if ( $pathinfo["mime"] == "directory" ) {
		unset($pathinfo["size"]);
	}
	$pathinfo["full"] = realpath($path);

	return $pathinfo;

}

?>


▼ 以下は、Windows での実行サンプルです。
C:\user\web\basic
対象外=>.
対象外=>..
db_update
Array
(
    [dirname] => C:\user\web\basic
    [basename] => db_update
    [filename] => db_update
    [parent] => basic
    [mime] => directory
    [full] => C:\user\web\basic\db_update
)
dir_test.php
Array
(
    [dirname] => C:\user\web\basic
    [basename] => dir_test.php
    [extension] => php
    [filename] => dir_test
    [parent] => basic
    [mime] => text/x-php
    [charset] => utf-8
    [size] => 1457
    [full] => C:\user\web\basic\dir_test.php
)
log.zip
Array
(
    [dirname] => C:\user\web\basic
    [basename] => log.zip
    [extension] => zip
    [filename] => log
    [parent] => basic
    [mime] => application/zip
    [charset] => binary
    [size] => 1589
    [full] => C:\user\web\basic\log.zip
)
php.exe
Array
(
    [dirname] => C:\user\web\basic
    [basename] => php.exe
    [extension] => exe
    [filename] => php
    [parent] => basic
    [mime] => application/x-dosexec
    [charset] => binary
    [size] => 59392
    [full] => C:\user\web\basic\php.exe
)
php5.dll
Array
(
    [dirname] => C:\user\web\basic
    [basename] => php5.dll
    [extension] => dll
    [filename] => php5
    [parent] => basic
    [mime] => application/x-dosexec
    [charset] => binary
    [size] => 5949440
    [full] => C:\user\web\basic\php5.dll
)
tool_html_150517214638.htm
Array
(
    [dirname] => C:\user\web\basic
    [basename] => tool_html_150517214638.htm
    [extension] => htm
    [filename] => tool_html_150517214638
    [parent] => basic
    [mime] => text/html
    [charset] => utf-8
    [size] => 603
    [full] => C:\user\web\basic\tool_html_150517214638.htm
)
_img.jpg
Array
(
    [dirname] => C:\user\web\basic
    [basename] => _img.jpg
    [extension] => jpg
    [filename] => _img
    [parent] => basic
    [mime] => image/jpeg
    [charset] => binary
    [size] => 133801
    [full] => C:\user\web\basic\_img.jpg
)



タグ:PHP
posted by lightbox at 2015-06-23 23:12 | PHP | このブログの読者になる | 更新情報をチェックする

2015年06月20日


PHP : unset によるオブジェクトのプロパティの削除と配列の要素の削除の検証

最初、配列関数の中を見ていても無いのでたぶんこういう事なんだろうと思って検証してみると、その通りでした。( 日本語は UTF-8 です )

Run code で検証

※ 日本語のプロパティなので、$obj->{"手当"} というように参照します
$format1 = <<<FIELD
{
    "社員コード": "",
    "氏名": "",
    "フリガナ": "",
    "所属": "",
    "性別": "",
    "作成日": "",
    "更新日": "",
    "給与": "",
    "手当": "",
    "管理者": "",
    "生年月日": ""
}
FIELD;

print "\n-----------------------------------";
print "\nJSON文字列\n";
print $format1;

print "\n-----------------------------------";
print "\nオブジェクトに変換したもの\n";

$obj = json_decode($format1);
print_r($obj);

print "\n-----------------------------------";
print "\n『手当』プロパティを削除\n";
unset($obj->{"手当"});

print_r($obj);

print "\n-----------------------------------";
print "\n配列に変換したもの\n";

$array = get_object_vars( $obj );
print_r( $array );

print "\n-----------------------------------";
print "\n配列の要素を削除\n";

unset($array["所属"]);
    
print_r( $array );


実行結果
-----------------------------------
JSON文字列
{
    "社員コード": "",
    "氏名": "",
    "フリガナ": "",
    "所属": "",
    "性別": "",
    "作成日": "",
    "更新日": "",
    "給与": "",
    "手当": "",
    "管理者": "",
    "生年月日": ""
}
-----------------------------------
オブジェクトに変換したもの
stdClass Object
(
    [社員コード] => 
    [氏名] => 
    [フリガナ] => 
    [所属] => 
    [性別] => 
    [作成日] => 
    [更新日] => 
    [給与] => 
    [手当] => 
    [管理者] => 
    [生年月日] => 
)

-----------------------------------
『手当』プロパティを削除
stdClass Object
(
    [社員コード] => 
    [氏名] => 
    [フリガナ] => 
    [所属] => 
    [性別] => 
    [作成日] => 
    [更新日] => 
    [給与] => 
    [管理者] => 
    [生年月日] => 
)

-----------------------------------
配列に変換したもの
Array
(
    [社員コード] => 
    [氏名] => 
    [フリガナ] => 
    [所属] => 
    [性別] => 
    [作成日] => 
    [更新日] => 
    [給与] => 
    [管理者] => 
    [生年月日] => 
)

-----------------------------------
配列の要素を削除
Array
(
    [社員コード] => 
    [氏名] => 
    [フリガナ] => 
    [性別] => 
    [作成日] => 
    [更新日] => 
    [給与] => 
    [管理者] => 
    [生年月日] => 
)


タグ:PHP
posted by lightbox at 2015-06-20 14:21 | PHP | このブログの読者になる | 更新情報をチェックする

2014年11月14日


Windows で、MySQL を使っているので phpMyAdmin で参照しようとして、AN HTTPD だと setup が動かなかったので Apache を入れようとしたらいろいろルールがあったお話



重要な手順部分は、NAVER にまとめました。

そもそも、USB でもサーバ移動できる AN HTTPD を授業で使用しており、卒業進級制作の課題内容を WEB と ローカルで同じ環境を作るよう指示した手前、自分でテストしていて起きた内容のまとめです。
( ちなみに、AN HTTPD は管理者権限で起動する必要があります )

phpMyAdmin

インストーラとか特にありません。定義ファイルは実運用で必要ですが、すぐテストしたいだけなら全てデフォルトで動作します。DB のユーザとパスワードでログインして操作可能です。

ですが、setup フォルダがあるので気になって使ってみると、config.inc.php という定義ファイルを作成する為のもので、サーバを何通りも追加して定義ファイルをダウンロードしたり表示したりできるツールでした。
さらに、config フォルダを作成して、そこに書き込み権限を与えると作成されますが、本体を実行する際にその confog フォルダが残っていると、早く消せと警告されます。つまり、あまり推奨するようなものでもなさそうです。

config.sample.inc.php をコピーして十分使えます。特に、保存領域の機能を追加するにしても、examples の中にある create_tables.sql を実行した後、/* Storage database and tables */ に関する設定のコメントを外すと、DB のテーブル内に表示しておきたいデータベースの一覧を保存できるようになり、運用が楽になります。

setup は、実際問題、あまり役には立ちそうに無かったのですが、AN HTTPD で動作しなかったので、Apache のテストをする事になってしまいました

Apache Lounge

さくらインターネットのレンタルサーバで動いたので、AN HTTPD のせいだと思い、Windows に Apache をインストールしようと思ったのですが、この時 Apache の配布に二種類ある事に気がつきませんでした。
Apache
Please use the Apache builds provided by Apache Lounge. They also provide VC11 builds of Apache for x86 and x64. We use their binaries to build the Apache SAPIs.

If you are using PHP with Apache 1 or Apache2 from apache.org (not recommended) 
PHP の Windows バイナリを配布するところにこのように書かれているのですが、最初 apache.org からダウンロードしてしまって、インストーラでインンストールした後、Apache から PHP を使うという所で止まってしまい、Apache Lounge の存在に気がつきました。 Apache Lounge は、完全な実行環境が書庫化されており、bin ディレクトリの httpd.exe をコマンドプロンプトから実行するだけで開始されます。サービスに登録したい場合は、httpd.exe -k install を実行するようにと、ReadMe.txt に書かれていました。
Install
-------


- Unzip the Apache24 folder to c:/Apache24 (that is the ServerRoot in the config).
  Default folder for your your webpages is DocumentRoot "c:/Apache24/htdocs"

  When you unzip to an other location, change ServerRoot in the httpd.conf,
  and change in httpd.conf the Documenroot, Directories, ScriptAlias,
  also when you use the extra folder config file(s) change to your location there. 

Start apache in a DOS box:

>httpd.exe

Install as a service:

>httpd.exe -k install

ApacheMonitor:

Double click ApacheMonitor.exe, or put it in your Startup folder.
スレッドセーフ

AN HTTPD では、ノンスレッドセーフを使用しています。つまり、既存の PHP 内に Apache 用の dll は入っていません。なので PHP を新たにダウンロードして、Apache のバージョンとも一致させる事になりました。

最新では、php5apache2_4.dll が入っていたので、Apache は 2.4 が必要です。ここで注意するのは、古いバージョンでなんとかしようとする場合は、対応する Apache の dll を Apache Lounge からダウンロードする事が必要な場合があります。Apache Lounge では、VC9 に関していくつか PHP のバージョンにあわせて配布されています。また、VC11 用のランタイム無いと動かないので、ランタイムを現在のものを使用したい場合は、同様のバージョンあわせとダウンロードが必要になります。

MSVCR110.dll

最新は、VC11 でビルドされているので、ランタイムをインストールしても良いという場合は、以下からダウンロードできます。

Visual Studio 2012 更新プログラム 4 の Visual C++ 再頒布可能パッケージ

でも、Microsoft の余計なインストールはできれば避けたいので、VC9 でなんとかしたい人も多いと思います


※ phpMyAdmin の setup は、結局 Windows の Apache で動作しました。


posted by lightbox at 2014-11-14 21:10 | PHP | このブログの読者になる | 更新情報をチェックする

2014年09月05日


PHP : ファイルのアップロード時のデータのダンプ( PHP 5.4.0 以降で利用可能な php://input での取得 / ASP / C# )

PHP での方法

php.ini で、enable_post_data_reading = Off を設定すると、PHP へのPOST データは、php://input で取得する方法が使用できます( PHP 5.4.0 以降で利用可能 )。ヘッダ情報は、apache_request_headers で取得できます。( この関数は PHP のバージョンによっては動作しません )
このオプションを無効にすると、$_POST や $_FILES に値が入らなくなります。 この場合、投稿されたデータを読むには、ストリームラッパー php://input を使う以外の方法はなくなります。 これは、リクエストをプロキシしたり POST データを処理する際のメモリ消費量を抑えたりする際に有用です。
以下はテストコードです。
<?php

$postdata = file_get_contents("php://input"); 
file_put_contents("body.dat", $postdata );

$headers = print_r(apache_request_headers(),true);
file_put_contents("head.txt", $headers);

?>
OK

▼ body.dat
------WebKitFormBoundaryYhPBaYDBSNNO1pBx
Content-Disposition: form-data; name="send"

upload button
------WebKitFormBoundaryYhPBaYDBSNNO1pBx
Content-Disposition: form-data; name="MAX_FILE_SIZE"

100000
------WebKitFormBoundaryYhPBaYDBSNNO1pBx
Content-Disposition: form-data; name="fileUpload"; filename="001.png"
Content-Type: image/png

バイナリデータ……
バイナリデータ……
バイナリデータ……
------WebKitFormBoundaryYhPBaYDBSNNO1pBx
Content-Disposition: form-data; name="fileUploadTitle"

comment
------WebKitFormBoundaryb80JkuEC8QiLNDst--

ASP での方法

ASP を使うのは、Windows7 では、プロフェッショナル以上が必要だと思いますが、IIS をインストールすれば、比較滝簡単に利用できます。ただ、慣れないうちは管理コンソールが解りにくいのが難点です。

IISのインストール



仮想ディレクトリの作成



仮想ディレクトリを追加して、ディレクトリの参照を有効にすれば、だいたい普通に使えるはずです。

<% Call Response.AddHeader( "Content-Type", "text/html; Charset=shift_jis" ) %>
<form
	method=POST
	enctype=multipart/form-data>
<input type=file name=upload>
<input type=submit name=send value="送信">
</form>
<%
if Request.ServerVariables( "REQUEST_METHOD" ) = "POST" then
 
' ****************************
' オブジェクト作成
' ****************************
	Set Stream = Server.CreateObject("ADODB.Stream")
 
' ****************************
' ストリームオープン
' ****************************
	Stream.Open
 
' ****************************
' Stream タイプの指定
' ****************************
	Stream.Type = 1
 
' ****************************
' raw データの受信と書き込み
' ****************************
	nCount = Request.TotalBytes
	Stream.Write Request.BinaryRead( nCount )
	Stream.SaveToFile Server.MapPath("Post.dat"), 2 

' ****************************
' Stream を閉じる
' ****************************
	Stream.Close
 
end if
%>


以下はその時の HTTP ヘッダです
POST /web/upload/test.asp HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/vnd.ms-excel, */*
Referer: http://localhost/web/upload/test.asp
Accept-Language: ja
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Content-Type: multipart/form-data; boundary=---------------------------7da1c519203ca
Accept-Encoding: gzip, deflate
Host: localhost
Content-Length: 78138
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: __csv=cdeb8a0717bcd53; ASPSESSIONIDAQTSTRBR=JHMFJGLDFNIDKMNFDIGBOAEK

データは以下のようになります
-----------------------------7da1c519203ca
Content-Disposition: form-data; name="upload"; filename="1252328628672351.png"
Content-Type: image/x-png

ここにバイナリデータ
ここにバイナリデータ
ここにバイナリデータ
-----------------------------7da1c519203ca
Content-Disposition: form-data; name="send"

送信
-----------------------------7da1c519203ca--



AN HTTPD + C#(VS2010)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace cgi_get_body {
	class Program {
		static void Main(string[] args) {
			Stream inputStream = Console.OpenStandardInput();
			using (FileStream fileStream = new FileStream(@"C:\user\body.dat", FileMode.Create)) {
				inputStream.CopyTo(fileStream);
			}
			EasyResponse();
		}
		static void EasyResponse() {

			Console.WriteLine("Expires: Thu, 04 Oct 2000 00:00:00 GMT");
			Console.WriteLine();

			Console.WriteLine("<!DOCTYPE html>");
			Console.WriteLine("<html lang="ja">");
			Console.WriteLine("<head>");
			Console.WriteLine("</head>");
			Console.WriteLine("<body>");
			Console.WriteLine("OK");
			Console.WriteLine("</body>");
			Console.WriteLine("</html>");

		}

	}
}

C# でビルドした exe が存在するディレクトリを AN HTTPD の一般パスに登録して、.exe を『一般パスでも実行する』ようにし、FORM の ACTION を exe ファイルにすれば c:\user\body.dat にアップロード情報が書き込まれます。



posted by lightbox at 2014-09-05 02:13 | PHP | このブログの読者になる | 更新情報をチェックする

2014年06月07日


PHP で問い合わせ画面のページリンクを常に5つ作成しておいて、jQuery でいらないリンクを非表示にする

ページリンクは大量にあっても、実際には業務効率が悪いので良いとは言えない場合もあります。条件で絞り込めばおのずとページ数は少なくなり、そのほうが効率的です。以下の方法は、初心者にとって難解かもしれないページリンクの実装を出来る限り簡単にしたものです。

PHP 側で解っている現在のデータ件数を JavaScript の変数に埋め込んで、その結果から jQuery のセレクタを使って必要無いリンクを非表示にしています



上の画像は実際の画面で、その非表示にした状態をデベロッパーツールで表示しています
$(function() {

	// PHP から、検索結果の件数を埋め込んで、JavaScript で利用します
	var row_counter = <?= $result->num_rows.'' == '' ? "0" : $result->num_rows ?>;

	// jQuery のセレクタで、検索結果の件数を使って特定のページ以降を
	// 非表示にします
	if ( row_counter <= 10 ) {
		$( "a[id*='p1']" ).hide();
	}
	if ( row_counter <= 20 ) {
		$( "a[id*='p1p2p3']" ).hide();
	}
	if ( row_counter <= 30 ) {
		$( "a[id*='p1p2p3p4']" ).hide();
	}
	if ( row_counter <= 40 ) {
		$( "a[id*='p1p2p3p4p5']" ).hide();
	}

});



タグ:PHP jquery
posted by lightbox at 2014-06-07 18:54 | PHP | このブログの読者になる | 更新情報をチェックする

2014年06月05日


PHP : HTMLのinput要素のname属性に二次元配列を指定して getElementsByName と jQueryのinput[name='value']:eq(n) でアクセステスト

結論から言えば、書き方だけの問題で、思った通りに動作します。ただ、JavaScript でアクセスする場合は id 属性を定義するほうが良いです。しかし、名前に関して二重の管理が必要になるのを避けたい場合はこのような方法も選択肢の一つではあると思います。

※ PHP 側のアクセスは、最初からグループ分けが可能ですし、便利な書き方です。



DOM を使ったコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
function checkForm() {

	if ( !confirm("送信してよろしいですか?") ) {
		return;
	}

	// 本来は、ここで入力チェックを実行し、
	// エラーならば return false; を実行する

	var obj;

	obj = document.getElementsByName("list[in][]");
	alert(obj[0].value);
	alert(obj[3].value);
	obj = document.getElementsByName("list[out][]");
	alert(obj[0].value);
	alert(obj[3].value);

	return true;
}
</script>
</head>
<body>
<form onsubmit='return checkForm();'>
<input type="submit">
<br>
<input type="text" name="list[in][]" value="A">
<input type="text" name="list[in][]" value="B">
<input type="text" name="list[in][]" value="C">
<input type="text" name="list[in][]" value="D">
<br>
<input type="text" name="list[out][]" value="V">
<input type="text" name="list[out][]" value="W">
<input type="text" name="list[out][]" value="X">
<input type="text" name="list[out][]" value="Y">
</form>


<pre>
<?php
print_r($_GET);
?>
</pre>
</body>
</html>


jQuery を使ったコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script type="text/javascript">
$(function() {

	// ***********************************************
	// Form が送信前に実行されるイベント
	// event.preventDefault(); で送信をキャンセル
	// ***********************************************
	$( "form" ).submit(function( event ) {
		if ( !confirm("送信してよろしいですか?") ) {
			event.preventDefault();
			return;
		}

		// 本来は、ここで入力チェックを実行し、
		// エラーならば event.preventDefault() を実行する

		alert( $("input[name='list[in][]']:eq(0)").val() );
		alert( $("input[name='list[in][]']:eq(3)").val() );

		alert( $("input[name='list[out][]']:eq(0)").val() );
		alert( $("input[name='list[out][]']:eq(3)").val() );

	});

});
</script>
</head>
<body>
<form>
<input type="submit">
<br>
<input type="text" name="list[in][]" value="A">
<input type="text" name="list[in][]" value="B">
<input type="text" name="list[in][]" value="C">
<input type="text" name="list[in][]" value="D">
<br>
<input type="text" name="list[out][]" value="V">
<input type="text" name="list[out][]" value="W">
<input type="text" name="list[out][]" value="X">
<input type="text" name="list[out][]" value="Y">
</form>


<pre>
<?php
print_r($_GET);
?>
</pre>
</body>
</html>



posted by lightbox at 2014-06-05 02:20 | PHP | このブログの読者になる | 更新情報をチェックする

2013年11月28日


PHP の簡易ログとしては file_put_contents が使われますが、表現方法をいろいろテストして行くと、PHP のバージョンを 5.4.0 以上にして json_encode を使いたくなります。

PHP の 5.4.0 以降では、json_encode の第二引数にフラグを設定して、とても便利で見やすい文字列が作成できます。
JSON_PRETTY_PRINT (integer)
  返される結果の書式を、スペースを使って整えます。
JSON_UNESCAPED_SLASHES (integer)
  / をエスケープしません。 
JSON_UNESCAPED_UNICODE (integer)
  マルチバイト Unicode 文字をそのままの形式で扱います (デフォルトでは \uXXXX にエスケープします)。 
一応、マイナーバージョンをチェックして、使え無いバージョンの場合は第二引数を使わない処理にしています。テストに使っている配列は、$_SERVER( 連想配列 ) と get_declared_classes() で出力される通常配列です。単純にログにキーが必要な場合は当然 print_r( 内容, true ) が良いと思いますが、json_encode で出力される文字列は、さらにシンプルで他への転用にも便利です。特に、単純配列の場合は、json_encode では 内容のみとなっていてより見やすくなっています。 後からの使い道にっては、implode("\n",$target) も使い勝手が良いかもしれません。
<?php

function log_test( $target, $file_name ) {


	$vm = explode( ".", PHP_VERSION );
	$vm = $vm[1] + 0;

	// 結果を見るテストなので、6つだけ取り出す
	$target = array_slice($target, 0, 6 );

	file_put_contents( $file_name, $target, FILE_APPEND );	

	file_put_contents( $file_name, "\n------------------------\n", FILE_APPEND );

	file_put_contents( $file_name, implode("\n",$target), FILE_APPEND );	

	file_put_contents( $file_name, "\n------------------------\n", FILE_APPEND );

	file_put_contents( $file_name, print_r($target,true), FILE_APPEND );	

	file_put_contents( $file_name, "\n------------------------\n", FILE_APPEND );

	if ( $vm >= 4 ) {
		file_put_contents( $file_name, json_encode($target,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE), FILE_APPEND );	
	}
	else {
		file_put_contents( $file_name, json_encode($target), FILE_APPEND );
	}

	file_put_contents( $file_name, "\n------------------------\n", FILE_APPEND );

}

$file_target = "log.txt";

// クリア
file_put_contents( $file_target, "" );	

log_test($_SERVER,"log.txt");

log_test(get_declared_classes(),"log.txt");

?>

<pre><?= file_get_contents("log.txt") ?></pre>
OK


▼ 出力結果
200/usr/local/bin:/usr/bin:/bin/home/winofsql/wwwtext/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8gzip,deflate,sdchja,en-US;q=0.8,en;q=0.6
------------------------
200
/usr/local/bin:/usr/bin:/bin
/home/winofsql/www
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
gzip,deflate,sdch
ja,en-US;q=0.8,en;q=0.6
------------------------
Array
(
    [REDIRECT_STATUS] => 200
    [PATH] => /usr/local/bin:/usr/bin:/bin
    [DOCUMENT_ROOT] => /home/winofsql/www
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    [HTTP_ACCEPT_ENCODING] => gzip,deflate,sdch
    [HTTP_ACCEPT_LANGUAGE] => ja,en-US;q=0.8,en;q=0.6
)

------------------------
{
    "REDIRECT_STATUS": "200",
    "PATH": "/usr/local/bin:/usr/bin:/bin",
    "DOCUMENT_ROOT": "/home/winofsql/www",
    "HTTP_ACCEPT": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "HTTP_ACCEPT_ENCODING": "gzip,deflate,sdch",
    "HTTP_ACCEPT_LANGUAGE": "ja,en-US;q=0.8,en;q=0.6"
}
------------------------
stdClassExceptionErrorExceptionClosureDateTimeDateTimeZone
------------------------
stdClass
Exception
ErrorException
Closure
DateTime
DateTimeZone
------------------------
Array
(
    [0] => stdClass
    [1] => Exception
    [2] => ErrorException
    [3] => Closure
    [4] => DateTime
    [5] => DateTimeZone
)

------------------------
[
    "stdClass",
    "Exception",
    "ErrorException",
    "Closure",
    "DateTime",
    "DateTimeZone"
]
------------------------
OK
この処理では、file_put_contents で出力した内容を file_get_contents でページに読み込んでいますが、このままでは実用で使えません。このような手法を実際のページで使う為には、出力ファイルはセッション単位で作成する必要がありますし、不要になった時( 一定時間経過後等 )の削除方法をシステム的に実装しなければなりません。



タグ:JSON PHP
posted by lightbox at 2013-11-28 19:04 | PHP | このブログの読者になる | 更新情報をチェックする

2013年06月01日


さくらのサーバーで hash_hmac のアルゴリズムで使えるもの

実行結果

※ Windows には 5.4.13 をインストールしていますが、少し種類は多かったです。
※ PHP マニュアル( hash_hmac )

▼ ソースコード
<?php

$arr = hash_algos();

print "<pre>";
print phpversion(). "\n";

print_r($arr);

foreach( $arr as $algo ){
	print "$algo => ";
	print hash_hmac( $algo, 'password', 'lightbox' ) . "\n";
}

print "</pre>";

?>


現時点での実行結果
5.2.17
Array
(
    [0] => md2
    [1] => md4
    [2] => md5
    [3] => sha1
    [4] => sha256
    [5] => sha384
    [6] => sha512
    [7] => ripemd128
    [8] => ripemd160
    [9] => ripemd256
    [10] => ripemd320
    [11] => whirlpool
    [12] => tiger128,3
    [13] => tiger160,3
    [14] => tiger192,3
    [15] => tiger128,4
    [16] => tiger160,4
    [17] => tiger192,4
    [18] => snefru
    [19] => gost
    [20] => adler32
    [21] => crc32
    [22] => crc32b
    [23] => haval128,3
    [24] => haval160,3
    [25] => haval192,3
    [26] => haval224,3
    [27] => haval256,3
    [28] => haval128,4
    [29] => haval160,4
    [30] => haval192,4
    [31] => haval224,4
    [32] => haval256,4
    [33] => haval128,5
    [34] => haval160,5
    [35] => haval192,5
    [36] => haval224,5
    [37] => haval256,5
)
md2 => d87434ac40cbf0de2773e4c51cce4484
md4 => 7453709872da8a97250079493e9bcd5a
md5 => 0b8d1a7cf74154638a19eb9958b8e475
sha1 => 48896bb7c5fdd2a07956c906439e6ccacde0f008
sha256 => e6fa0d3621e86d2f098b8536438eda1eb7a5506447e02a2d3f61d31ec5d33ed8
sha384 => 260156d96024444ff6057dde5a3a13c3805019aeeb16b494ab95a79f2fb69d67fbb2513d6644b5f48d7af1560c93eb0f
sha512 => 1356741ab6091d5a5ceae4c2748669d0659501dfa66b1347f7e1634f3adbf1e6b1c37aae609bbc70b31107ce1eacf4761ed09d919b1a71d11baa3f79b94d24f1
ripemd128 => 3ee49d45c2f9ec77bb39a6a29569663e
ripemd160 => 1d7d19bdbe034b8bd611042f8edb55aa8b6d05e4
ripemd256 => 7b089b287a192245a5c0c8591d5c2ed98248a787639902654f8446b42c0f258b
ripemd320 => f493195c3dfca08e42ed78403eed74e6997a8728e0cd95c33745f5207ac95cdacb68ec65ee4bf4e9
whirlpool => ba74027a5597e9af0dc4463562d03cf793435223619ac972aab58fae09fb9dcc604d06a0a2d6ef08b370bee26a11241f923494a8168bc07a093a7c4247752e74
tiger128,3 => a8d42bebcba55ae2122b024d42950cc0
tiger160,3 => 3a39a524ae0d95497953abd85f8789fed89dd148
tiger192,3 => 1b9000939041c3a062542f1ba6cfa7468fd12ca3dfb27eb4
tiger128,4 => 30e2783e192892b264cbf874bef01fe7
tiger160,4 => a773b951d8bc513c376b10d7410a942d4a9481d0
tiger192,4 => a87d8642883c089a5d3bba866a10c6c9f020c93b2b212e08
snefru => 5055d3627109b60ca2282a23a69b5667ef0bac5ce97d152cad9d0b218d6c1c57
gost => f15fe74cc0ce8b20937404fd5dceee19a5141b8172014cf1f2e2721915021526
adler32 => 0abc0248
crc32 => 44f03d85
crc32b => 3207591a
haval128,3 => b2f45056c82502f4b533230cfada72ff
haval160,3 => 18e196ca1065f13f481d21942c96485dba8ad660
haval192,3 => a6043af26f30ef0fd2a123d208a7f7301d541ae1c8e7ce3f
haval224,3 => b210b70701b80a1534268182e9dc96cadb5dd741bca45b0212c27e79
haval256,3 => c0ae630d0a85cc817083284a1abe29d6910f9336c6877a8efe13434e70936db4
haval128,4 => 25af3633e1af7f6140a2610ee64c4495
haval160,4 => 7f6204854d8e8932324dd670912492da37fe9d0f
haval192,4 => 6cdcf6775f33dce2e2733435628683b1bf7b338b0f1c1437
haval224,4 => de8240dc4402666410de619dd83d6589dcdcca1b39b8b679a1b1d22d
haval256,4 => 83dee3d5886e148e93800b01f7d96bbaf8ab8a0691d2e182865cb5b55947542c
haval128,5 => 8a6ddf70531bdb18715fbc1ff0ff3e65
haval160,5 => 7a9c0cb7c91a10a6b9864fe58866a5cc19f4f16c
haval192,5 => 8189cdab2b8fd932977517e64f84aa2f6586c28edc1b2453
haval224,5 => 9f62b2c730da14bcf9edfc14ce58c225695a4fb6988079b7a3ce8cdd
haval256,5 => 4fa308845bb7087c0bb732f674c67a9aa84fd9ed2a1a9cc7375e216d6af3ace6



posted by lightbox at 2013-06-01 13:04 | PHP | このブログの読者になる | 更新情報をチェックする

2011年06月11日


Pear を使用してダウンロード時のみ zip 圧縮してブラウザにデータを送る( プログレスバーはでません )

Pear のインストールは Windows 環境で Pear のインストール を参照して下さい。インストールは Windows ベースですが、Pear ディレクトリ内のライブラリをレンタルサーバーにアップロードして動作させる事ができます。

※ zip 圧縮には、File_Archive が必要です

このサンプルでは、相対参照によるファイルのパス一覧を配列にセットする事によって全てを zip 圧縮してダウンロードさせます

$files[] = "./" の指定で、中にあるサブフォルダも対象となります。

圧縮という仕様上、ファイルサイズを content-length で送る事ができないので、ダウンロード時にプログレスバーが出る事はありません。どうしても必要な場合は、zip ファイルを一時名でサーバーで作成して、そのファイルを読み込んでダウンロードすれば良いと思いますが、効率が良いとはけっして言えないので小さなファイルならばこれで十分だと思います
<?php
// *********************************************
// PHP 5.3 以降で必要
// *********************************************
error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE );

// *********************************************
// Pear ライブリを使用する為に、include パスを設定し、
// 必要なライブラリを読み込む
// *********************************************
set_include_path( "c:/php5217/PEAR" );
require_once "File/Archive.php";

// *********************************************
// 圧縮レベル
// "zipCompressionLevel"
//		Value between 0 and 9 specifying the default 
//		compression level used by Zip writers 
//		(0 no compression, 9 highest compression)
//		Default: 9
// *********************************************
File_Archive::setOption('zipCompressionLevel', 9);

// ダウンロード用アーカイブを決定
$zip = File_Archive::toArchive(
	"zip_sample.zip",
	File_Archive::toOutput()
);

// このディレクトリそのものを追加する
$files[] = "./";
// 別のディレクトリのファイルを追加
$files[] = "../../twitter/callback.php";

File_Archive::extract( 
	$files, $zip
);

?>


※ 単独ファイルの場合は、二つ以上の上の階層まで読みだせるのですが、
※ ディレクトリの場合は、一つ上の階層までしか読めませんでした。
※ ディレクトリが読める場合は、"*.php" のようなワイルドカードを指定できます


▼ 以下は、setOption のオプションの一覧です
"cache"
	Instance of a Cache_Lite object used to cache
	some compressed	data to speed up future compressions
	of files
	Default: null (no cache used)

"zipCompressionLevel"
	Value between 0 and 9 specifying the default
	compression level used by Zip writers
	(0 no compression, 9 highest compression)
	Default: 9

"gzCompressionLevel"
	Value between 0 and 9 specifying the default
	compression level used by Gz writers 
	(0 no compression, 9 highest compression)
	Default: 9

"tmpDirectory"
	Directory where the temporary files generated by
	File_Archive will be created
	Default: '.'

"appendRemoveDuplicates"
	If set to true, the appender created will by 
	default remove the file present in the archive when
	adding a new one. This will slow the appending of
	files to archives
	Default: false

"blockSize"
	To transfer data from a reader to a writer, some
	chunks a read from the source and written to the
	writer. This parameter controls the size of the	chunks
	Default: 64kB

"cacheCondition"
	This parameter specifies when a cache should be used.
	When the cache is used, the data of the reader is
	saved in a temporary file for future access.The cached
	reader will be read only once, even if you read
	it several times.This can be usefull to read compressed
	files or downloaded files (from http or ftp)
	The possible values for this option are
	 - false: never use cache
	 - a regexp: A cache will be used if the specified
		URL matches the regexp
	preg_match is used
	Default: false
	Example: '/^(http|ftp):\/\//' will cache all files
		downloaded via http or ftp

以下は、動的な単独ファイルの追加と、配列の変わりに File_Archive::readMultiを使用しています
<?php
// *********************************************
// PHP 5.3 以降で必要
// *********************************************
error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE );

// *********************************************
// Pear ライブリを使用する為に、include パスを設定し、
// 必要なライブラリを読み込む
// *********************************************
set_include_path( "c:/php5217/PEAR" );
require_once "File/Archive.php";

// *********************************************
// 圧縮レベル
// "zipCompressionLevel"
//		Value between 0 and 9 specifying the default 
//		compression level used by Zip writers 
//		(0 no compression, 9 highest compression)
//		Default: 9
// *********************************************
File_Archive::setOption('zipCompressionLevel', 9);

// ダウンロード用アーカイブを決定
$zip = File_Archive::toArchive(
	"zip_sample.zip",
	File_Archive::toOutput()
);

// 動的な追加
$zip->newFile("mydata/readme.txt");
$zip->writeData( "My name is lightbox." ); 
$zip->close();

File_Archive::extract( 
	File_Archive::readMulti(
		array(
			// このディレクトリそのものを追加する
			File_Archive::read('./'),
			// 別のディレクトリのファイルを追加
			File_Archive::read('../../twitter_api/GetAccessToken/phase_1.php'),
			// 一つ上のディレクトリの内容を追加
			File_Archive::read('../twitter/*.php' )
		)
	), $zip
);

?>




posted by lightbox at 2011-06-11 20:01 | PHP | このブログの読者になる | 更新情報をチェックする

Windows 環境で Pear のインストール

2013 年 : Pear インストール / Mail パッケージと実行サンプル( GMail でメール送信 )

Pear は、いったんダウンロードしてしまえば、それを別の環境に単純コピーでインストールする事ができます。それは、レンタルサーバでも同じでアップロードするだけで動作します。

ただ、いずれかのバージョンから go-pare.bat を実行する必要があるので、PHP のサイトより、5.2.17 をダウンロードし、c:\php5217 の中に php-cgi.exe がある環境を作り、そのフォルダ内をカレントとして go-pare.bat を実行しています。
http://pear.php.net/go-pear.phar をダウンロードして、php go-pear.phar と実行します
( PHP 5.2.17 VC6 x86 Non Thread Safe )


system か local の違いは、Windows のディレクトリに ini ファイルを作るかどうかですが、インストール元が欲しいだけなので、local を入力してやると、pear.ini がこのフォルダの中に作成されます。後は、Enter でインストールが開始されます。



警告が出ていますが、インストールは成功しているので Enter で続行します。



また、警告が出ていますが、インストールは成功しているので Enter で終了します。



pear.bat で、このままパッケージ処理をしようとすると、警告がでるので、こちらは対処方法がメッセージで表示されるので、その通りにチャネルの更新を行います。
pear channel-update pear.php.net

パッケージの正しい文字列は pear search File のように文字列の一部分から一覧を表示する事ができるので、パッケージ名を取得し、インストールします

( 例 : pear install -f -a -o File_Archive )

インストールのオプションは、pear help install で表示する事ができます
( -o はいらないと思いますが、一応念のためです )
-f, --force
	will overwrite newer installed packages
-l, --loose
	do not check for recommended dependency version
-n, --nodeps
	ignore dependencies, install anyway
-r, --register-only
	do not install files, only register the package as installed
-s, --soft
	soft install, fail silently, or upgrade if already installed
-B, --nobuild
	don't build C extensions
-Z, --nocompress
	request uncompressed files when downloading
-R DIR, --installroot=DIR
	root directory used when installing files
	(ala PHP's INSTALL_ROOT), use packagingroot for RPM
-P DIR, --packagingroot=DIR
	root directory used when packaging files, like RPM packaging
--ignore-errors
	force install even if there were errors
-a, --alldeps
	install all required and optional dependencies
-o, --onlyreqdeps
	install all required dependencies
-O, --offline
	do not attempt to download any urls or contact channels
-p, --pretend
	Only list the packages that would be downloaded
※ インストールとは関係ありませんが、PHP 5.3 以降では ※ error_reporting(E_ALL & ~E_DEPRECATED); を実行しておかないと ※ 実行時に警告が出るライブラリがあります ▼
Deprecated: Assigning the return value of new by reference is deprecated 
▼ 警告発生例( 5.3 以降でしか使わない場合は =& を = に変更しても良い )
$tmp =& new File_Archive_Reader_ChangeName_AddDirectory(
	$realSymbolic,
	$result
);



posted by lightbox at 2011-06-11 18:04 | PHP | このブログの読者になる | 更新情報をチェックする

2009年12月15日


PHP : php-5.3.1 の日付関数の注意点

PHP のマニュアル( date 関数 )には以下のように記述されています。
すべての日付/時刻関数は、有効なタイムゾーンが設定されていない場合にE_NOTICE を発生させます。また、システム設定のタイムゾーンあるいは環境変数 TZ を使用した場合には E_STRICT あるいは E_WARNING を発生させます。
で、結論として 5.3.1 で 以下のようなメッセージが出力されます
PHP 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 ' 
Asia/Tokyo' for '9.0/no DST' instead in Command line code on line 1
マニュアルの記述には、バージョンによる変更履歴が書かれていますが、少なくとも、Windows 版では事実と一致しないようで、5.2.11 だとワーニングは出ません。どちらも php.ini 無しのデフォルトでテストしました。 結局、5.3.1 の場合は、PHP.ini に以下を設定します。 ( timezone の確認は、コマンドプロンプトから php --ri date でもできます )
[Date]
date.timezone = Asia/Tokyo
関連する記事 PHP のバージョンを 5.2 から 5.4 へ変更したところ、個別に date_default_timezone_set を実行するように言われました。
posted by lightbox at 2009-12-15 15:12 | PHP | このブログの読者になる | 更新情報をチェックする

2009年09月02日


PHP : 暗号化と複合( libmcrypt )

VB.NET でやるのも少し面倒そうだったので。バッチ処理でパスワードがバレバレになるのを防ぐ為に、まずは暗号化のテストです。途中の暗号化された文字列をbase64 でエンコードして取り出して使用します。
( こんな感じ : YjAbG+kJK/Lf4DL+0vlStkAk0cKP8+VZBZ6kIQ== )
<?
// phpinfo() で確認できたアルゴリズム
// cast-128 gost rijndael-128 twofish arcfour cast-256 loki97 rijndael-192
// saferplus wake blowfish-compat des rijndael-256 serpent xtea blowfish 
// enigma rc2 tripledes 

// php_mcrypt

	// 暗号モジュールをオープンします
	// マニュアルのディレクトリ指定は動作しませんでした
	// おそらく、libmcrypt.dll は、php と同じ場所で動作するようです
	// php 4.4.4 では全て同じディレクトリに入れて動きました。
	$td = mcrypt_module_open('rijndael-256', '', 'ofb', '');

	// mcrypt_enc_get_iv_size($td) で取得できる長さの文字列
	$iv = "12345678123456781234567812345678";
	$ks = mcrypt_enc_get_key_size($td);

	// キーを作成します
	$key = substr(md5('とても大事なキーです'), 0, $ks);

	// 暗号化処理を初期化します
	mcrypt_generic_init($td, $key, $iv);

	// データを暗号化します
	$encrypted = mcrypt_generic($td, 'とてもとても大事なデータです');

	// 暗号化ハンドラを終了します
	mcrypt_generic_deinit($td);

	// 復号用の暗号モジュールを初期化します
	$iv = "12345678123456781234567812345678";
	mcrypt_generic_init($td, $key, $iv);

	// 暗号化された文字列を復号します
	$decrypted = mdecrypt_generic($td, $encrypted);

	// 復号ハンドルを終了し、モジュールを閉じます
	mcrypt_generic_deinit($td);
	mcrypt_module_close($td);

	// 文字列を表示します
	echo trim($decrypted) . "\n";

?>


プログラムではそれを複合して元に戻して使おうというわけです。$iv は、モジュールを初期化する文字列でなんでもいいみたいなので、PHP マニュアルのサンプルで使用されていた関数を使用せずに適当な文字列を使用しています。しかし、この文字列と秘密のキーと二つ無いと復号はできません。

動作環境は、けっこう適当でバグ持ちのようで、WEB で古い記事を見ると前からそんな感じみたいです。Windows モジュールってけっこうこういうのは多いみたいですね

php5 でテストした後、php4.4.4 でもテストしています。これは、Bambalam PHP EXE Compiler を使って秘密のキーを隠蔽しようと思ってるからなんですが、テストはこれからです


タグ:PHP
posted by lightbox at 2009-09-02 23:24 | PHP | このブログの読者になる | 更新情報をチェックする

2009年08月02日


begin で始まるテキストで添付されたファイル(uuencode)を元に戻す方法

単純に PHP の convert_uudecode で戻ります。

1) メールソフトから begin と end の行を除いた間の行をコピー
2) テキストファイルとして保存する( LF 改行にして下さい )
3) PHP の以下のコードを実行する( 02.txt が対象ファイル )
<?
$a = file_get_contents( "C:\\TMP\\uu\\02.txt" );
$b = convert_uudecode( $a );
file_put_contents( "C:\\TMP\\uu\\02.jpg", $b );
?>

最初何事かと思いましたが、単純でした。


タグ:トラブル
posted by lightbox at 2009-08-02 03:18 | 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 ドロップシャドウの参考デモ
PHP正規表現チェッカー
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり