SQLの窓

2017年05月19日


Windows で Laravel を試す際、PHP の Windows バージョンが 5.6.30 なので、Laravel 5.2 をインストールします

おそらくは、5.4 でも動作するのでは無いかと思いますが、世の中の情報がそれほど最新に対応してるわけでも無く、最新だと、ルーティングするファイルも違うので Laravel 5.2 でテストを行いました。

Laravel 5.2 公式ページ(英文)
バージョン対象PHP バージョンBladeテンプレートルーティングリリース
5.4PHP >= 5.6.4OKroutes/web.php2017/1/24
5.3PHP >= 5.6.4OKroutes/web.php2016/8/23
5.2PHP >= 5.5.9OKapp/Http/routes.php2015/12/21
5.1PHP >= 5.5.9OKapp/Http/routes.php2015/6/9
5.07 > PHP >= 5.4なしapp/Http/routes.php2015/2/4
Laravel 5.2 日本語ドキュメントページ

composer global ... による Laravel のインストール

試してみましたが、これは最新の Larvel がインストールされるため、laravel new ... でプロジェクトを作成する方法はできません。以下のように Composer で行う必要があります。
composer create-project --prefer-dist laravel/laravel プロジェクト名 "5.2.*"
※ プロジェクト名は英数字 上記コマンドは長いので、以下のようなバッチファイルにして php がインストールされているフォルダに保存するといいでしょう ( Composer のインストールで、php インストールフォルダにパスが通っているはずなので )
@echo off
composer create-project --prefer-dist laravel/laravel %1 "5.2.*"

※ laravelx.bat だとすると、laravelx プロジェクト名 で実行できます

それ以降は、一般的な情報通りに、プロジェクトディレクトリでコマンドプロンプトを開いて、以下のコマンドを実行します。
php artisan serve
※ Larvel のインストールされたバージョンの確認は、php artisan -V で確認 ※ Composer のインストールで、PHP のディレクトリが検索パスに追加されています Larvel 5.2 のドキュメントでは、php artisan serve の記述がなくなっていますが、5.3 では復活しています。5.3 では、Homestead も使えますよと一行だけ書かれていますが、Homestead が主流にはなりえなかったのでしょう。 関連する記事 Laravel を試す為に Windows に Composer をインストール
タグ:PHP Laravel
posted by lightbox at 2017-05-19 09:34 | Comment(0) | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2017年05月09日


Laravel を試す為に Windows に Composer をインストール

Composer をインストールする

ちゃんと、『プログラムと機能』に登録されるのをインストール後に確認して下さい。



ダウンロード

ダウンロードは、Dependency Manager for PHP からダウンロードボタンをクリックして Composer-Setup.exe よりダウンロードします。



インストール事前チェック

インストーラを実行前に、php の場所を確認して、php.ini の extension=php_openssl.dll を有効にしておいてください。





インストール後チェック

インストール終了すると、システム用パス環境変数の最後にインストール場所が追加されているので確認して下さい。(後々の都合上、php のパスも登録されるので、既に登録している場合はどちらかを削除するといいです)

ユーザのほうにも登録されますが、vendor\bin というフォルダは最初は存在しません。しかし、Conposer でインストールした Laravel がここにインストールされる予定(最新版しかここには登録できないようなので、Laravel のインストールは毎回 Conposer を使うしかありません)です。

※ pathx コマンドはこちらを参照して下さい



C:\ProgramData\ComposerSetup\bin にインストールされ、composer.bat と composer.phar と composer という3つのファイルが保存され、composer.bat が windows から呼び出されます。

最終確認

コマンドプロンプトを開いて、composer と入力して以下のようになれば OK です



関連する記事

Windows で Laravel を試す際、PHP の Windows バージョンが 5.6.30 なので、Larvel 5.2 をインストールします




タグ:PHP Laravel Conposer
posted by lightbox at 2017-05-09 21:50 | Comment(0) | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2016年11月05日


スマホ対応、サーバインデックス表示パッケージ( jQuery + Bootstrap(css) + mmenu + PHP )



 

こちらからアクセスできます



左は通常のログイン前の表示で、右はログイン後の表示です。ログイン後は、フォルダから下の全てのファイルを zip 書庫でダウンロード可能になります。また、下部のパスが、ドキュメントルートからの表示になります。( logout と入力するとログアウトされます )

インストールは、好きな場所に保存して、このインデックスを表示したい最上位フォルダに .htaccess を置いて
DirectoryIndex /toolbox/data2/index/files.php
のように、保存したパスを DirectoryIndex で指定するだけです
実行するカレントフォルダは保存した場所となりますが、呼び出されるのは各フォルダから呼び出されるので、$_SERVER['REQUEST_URI'] となり、その場所を使ってフォルダ・ファィルの一覧を表示しています。
files.php ログインパスワードは、files.php に以下のように指定します
<?php
session_cache_limiter('nocache');
session_start();
$GLOBALS['pass'] = 'パスワード';

require_once("view_main.php");
?>


session_cache_limiter('nocache') は、キャッシュを使用しないヘッダをブラウザに返すようにする処理です。

セッションを使ったログインの処理は、new FormData() で作成した FormData オブジェクトを使用して、jQuery の $.ajax で呼び出しています。

戻りの JSON オブジェクトは、json_encode($_POST) によって、view_main.php が返しています。そして、ログインが成功したら、location.reload(true) でページをリロードしてセッションの処理を有効化します。

view_main.php
<?php
// REQUEST_URI は呼び出し元のパス
$GLOBALS['path'] = explode("?", $_SERVER['REQUEST_URI']);
require_once("download.php");

// *************************************
// フォルダ内を全て zip でダウンロード
// *************************************
if ( $_GET['download'] != "" ) {
	if ( $_SESSION['login'] == 'yes' ) {
		$result = download();
	}
	else {
		header( "Content-Type: text/html; charset=utf-8" );
		print "ログインされていません";
	}
	exit();
}

// *************************************
// ログイン処理
// 1) ダウンロード可能
// 2)パスを DOCUMENT_ROOT で表示
// *************************************
if ( $_GET['login'] == "yes" ) {
	header( "Content-Type: application/json; charset=utf-8" );
	if ( $_POST['pass'] == $GLOBALS['pass'] && $GLOBALS['pass'] != "" ) {
		$_SESSION['login'] = 'yes';
		$_POST['login'] = 'yes';
	}
	else {
		// ログアウト
		if ( $_POST['pass'] == 'logout' ) {
			// セッションをクリア
			$_SESSION = array();
			$_POST['login'] = 'logout';
		}
		else {
			$_POST['login'] = 'no';
		}
	}
	// ブラウザへ JSON 文字列で結果を返す
	print json_encode($_POST);
	exit();
}

header( "Content-Type: text/html; charset=utf-8" );

// *************************************
// 表示コントロール
// *************************************
$GLOBALS['title'] = "インデックス";
$GLOBALS['comment'] = $_SERVER['DOCUMENT_ROOT'] . rtrim($GLOBALS['path'][0],"/");
$GLOBALS['root_script'] = "files.php";

// 表示するファイルの一覧は DOCUMENT_ROOT + REQUEST_URI
$handle = @opendir($GLOBALS['comment']);
$files = array();	// 全ての一覧をソートしたものが入る
$files2 = array();	// ファイルのみが入る
while( $target = readdir( $handle ) ) {
	$files[] = $target;
}
sort($files);
foreach ( $files as $file ) {

	// 対象外は読み飛ばし
	if ( $file == '.' || $file == '..' ) {
		continue;
	}
	if ( $file == ".htaccess" ) {
		continue;
	}
	// フォルダ
	if ( is_dir($GLOBALS['comment'] . "/" .$file) ) {

		// ダウンロード用のフォルダパス
		$path = urlencode($_SERVER['REQUEST_URI']);

		if ( $_SESSION['login'] == 'yes' ) {
			$GLOBALS["data"] .= <<< FILES

				<tr>
					<td><a class="link" href="./{$file}/">[{$file}]</a></td>
					<td></td>
					<td><a class="link" href="./?download={$file}">ダウンロード</a></td>
				</tr>

FILES;
		}
		else {
			$GLOBALS["data"] .= <<< FILES

				<tr>
					<td><a class="link" href="./{$file}/">[{$file}]</a></td>
					<td></td>
					<td></td>
				</tr>

FILES;
		}
	}
	else {
		$files2[] = $file;
	}
}

// ファイルのタイプの取得用
$finfo = finfo_open(FILEINFO_MIME_TYPE);
foreach ( $files2 as $file ) {

	$size = filesize($GLOBALS['comment'] . "/" . $file);
	$type = finfo_file($finfo, $GLOBALS['comment'] . "/" . $file);

	// urlencode されたファイル名の対応(元々は日本語ファイル名)
	$file_e = urlencode($file);

	// ファイル一覧用 HTML
	$GLOBALS["data"] .= <<< FILES

			<tr>
				<td><a href="{$file_e}">{$file}</a></td>
				<td>{$size}</td>
				<td>{$type}</td>
			</tr>

FILES;

}
finfo_close($finfo);



?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta content="width=device-width initial-scale=1.0 minimum-scale=1.0 maximum-scale=1.0 user-scalable=no" name="viewport">
<meta charset="utf-8">
<title><?= $GLOBALS['title'] ?></title>

<?php require_once("std/libs.php") ?>

<?php require_once("std/css.php") ?>

<style>
legend {
	font-size: 18px;
	padding-left: 6px;
}

.table-responsive td, .table-responsive th {
	white-space: nowrap;
}

#data {
	margin-bottom: 20px;
}
#comment {
	word-break: break-all;
}

#pass {
	padding: 20px;
	margin: 40px;
}
#system {
	width: 200px;
	margin-right: 8px;
}
</style>

<script>
<?php require_once("std/js.php") ?>

$(function(){

	// スマホでロード時の処理のチラつき防止用
	$("#wrapper").css("visibility","visible");

	$("#system_login").on("click", function(){
		var formData = new FormData();
		formData.append("pass", $("#system").val() );
		$.ajax({
			url: "./?login=yes",
			type: "POST",
			data: formData,
			processData: false,  // jQuery がデータを処理しないよう指定
			contentType: false   // jQuery が contentType を設定しないよう指定
		})
		.done(function( data, textStatus ){
			console.log( "status:" + textStatus );
			console.log( "data:" + JSON.stringify(data, null, "    ") );

			if ( data.login == 'yes' || data.login == 'logout' ) {
				location.reload(true);
			}

		})
		.fail(function(jqXHR, textStatus, errorThrown ){
			console.log( "status:" + textStatus );
			console.log( "errorThrown:" + errorThrown );

		})
	});
	

	// **************************************
	// mmenu
	// **************************************
	$("#mmenu_left").mmenu({
		navbar: {
			title: "メニュー"
		},
		offCanvas: {
			position  : "left",
			zposition : "next"
		}
	});


});

</script>
</head>
<body>

<div id="wrapper">
<script>
// スマホでロード時の処理のチラつき防止用
$("#wrapper").css( "visibility", "hidden" );
</script>

	<div id="head">
		<?php require_once("std/view_hamburger.php") ?>
		<div id="title"><?= $GLOBALS['title'] ?></div>
	</div>

	<div id="body">
		<form id="frm" class="form-inline">

			<div style='margin:10px;'>
				<a href="../">親フォルダ</a>
			</div>

			<div id="data" class="table-responsive">

				<table class="table table-condensed table-hover">
					<tr>
						<th style='width:200px;'>ファイル名</th>
						<th style='width:80px;'>サイズ</th>
						<th>MIME</th>
					</tr>

					<?= $GLOBALS["data"] ?>

				</table>
			</div>

			<fieldset>
				<legend></legend>
				<table class="table table-condensed">

					<tr><td class="fields result error" id="erow1"><?= $GLOBALS['error'] ?></td></tr>
					<tr><td class="fields result error" id="erow2"></td></tr>

				</table>

			</fieldset>

		</form>
	</div>

	<div id="comment">
<?php
if ( $_SESSION['login'] == 'yes' ) {
	print $GLOBALS['comment'];
}
else {
	print str_replace($_SERVER['DOCUMENT_ROOT'],"",$GLOBALS['comment']);
}

?>
	</div>

	<div id="pass" class="input-group">
		<input type="password" id="system" class="form-control">
		<input type="button" value="管理者" id="system_login" class="btn">
	</div>

</div>


<?php require_once("unit_menu.php") ?>


</body>
</html>



download.php

ログインしていないと、download 関数が呼ばれる事はありません。

recursionFiles は再帰関数です。glob でフォルダが無くなるまで全ての階層を展開して、戻り値にその値を返して親でマージするので、戻って来た内容はだんだん多くなり、最後に全てのファイルのパスが取得されます。

$zip->addFile で追加する場合、第二引数で書庫内のパスを対象とするフォルダとする為、$rpath_exclude にあらかじめ対象フォルダの realpath をセットしておいて、その部分を消去して $zip->addFile に渡しています。
<?php

// ***********************************************
// フォルダを全て書庫化してダウンロード
// ***********************************************
function download() {

	$_GET['download'] = str_replace('/','',$_GET['download']);
	$_GET['download'] = str_replace('..','',$_GET['download']);
	$_GET['download'] = str_replace('.','',$_GET['download']);
	$rpath = $_SERVER['DOCUMENT_ROOT']  . rtrim($GLOBALS['path'][0],"/") . "/" . $_GET['download'];
	$rpath_exclude = $rpath . "/";

	if ( rtrim($GLOBALS['path'][0],"/") == '' ) {
		print "REQUEST_URI is Incorrect";
	}

	// ファイルは対象外(存在チェックも行う)
	if ( !is_dir($rpath) ) {
		print rtrim($GLOBALS['path'][0],"/") . "/" . $_GET['download'] . " not found or not dir";
		return false;
	}

	// ***********************************************
	// readfile 用、バッファ解除
	// ***********************************************
	ob_end_clean();

	// ***********************************************
	// 対象フォルダ名
	// ***********************************************
	$target_dir = $rpath;

	// ***********************************************
	// 書庫ファイル名
	// ***********************************************
	$zipname = basename( $target_dir );

	// ***********************************************
	// 一時ファイルを作成 ( temp/oooooo.tmp )
	// ***********************************************
	$file = tempnam( sys_get_temp_dir(), "zip" ); 

	// ***********************************************
	// ZIP 書庫作成
	// ***********************************************
	$zip = new ZipArchive(); 

	$zip->open($file, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE ); 

	$targets = recursionFiles( $target_dir );

	foreach( $targets as $target ) {
		$zip->addFile( $target, str_replace($rpath_exclude,"", $target) );
	}

	$zip->close(); 

	// ***********************************************
	// ダウンロードさせる為の処理
	// ***********************************************
	header("Content-Type: application/zip"); 
	header("Connection: close");
	header("Content-Length: " . filesize($file)); 
	header("Content-Disposition: attachment; filename=\"{$zipname}.zip\""); 
	readfile($file); 


	// ***********************************************
	// 一時ファイルを削除
	// ***********************************************
	unlink($file); 

	return true;

}


// ***********************************************
// 再帰によるファイル一覧作成
// ***********************************************
function recursionFiles( $target ) {

	$files = glob( "{$target}/*" );
	$result = array();

	foreach ( $files as $file ) {
		// ファイル
		if (is_file($file)) {
			if ( basename($file) != "files.php" ) {
				$result[] = $file;
			}
		}
		// フォルダ
		else {
			$result = array_merge($result, recursionFiles($file));
		}
	}

	return $result;
}


?>




posted by lightbox at 2016-11-05 21:29 | Comment(0) | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2016年05月29日


超簡易掲示板 : 保存タイプは CSV





board.php、model.php、view.php の 3 ファイルで動作します。json.php が同梱されていますが、出力ファイルである board.csv を JSON 形式で取得する為のコードです。( JavaScript からアクセスする場合は、header( "Access-Control-Allow-Origin: *" ); を追加して下さい )

他のアプリケーションからのアクセスを簡単にテストできる仕様になっています。

board.php
<?php
// **************************************
// php.ini の output_buffering をチェックして
// 有効になっていた場合は、header の前に出力可能です
// **************************************

// **************************************
// 通常の HTML として出力します
// **************************************
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" );

// **************************************
// 関数の定義を読み込みます
// **************************************
require_once("model.php");

// **************************************
// $_POST['send'] != "" は送信ボタンが
// クリックされた事を示します
// さらに、テキストエリアに何か入力され
// た場合に処理を行います
// **************************************
$_POST['text'] = preg_replace( "/^[ \s]+/u", "", $_POST['text'] );
$_POST['text'] = preg_replace( "/[ \s]+$/u", "", $_POST['text'] );
if ( $_POST['send'] != "" && $_POST['text'] != "" ) {

	// データの書き込み処理
	post_data();

}

// *************************************
// データの表示処理
// *************************************
disp_data();


// **************************************
// ▼ 以下は画面です。$log_text を
//    埋め込んでいます
// **************************************
require_once("view.php");
?>


model.php
<?php

// **************************************
// データの書き込み処理
// **************************************
function post_data() {

	// データを一括読み込み
	$log_text = @file_get_contents("board.csv");

	// **************************************
	// 本文中の改行コードを "\n" という
	// 文字列に変換しています
	// **************************************
	$_POST['text'] = str_replace("\r\n","\\n",$_POST['text']);
	$_POST['text'] = str_replace("\n","\\n", $_POST['text'] );
	$_POST['text'] = str_replace("\r","\\n", $_POST['text'] );

	// HTML 要素を無効にする
	$_POST['text'] = str_replace("<","&lt;",$_POST['text']);
	$_POST['text'] = str_replace(">","&gt;",$_POST['text']);

	// HTML 要素を無効にする
	$_POST['subject'] = str_replace("<","&lt;",$_POST['subject']);
	$_POST['subject'] = str_replace(">","&gt;",$_POST['subject']);
	$_POST['name'] = str_replace("<","&lt;",$_POST['name']);
	$_POST['name'] = str_replace(">","&gt;",$_POST['name']);

	// シングルクォートとダブルクォートとカンマ
	$_POST['text'] = str_replace("'","&#39;",$_POST['text']);
	$_POST['text'] = str_replace("\"","&#34;",$_POST['text']);
	$_POST['text'] = str_replace(",","&#44;",$_POST['text']);

	// シングルクォートとダブルクォートとカンマ
	$_POST['subject'] = str_replace("'","&#39;",$_POST['subject']);
	$_POST['subject'] = str_replace("\"","&#34;",$_POST['subject']);
	$_POST['subject'] = str_replace(",","&#44;",$_POST['subject']);
	$_POST['name'] = str_replace("'","&#39;",$_POST['name']);
	$_POST['name'] = str_replace("\"","&#34;",$_POST['name']);
	$_POST['name'] = str_replace(",","&#44;",$_POST['name']);

	$log_wk = "{$_POST['text']},{$_POST['subject']},{$_POST['name']},{$_POST['datetime']}";

	// **************************************
	// 前回データとの境界に改行コードを
	// 設定しています
	// **************************************
	$log_text = $log_wk . "\n" . $log_text;

	// 書き込み
	file_put_contents("./board.csv", $log_text );

	// GET メソッドで再表示します
	header( "Location: board.php" );
	exit();


}

// **************************************
// データの表示処理
// **************************************
function disp_data() {

	// 埋め込み用データを global 宣言
	global $log_text;

	// データを一括読み込み
	$rows = @file("./board.csv");
	// ファイルが存在しない場合
	if ( $rows === false ) {
		$log_text = "ここに投稿データが表示されます";
		return;
	}

	// 表示用の埋め込みに使用される文字列変数
	$log_text = "";
	foreach( $rows as $v ) {

		$data = explode(",", $v);

		// **************************************
		// 本文の改行は br 要素で表現します
		// **************************************
		$row = str_replace("\\n", "<br>\n", $data[0] );

		// **************************************
		// 行毎に表示 HTML を作成
		// **************************************
		$row = "<h3>{$data[1]}</h3>{$row}<br><span class='sb'>({$data[2]} : {$data[3]} )</span><br>";

		// **************************************
		// 記事の境界を hr 要素で表現します
		// **************************************
		$row .= "<hr>\n";

		// **************************************
		// 表示画面全体 を作成
		// **************************************
		$log_text .= $row;
	
	}


}

?>


行データの作成は、以下のように置き換えるとメンテナンスしやすくなります。また、この部分を別ファイルにして require するともっと使いやすくなるでしょう。
		// **************************************
		// 行毎に表示 HTML を作成
		// **************************************
		$row = <<<HTML
		<h3>{$data[1]}</h3>
		{$row}<br>
		<span class='sb'>({$data[2]} : {$data[3]} )</span><br>
HTML;


view.php
<!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>
* {
	font-family: "ヒラギノ角ゴPro W3","Hiragino Kaku Gothic Pro","メイリオ",Meiryo,"MS Pゴシック",Verdana,Arial,Helvetica,sans-serif;
}
body {
	margin: 5px;
}
form {
	padding-right: 5px;
}
.sb {
	font-size: 8px;
}
#text {
	height: 100px;
	width: 500px;
}
#subject,#name {
	width: 400px;
}

@media screen and (max-width:479px) {

	#text {
		width: 100%;
	}
	#subject,#name {
		width: 230px;
	}
	#line_control {
		display: none;
	}
}

</style>

<script>

$( function(){
	$("form").on("submit", function(){

		var dateNow = new Date();
		var dateString = 
			dateNow.getFullYear() + "/" + 
			("0"+(dateNow.getMonth()+1)).slice(-2)+ "/" + 
			("0"+(dateNow.getDate())).slice(-2);
		var timeString = 
			("0"+(dateNow.getHours())).slice(-2) + ":" + 
			("0"+(dateNow.getMinutes())).slice(-2) + ":" + 
			("0"+(dateNow.getSeconds())).slice(-2);

		$("#datetime").val( dateString + " " + timeString );

	});
});

</script>
</head>

<body>
<h3><a href="board.php" style="color:black;">超簡易掲示板 ( CSV )</a></h3>

<form method="POST">
	タイトル <input
		type="text"
		id ="subject"
		name="subject">
	<br>
	名  前 <input
		type="text"
		id ="name"
		name="name">
	<br>
	<textarea
		id ="text"
		name="text"></textarea>
	<input type="hidden"
		id="datetime"
		name="datetime">
	<br>
	<input
		type="submit"
		name="send"
		value="送信">
</form>
<br>

<?= $log_text ?>

</body>
</html>


json.php
<?php
// **************************************
// 通常の HTML として出力します
// **************************************
header( "Content-Type: application/json; charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// データを一括読み込み
$rows = @file("./board.csv");
// ファイルが存在しない場合
if ( $rows === false || $rows[0] == "" ) {
	print '{ "error": "ファイルが存在しません" }';
	exit();
}

// 全ての行用の JSON 用クラス作成
$json = new stdClass;
// 行データを格納する配列を作成
$json->item = array();

foreach( $rows as $v ) {

	$data = explode(",", $v);

	// 新しい行用のクラス作成
	$board_data = new stdClass;

	// text プロパティに 本文をセット
	$board_data->text = $data[0];
	// subject プロパティに タイトルをセット
	$board_data->subject = $data[1];
	// name プロパティに 名前をセット
	$board_data->name = $data[2];
	// subject プロパティに タイトルをセット
	$board_data->datetime = $data[3];

	// 配列の最後に投稿データをセット
	array_push ($json->item, $board_data);


}

print json_encode($json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

?>



posted by lightbox at 2016-05-29 22:21 | Comment(0) | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2016年04月26日


超簡易掲示板 ( JSON ) : PHP





保存データを行単位で区切り文字で分けて投稿データを保存する方法は古くからありますが、JSON 形式で保存しておくと、投稿データ内の改行やクォートなどのデータを自分で処理する必要がなくなる上に、新しい項目も追加するのが容易になります。さらに、データが JSON で作られるので、そのまま http で他のアプリケーションからアクセスする事も容易になります

一応、MVC にのっとり、M(model.php) / V(view.php) / C(board.php) になっています

board.php
<?php
// **************************************
// php.ini の output_buffering をチェックして
// 有効になっていた場合は、header の前に出力可能です
// **************************************

// **************************************
// 通常の HTML として出力します
// **************************************
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" );

// **************************************
// 関数の定義を読み込みます
// **************************************
require_once("model.php");

// **************************************
// $_POST['send'] != "" は送信ボタンが
// クリックされた事を示します
// さらに、テキストエリアに何か入力され
// た場合に処理を行います
// **************************************
$_POST['text'] = preg_replace( "/^[ \s]+/u", "", $_POST['text'] );
$_POST['text'] = preg_replace( "/[ \s]+$/u", "", $_POST['text'] );
if ( $_POST['send'] != "" && $_POST['text'] != "" ) {

	// データの書き込み処理
	post_data();

}

// データの表示処理
disp_data();


// **************************************
// ▼ 以下は画面です。$log_text を
//    埋め込んでいます
// **************************************
require_once("view.php");
?>

FORM は一般的な POST メソッドで送信されます。なので、書き込んだ直後にリダイレクトして GET メソッドで呼び出しなおすという処理が入っています。タイトルの『超簡易掲示板 ( JSON )』をクリックすると、GET メソッドでの呼び出しであるリンクとなっています。

投稿データの表示内容は、いったん文字列で作成して後から view.php の該当部分に埋め込む形式です。最新のデータは、array_unshift によって、データの先頭に追加されます。

HTML 要素を無効にする方法としては、htmlentitieshtmlspecialchars がありますが、初心者向けとして最低限の置き換えを str_replace で実装しています。

json_encode による、オブジェクトから文字列の変換では、オプションの JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT でデバッグしやすいように可読性に重点を置いています。

model.php
<?php

// **************************************
// データの書き込み処理
// **************************************
function post_data() {

	// データを一括読み込み
	$log_text = @file_get_contents("board.log");

	$json = json_decode( $log_text );
	// 空のファイルかまたは、JSON データでは無い場合
	if ( $json === null ) {

		// JSON 用クラス作成
		$json = new stdClass;
		// 行データを格納する配列を作成
		$json->item = array();

	}

	// 改行コードを \n のみ(1バイト)にする
	$_POST['text'] = str_replace("\r","",$_POST['text']);

	// HTML 要素を無効にする
	$_POST['text'] = str_replace("<","&lt;",$_POST['text']);
	$_POST['text'] = str_replace(">","&gt;",$_POST['text']);

	// HTML 要素を無効にする
	$_POST['subject'] = str_replace("<","&lt;",$_POST['subject']);
	$_POST['subject'] = str_replace(">","&gt;",$_POST['subject']);
	$_POST['name'] = str_replace("<","&lt;",$_POST['name']);
	$_POST['name'] = str_replace(">","&gt;",$_POST['name']);

	// 新しい投稿用のクラス作成
	$board_data = new stdClass;

	// text プロパティに 入力された本文をセット
	$board_data->text = $_POST['text'];
	// subject プロパティに 入力されたタイトルをセット
	$board_data->subject = $_POST['subject'];
	// name プロパティに 入力された名前をセット
	$board_data->name = $_POST['name'];
	// subject プロパティに 入力されたタイトルをセット
	$board_data->datetime = $_POST['datetime'];

	// 配列の先頭に 新しい投稿データをセット
	array_unshift($json->item, $board_data);

	// 全ての投稿データを JSON として一括書き込み
	file_put_contents("./board.log", json_encode( $json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT ) );

	// GET メソッドで再表示します
	header( "Location: {$_SERVER["PHP_SELF"]}" );
	exit();


}

// **************************************
// データの表示処理
// **************************************
function disp_data() {

	// 埋め込み用データを global 宣言
	global $log_text;

	// データを一括読み込み
	$log_text = @file_get_contents("./board.log");
	// ファイルが存在しない場合
	if ( $log_text === false ) {
		$log_text = "ここに投稿データが表示されます";
		return;
	}

	$json = json_decode( $log_text );
	// 空のファイルかまたは、JSON データでは無い
	if ( $json === null ) {
		$log_text = "ここに投稿データが表示されます";
		return;
	}

	// 表示用の埋め込みに使用される文字列変数
	$log_text = "";
	foreach( $json->item as $v ) {
	
		// **************************************
		// 本文の改行は br 要素で表現します
		// **************************************
		$v->text = str_replace("\n", "<br>\n", $v->text );

		// **************************************
		// 記事の境界を hr 要素で表現します
		// **************************************
		$v->text .= "<hr>\n";

		// **************************************
		// 行毎に表示 HTML を作成
		// **************************************
		$log_text .= "【{$v->subject}】( {$v->name} : {$v->datetime} ) <br>" . $v->text;
	
	}


}

?>


投稿時の日付データは、ブラウザ側でセットするようにしています。特に日付に関しては JavaScript ではスマートな方法が無いので、学習のきっかけ用としてこのようになっています。また、送信時のイベント処理としても重要なサンプルとなり、jQuery の基本サンプルでもあります。

※ jQuery は、Google のホスティングを使用しています。

view.php
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=1280,initial-scale=1.0">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>

<style>
* {
	font-family: "ヒラギノ角ゴPro W3","Hiragino Kaku Gothic Pro","メイリオ",Meiryo,"MS Pゴシック",Verdana,Arial,Helvetica,sans-serif;
}
</style>

<script>

$( function(){
	$("form").on("submit", function(){

		var dateNow = new Date();
		var dateString = 
			dateNow.getFullYear() + "/" + 
			("0"+(dateNow.getMonth()+1)).slice(-2)+ "/" + 
			("0"+(dateNow.getDate())).slice(-2);
		var timeString = 
			("0"+(dateNow.getHours())).slice(-2) + ":" + 
			("0"+(dateNow.getMinutes())).slice(-2) + ":" + 
			("0"+(dateNow.getSeconds())).slice(-2);

		$("#datetime").val( dateString + " " + timeString );

	});
});

</script>
</head>

<body>
<h3><a href="board.php" style="color:black;">超簡易掲示板 ( JSON )</a></h3>

<form method="POST">
	タイトル <input type="text"
		name="subject"
		style="width:400px;">
	<br>
	名  前 <input type="text"
		name="name"
		style="width:400px;">
	<br>
	<textarea name="text"
		style="width:500px;height:100px;"></textarea>
	<input type="hidden"
		name="datetime" id="datetime">
	<br>
	<input type="submit"
		name="send"
		value="送信">
</form>
<br>

<?= $log_text ?>

</body>
</html>


JSON は、item プロパティが配列になり、複数項目の投稿データが格納されます。

JSON データ
{
    "item": [
        {
            "text": "最低限の機能を持った掲示板です。\nデータ形式は JSON でとても拡張しやすく便利です。",
            "subject": "こんにちは",
            "name": "山田 タロウ",
            "datetime": "2016\/04\/25 17:52:17"
        }
    ]
}


タグ:掲示板 PHP
posted by lightbox at 2016-04-26 12:21 | Comment(0) | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2015年02月14日


PHP による『超簡易掲示板』 / アプリケーションからの POST 検証用



デモページ

2015-02-14 : 更新
コメントを追加して、特殊な文字を無効化しました

2013/01/07 : 更新
Chrome での表示で、\n 埋め込まれているデータを <br /> に変換して、実際に改行して見えるようにしました。

Windows Phone(C#) から使うと、エミュレータ内では取得しにくい長い文字列を LOG 等の目的で出力可能です。

1) Google Chrome から実行すると、『掲示板として動作します』
※ F12 の開発者ツールでデバイスモードにしてから、リセットして UA に適当な文字を入力して再表示すると JSON 表示されます( iPad 等でもいいですが、それではテキスト選択ができません )







2) それ以外のブラウザからだと、表示されるのは JSON です
<?php
// **************************************
// ブラウザの判定をしています
// ( $_SERVER['HTTP_USER_AGENT'] )
// **************************************
$AGENT = "";
if ( strpos( $_SERVER['HTTP_USER_AGENT'], "Chrome") !== false ) {
	$AGENT = "Chrome";
}

// **************************************
// ブラウザが Google Chrome の場合のみ
// 通常の HTML として出力します
// ※ キャラクタセットは UTF-8 です
// **************************************
if ( $AGENT == "Chrome" ) {
	header( "Content-Type: text/html; Charset=utf-8" );
}
else {
	header( "Content-Type: text/plain; Charset=utf-8" );
}

// **************************************
// キャッシュを無効にするヘッダです
// **************************************
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

$log_text = @file_get_contents("./text.log");
// **************************************
// 書き込み処理です
// **************************************
if ( $_POST['send'] != "" && $_POST['text'] != "" ) {
	// **************************************
	// 本文中の改行コードを "\n" という
	// 文字列に変換しています
	// **************************************
	$log_wk = str_replace("\r\n","\\n",$_POST['text']);
	$log_wk = str_replace("\n","\\n", $log_wk );
	$log_wk = str_replace("\r","\\n", $log_wk );

	// **************************************
	// 特殊な文字を無効化します
	// **************************************
	$log_wk = str_replace("&","&amp;",$log_wk);
	$log_wk = str_replace("<","&lt;",$log_wk);
	$log_wk = str_replace(">","&gt;",$log_wk);
	// シングルクォート
	$log_wk = str_replace("'","&#39;",$log_wk);
	// ダブルクォート
	$log_wk = str_replace("\"","&#34;",$log_wk);

	// **************************************
	// 前回データとの境界に改行コードを
	// 設定しています
	// **************************************
	$log_text = $log_wk . "\n" . $log_text;

	file_put_contents("./text.log", $log_text );
	if ( $AGENT == "Chrome" ) {
		// GET メソッドで再表示します
		header( "Location: {$_SERVER["PHP_SELF"]}" );
		exit();
	}
}

// **************************************
// 環境によって必要ありませんが、
// エラー時の設定です
// **************************************
error_reporting(E_ALL ^ E_NOTICE);
ini_set( "display_errors", "1" );

// **************************************
// Chrome 以外では JSON 文字列で返します
// ※ text.log にデータが保存されています
// **************************************
if ( $AGENT != "Chrome" ) {
?>
{
	"item" : [ 
<?php
	$json_data = @file( "./text.log" );

	$cnt = count($json_data);
	for( $i = 0; $i < $cnt; $i++ ) {
		if ( $i != 0 ) {
			print "\t\t,{ \"text\": \"" . chop($json_data[$i]) . "\" }\n";
		}
		else {
			print "\t\t{ \"text\": \"" . chop($json_data[$i]) . "\" }\n";
		}
	}
?>

	]
}
<?
}
else {
	// **************************************
	// 記事の境界を hr 要素で表現します
	// **************************************
	$log_text = str_replace("\n", "<hr style='color:#c0c0c0;'>\n", $log_text );

	// **************************************
	// 本文の改行は br 要素で表現します
	// **************************************
	$log_text = str_replace("\\n", "<br>\n", $log_text );
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=1280,initial-scale=1.0">
</head>

<body>

<form method="POST">
<textarea name="text" style="width:400px;height:100px;"></textarea>
<br>
<input type="submit" name="send" value="送信">
</form>

<?= $log_text ?>
</body>
</html>
<? } ?>

関連する記事

WindowsPhone からの単純なインターネット投稿
コマンドプロンプトから Windows PHP を使って POST 投稿する

関連するオンラインツール

JSON チェック( JSONLint / The JSON Validator )



posted by lightbox at 2015-02-14 11:12 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2014年10月31日


PHP : 既存 GD 関連ライブラリで、背景をグラデーション(2)






開始  終了 
タイプ 
ステップ  


ライブラリ関連のソースコードは、『PHP : 既存 GD 関連ライブラリで、背景をグラデーション』を参照して下さい。グラデーションクラスと、GD 基本クラスを紹介しています。

それらのクラスを使用して実行していますが、PHP 自体を画像としてブラウザに返すコードなので、ここでの実行は、IMG 要素の SRC 属性に QueryString を引き渡して随時実行しています。

※ 今回は、コードの中に他のサイトから実行した場合に以下の画像が表示されるようにするコードを付加しています。

( ▲ クリックすると、フリーフォントで簡単ロゴ作成に移動します )

example_02.php(UTF-8N)
<?php
// ***********************************************
//
//  プログラム名 : グラデーションサンプル(2)
//  作   成   者 : lightbox
//  作   成   日 : 2014/10/31
//
//  概要 : 
//  背景画像としてのグラデーション
//
// ***********************************************
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

require_once('gd_lightbox.php');
require_once('gradient.php');

// ステップの範囲を限定
if ( $_GET['step']+0 > 20 ) {
	$_GET['step'] = 20;
}
if ( $_GET['step']+0 < 0 ) {
	$_GET['step'] = 0;
}
if ( $_GET['type'] == '' ) {
	$_GET['type'] = "horizontal";
}
if ( $_GET['sc'] == '' ) {
	$_GET['sc'] = "#000000";
}
if ( $_GET['ec'] == '' ) {
	$_GET['ec'] = "#ffffff";
}

// グラデーションキャンバスの作成
$gradient = new gd_gradient_fill(400,200,$_GET['type'],$_GET['sc'],$_GET['ec'],$_GET['step']+0);
// サイズ 400x200
$image = $gradient->image;

// GD インスタンス作成
$gd = new GD();

// PNG として設定
$gd->type = "PNG";
// グラデーションを設定
$gd->im = $image;

$site = false;
$target_sites = array("http://toolbox.winofsql.jp/","http://logicalerror.seesaa.net/");
foreach( $target_sites as $target ) {
	$len = strlen( $target );
	$ref = substr( $_SERVER['HTTP_REFERER'], 0, $len );
	if ( $target == $ref ) {
		$site = true;
		break;
	}
}

if ( $site ) {
	// ブラウザへ出力
	$gd->Response();
}
else {
	// ブラウザへ出力
	$gd->LoadPng("site_warning.png");
	$gd->Response();
}
?>


▼ このブログでの実装コード
<script>
if ( !window.jQuery ) {
	document.write("<"+"script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></"+"script>");
}
if ( window[window.location.hostname+'.loadModcoder'] !== true ) {
	window[window.location.hostname+'.loadModcoder'] = true;
	document.write("<"+"script src="http://homepage2.nifty.com/lightbox/modcoder_excolor/jquery.modcoder.excolor.js"></"+"script>");
}
</script>
<script type="text/javascript">
$(function(){
	$(".color_field").modcoder_excolor();
});

function set_gradient() {
	var src = "http://toolbox.winofsql.jp/gradient/example_02.php?step=" + $("#step").val();
	src += "&sc=" + encodeURIComponent($("#sc").val());
	src += "&ec=" + encodeURIComponent($("#ec").val());
	src += "&type=" + $("#gtype").val();
	$("#gradient").prop("src",src);
}
</script>

<style type="text/css">
.color_field {
	width: 80px;
}
</style>
<pre class=w6>
開始 <input id="sc" class="color_field" type="text" readonly value="#000000"> 終了 <input id="ec" class="color_field" type="text" readonly value="#ffffff">
タイプ <select id="gtype">
<option value="horizontal">horizontal</option>
<option value="vertical">vertical</option>
<option value="ellipse">ellipse</option>
<option value="ellipse2">ellipse2</option>
<option value="circle">circle</option>
<option value="circle2">circle2</option>
<option value="square">square</option>
<option value="diamond">diamond</option>
</select>
ステップ <input id="step" type="number" max="20" min="0" value="0"> <input type="button" value="グラデーション" onclick='set_gradient()'>
<img id="gradient" src="https://lh3.googleusercontent.com/-vhWb-RDtIR8/VFNVjqUJ8mI/AAAAAAAAXVU/7wyCb2JipJM/s400/gradient.png" style='border:solid 1px #000000;' onclick='set_gradient()'>
IE がまだ type="color" に対応していないので、カラーピッカーは jQuery のプラグインを使用しています


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

PHP : 既存 GD 関連ライブラリで、背景をグラデーション

画像そのものを php で作成しています。クリックすると、img 要素の中の src の URLに渡す step パラメータが変化します。

▼ クリックするとグラデーションをテストできます。
ステップ  

( せっかくなので、step の入力は HTML5 の type="number" を使用してます / max="20" )

この間作成した、GD を使用した画像の縮小ライブラリと、『PHP and GD : Emulate Gradient Fill』からダウンロードできるグラデーション用ライブラリを使用して GD の背景としてグラデーションを設置するサンプルです。

Emulate Gradient Fill は、そのままでは使え無いので、74行目をコメントにする必要があります。また、テストしやすいようにコンストラクタの引数に全てデフォルトを設定しています。

※ このライブラリは、英語しか使われていないので、そのままで結構ですが、画像の縮小ライブラリと実行サンプルは、UTF-8N で保存しています。

gd_gradient_fill
<?php
/*
Script Name: GD Gradient Fill
Script URI: http://planetozh.com/blog/my-projects/images-php-gd-gradient-fill/
Description: Creates a gradient fill of any shape (rectangle, ellipse, vertical, horizontal, diamond)
Author: Ozh
Version: 1.1
Author URI: http://planetozh.com/
*/

/* Release history :
 * 1.1
 *		- changed : more nicely packaged as a class
 *		- fixed : not displaying proper gradient colors with image dimension greater than 255 (because of a limitation in imagecolorallocate)
 *		- added : optional parameter 'step', more options for 'direction'
 * 1.0
 *		- initial release
 */

/* Usage :
 *
 * require_once('/path/to/gd-gradient-fill.php');
 * $image = new gd_gradient_fill($width,$height,$direction,$startcolor,$endcolor,$step);
 *
 * Parameters :
 *		- width and height : integers, dimesions of your image.
 *		- direction : string, shape of the gradient.
 *		  Can be : vertical, horizontal, rectangle (or square), ellipse, ellipse2, circle, circle2, diamond.
 *		- startcolor : string, start color in 3 or 6 digits hexadecimal.
 *		- endcolor : string, end color in 3 or 6 digits hexadecimal.
 *		- step : integer, optional, default to 0. Step that breaks the smooth blending effect.
 * Returns a resource identifier.
 *
 * Examples :
 *
 * 1.
 * require_once('/home/ozh/www/includes/gd-gradient-fill.php');
 * $image = new gd_gradient_fill(200,200,'horizontal','#fff','#f00');
 *
 * 2.
 * require_once('c:/iis/inet/include/gd-gradient-fill.php');
 * $myimg = new gd_gradient_fill(80,20,'diamond','#ff0010','#303060');
 *
 */


// Test it :
// $image = new gd_gradient_fill(400,200,'ellipse','#f00','#000',0);

class gd_gradient_fill {
	
	// Constructor. Creates, fills and returns an image
	function gd_gradient_fill($w=400,$h=200,$d="horizontal",$s="#000000",$e="#FFFFFF",$step=0) {
		$this->width = $w;
		$this->height = $h;
		$this->direction = $d;
		$this->startcolor = $s;
		$this->endcolor = $e;
		$this->step = intval(abs($step));

		// Attempt to create a blank image in true colors, or a new palette based image if this fails
		if (function_exists('imagecreatetruecolor')) {
			$this->image = imagecreatetruecolor($this->width,$this->height);
		} elseif (function_exists('imagecreate')) {
			$this->image = imagecreate($this->width,$this->height);
		} else {
			die('Unable to create an image');
		}
		
		// Fill it
		$this->fill($this->image,$this->direction,$this->startcolor,$this->endcolor);
		
		// Show it		
//		$this->display($this->image);
		
		// Return it
		return $this->image;
	}
	
	
	// Displays the image with a portable function that works with any file type
	// depending on your server software configuration
	function display ($im) {
		if (function_exists("imagepng")) {
			header("Content-type: image/png");
			imagepng($im);
		}
		elseif (function_exists("imagegif")) {
			header("Content-type: image/gif");
			imagegif($im);
		}
		elseif (function_exists("imagejpeg")) {
			header("Content-type: image/jpeg");
			imagejpeg($im, "", 0.5);
		}
		elseif (function_exists("imagewbmp")) {
			header("Content-type: image/vnd.wap.wbmp");
			imagewbmp($im);
		} else {
			die("Doh ! No graphical functions on this server ?");
		}
		return true;
	}
	
	
	// The main function that draws the gradient
	function fill($im,$direction,$start,$end) {
		
		switch($direction) {
			case 'horizontal':
				$line_numbers = imagesx($im);
				$line_width = imagesy($im);
				list($r1,$g1,$b1) = $this->hex2rgb($start);
				list($r2,$g2,$b2) = $this->hex2rgb($end);
				break;
			case 'vertical':
				$line_numbers = imagesy($im);
				$line_width = imagesx($im);
				list($r1,$g1,$b1) = $this->hex2rgb($start);
				list($r2,$g2,$b2) = $this->hex2rgb($end);
				break;
			case 'ellipse':
				$width = imagesx($im);
				$height = imagesy($im);
				$rh=$height>$width?1:$width/$height;
				$rw=$width>$height?1:$height/$width;
				$line_numbers = min($width,$height);
				$center_x = $width/2;
				$center_y = $height/2;
				list($r1,$g1,$b1) = $this->hex2rgb($end);
				list($r2,$g2,$b2) = $this->hex2rgb($start);
				imagefill($im, 0, 0, imagecolorallocate( $im, $r1, $g1, $b1 ));
				break;
			case 'ellipse2':
				$width = imagesx($im);
				$height = imagesy($im);
				$rh=$height>$width?1:$width/$height;
				$rw=$width>$height?1:$height/$width;
				$line_numbers = sqrt(pow($width,2)+pow($height,2));
				$center_x = $width/2;
				$center_y = $height/2;
				list($r1,$g1,$b1) = $this->hex2rgb($end);
				list($r2,$g2,$b2) = $this->hex2rgb($start);
				break;
			case 'circle':
				$width = imagesx($im);
				$height = imagesy($im);
				$line_numbers = sqrt(pow($width,2)+pow($height,2));
				$center_x = $width/2;
				$center_y = $height/2;
				$rh = $rw = 1;
				list($r1,$g1,$b1) = $this->hex2rgb($end);
				list($r2,$g2,$b2) = $this->hex2rgb($start);
				break;
			case 'circle2':
				$width = imagesx($im);
				$height = imagesy($im);
				$line_numbers = min($width,$height);
				$center_x = $width/2;
				$center_y = $height/2;
				$rh = $rw = 1;
				list($r1,$g1,$b1) = $this->hex2rgb($end);
				list($r2,$g2,$b2) = $this->hex2rgb($start);
				imagefill($im, 0, 0, imagecolorallocate( $im, $r1, $g1, $b1 ));
				break;
			case 'square':
			case 'rectangle':
				$width = imagesx($im);
				$height = imagesy($im);
				$line_numbers = max($width,$height)/2;
				list($r1,$g1,$b1) = $this->hex2rgb($end);
				list($r2,$g2,$b2) = $this->hex2rgb($start);
				break;
			case 'diamond':
				list($r1,$g1,$b1) = $this->hex2rgb($end);
				list($r2,$g2,$b2) = $this->hex2rgb($start);
				$width = imagesx($im);
				$height = imagesy($im);
				$rh=$height>$width?1:$width/$height;
				$rw=$width>$height?1:$height/$width;
				$line_numbers = min($width,$height);
				break;
			default:
		}
		
		for ( $i = 0; $i < $line_numbers; $i=$i+1+$this->step ) {
			// old values :
			$old_r=$r;
			$old_g=$g;
			$old_b=$b;
			// new values :
			$r = ( $r2 - $r1 != 0 ) ? intval( $r1 + ( $r2 - $r1 ) * ( $i / $line_numbers ) ): $r1;
			$g = ( $g2 - $g1 != 0 ) ? intval( $g1 + ( $g2 - $g1 ) * ( $i / $line_numbers ) ): $g1;
			$b = ( $b2 - $b1 != 0 ) ? intval( $b1 + ( $b2 - $b1 ) * ( $i / $line_numbers ) ): $b1;
			// if new values are really new ones, allocate a new color, otherwise reuse previous color.
			// There's a "feature" in imagecolorallocate that makes this function
			// always returns '-1' after 255 colors have been allocated in an image that was created with
			// imagecreate (everything works fine with imagecreatetruecolor)
			if ( "$old_r,$old_g,$old_b" != "$r,$g,$b") 
				$fill = imagecolorallocate( $im, $r, $g, $b );
			switch($direction) {
				case 'vertical':
					imagefilledrectangle($im, 0, $i, $line_width, $i+$this->step, $fill);
					break;
				case 'horizontal':
					imagefilledrectangle( $im, $i, 0, $i+$this->step, $line_width, $fill );
					break;
				case 'ellipse':
				case 'ellipse2':
				case 'circle':
				case 'circle2':
					imagefilledellipse ($im,$center_x, $center_y, ($line_numbers-$i)*$rh, ($line_numbers-$i)*$rw,$fill);
					break;
				case 'square':
				case 'rectangle':
					imagefilledrectangle ($im,$i*$width/$height,$i*$height/$width,$width-($i*$width/$height), $height-($i*$height/$width),$fill);
					break;
				case 'diamond':
					imagefilledpolygon($im, array (
						$width/2, $i*$rw-0.5*$height,
						$i*$rh-0.5*$width, $height/2,
						$width/2,1.5*$height-$i*$rw,
						1.5*$width-$i*$rh, $height/2 ), 4, $fill);
					break;
				default:	
			}		
		}
	}
	
	// #ff00ff -> array(255,0,255) or #f0f -> array(255,0,255)
	function hex2rgb($color) {
		$color = str_replace('#','',$color);
		$s = strlen($color) / 3;
		$rgb[]=hexdec(str_repeat(substr($color,0,$s),2/$s));
		$rgb[]=hexdec(str_repeat(substr($color,$s,$s),2/$s));
		$rgb[]=hexdec(str_repeat(substr($color,2*$s,$s),2/$s));
		return $rgb;
	}
}
?>

今回のサンプルでは、step だけを変更できるようにしました。step は、デフォルトでは 0 を使用してなめらかなグラデーションになりますが、大きくする事によって、縦の縞模様の幅が広くなっていきます。( 特別なデザインで必要な場合以外使用する事は無いと思います )

example_01.php
<?php
// ***********************************************
//
//  プログラム名 : グラデーションサンプル(1)
//  作   成   者 : lightbox
//  作   成   日 : 2014/10/31
//
//  概要 : 
//  背景画像としてのグラデーション
//
// ***********************************************
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

require_once('gd_lightbox.php');
require_once('gradient.php');

// ステップの範囲を限定
if ( $_GET['step']+0 > 20 ) {
	$_GET['step'] = 20;
}
if ( $_GET['step']+0 < 0 ) {
	$_GET['step'] = 0;
}

// グラデーションキャンバスの作成
$gradient = new gd_gradient_fill(400,200,"horizontal","#000000","#FFFFFF",$_GET['step']+0);
// 1) 400x200
// 2) horizontal
// 3) 黒から白へ
$image = $gradient->image;

// GD インスタンス作成
$gd = new GD();

// PNG として設定
$gd->type = "PNG";
// グラデーションを設定
$gd->im = $image;
// PNGファイルとして出力
//$gd->SavePng("example_01.png");
// JPEGファイルとして出力( 第二引数を省略すると 75 )
//$gd->SavePng("example_01.jpg",90);

// ブラウザへ出力
$gd->Response();
?>

※ 画像として保存する処理をコメントにしています

gd_lightbox.php
<?php
# ***********************
# クラス
# ***********************
class GD {

	var $im;
	var $type;

# ***********************
# コンストラクタ
# ***********************
	function GD( ) {
	}

# ***********************
# キャンバス作成
# ***********************
	function CreateCanvas( $Width, $Height, $Type="PNG" ) {
		$this->type = $Type;
		$this->im = imagecreatetruecolor($Width, $Height);
	}

# ***********************
# PNG ロード
# ***********************
	function LoadPng( $Target ) {
		$this->type = "PNG";
		$this->im = ImageCreateFromPng($Target);
	}
 
# ***********************
# JPEG ロード
# ***********************
	function LoadJpeg( $Target ) {
		$this->type = "JPEG";
		$this->im = ImageCreateFromJpeg($Target);
	}

# ***********************
# 色リソース作成
# ***********************
	function CreateColor( $Red, $Green, $Blue ) {
		$ret = ImageColorAllocate (
			$this->im,
			$Red, $Green, $Blue );
		return $ret;
	}

# ***********************
# 線幅設定
# ***********************
	function SetLineWidth( $Width ) {
		ImageSetThickness( $this->im, $Width );
	}

# ***********************
# 直線の描画
# ***********************
	function Line( $x1, $y1, $x2, $y2, $Option ) {
		if ( is_array( $Option ) ) {
			ImageSetStyle( $this->im, $Option );
			ImageLine(
				$this->im, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED );
		}
		else {
			ImageLine(
				$this->im, $x1, $y1, $x2, $y2, $Option );
		}
	}

# ***********************
# 矩形の描画
# ***********************
	function Box( $x, $y, $w, $h, $Color, $fill=FALSE ) {
		if ( $fill ) {
			imageFilledRectAngle(
				$this->im, $x, $y, $x+$w, $y+$h, $Color );
		}
		else {
			ImageRectAngle(
				$this->im, $x, $y, $x+$w, $y+$h, $Color );
		}
	}

# ***********************
# 楕円の描画
# ***********************
	function Arc( $x, $y, $w, $h, $Color ) {
		ImageArc( $this->im, $x, $y, $w, $h, 0, 359, $Color );
	}

# ***********************
# ブラウザへ出力
# ***********************
	function Response( ) {
		switch( $this->type ) {
			case "PNG":
				header('Content-Type: image/png');
				ImagePng( $this->im );
				break;
			case "JPEG":
				header('Content-Type: image/jpeg');
				ImageJpeg( $this->im );
				break;
		}
	}

# ***********************
# PNG 保存
# ***********************
	function SavePng( $FilePath ) {
		ImagePng( $this->im, $FilePath );
	}

# ***********************
# JPEG 保存
# ***********************
	function SaveJpeg( $FilePath, $Quality=75 ) {
		ImageJpeg( $this->im, $FilePath, $Quality );
	}

# ***********************
# 色リソース開放
# ***********************
	function DestroyColor( $Color ) {
		ImageColorDeallocate( $this->im, $Color );
	}

# ***********************
# イメージの破棄
# ***********************
	function Destroy( ) {
		ImageDestroy ( $this->im );
	}

# ***********************
# 伸縮された新しいイメージの作成
# ***********************
	function Copy( &$New, $rate ) {
		$w = ImageSx( $this->im );
		$h = ImageSy( $this->im );
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w * $rate, $h * $rate );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}

	function CopyW( &$New, $w_new ) {
		$w = ImageSx( $this->im );
		$rate = $w_new / $w;
		$h = ImageSy( $this->im );
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w_new, $h * $rate );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}

	function CopyH( &$New, $h_new ) {
		$w = ImageSx( $this->im );
		$h = ImageSy( $this->im );
		$rate = $h_new / $h;
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w * $rate, $h_new );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}

	function CopyWH( &$New, $w_new, $h_new ) {
		$w = ImageSx( $this->im );
		$h = ImageSy( $this->im );
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w_new, $h_new );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}
}
?>




posted by lightbox at 2014-10-31 19:24 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2014年09月27日


PHP : htmlentities : テキストエリアによるテキスト処理

テキストエリアで長いソースコード等を入力して保存する場合、読み込んで表示する時のみ htmlentities 変換してから TEXTAREA 要素で挟む必要があります。

変換結果の確認は、Google Chrome のコンソールで 『$("body > form > table > tbody > tr:nth-child(2) > td:nth-child(2) > textarea").innerHTML』です
<?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" );

// POST メソッドで送信された時のみ処理する
// ( URL から呼び出された場合は処理しない )
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {

	if ( $_POST['send'] == '読み出し' ) {
		$text = @file_get_contents("./text.data");
		$text = htmlentities( $text, ENT_NOQUOTES, "utf-8" );
	}
	if ( $_POST['send'] == '書き込み' ) {
		file_put_contents("./text.data", $_POST['text'] );
		$text = htmlentities( $_POST['text'], ENT_NOQUOTES, "utf-8" );
	}

}

?>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>HTML雛形</title>
<style type="text/css">
* {
	font-family: "メイリオ","MS Pゴシック";
	font-size: 16px;
}
.column {
	border-style:solid;
	border-width:1px;
	border-color:#000000;
	padding: 4px;
}
</style>

<script type="text/javascript">
function submitForm() {
	if ( !confirm( "Submit ボタンで送信しますか?" ) ) {
		return false;
	}
	return true;
}
</script>

</head>
<body>

<form
	name="frm"
	method="post"
	action=""
	onsubmit='return submitForm();'
>
<table
	border=1
	style='
		border-collapse:collapse;
		border-style:solid;
		border-width:1px;
		border-color:#000000;
	'
>

<tr>
	<td class="column" colspan=2>
	<input
		type="submit"
		name="send"
		value="読み出し"
	>
	<input
		type="submit"
		name="send"
		value="書き込み"
	>
	</td>
</tr>

<tr>
	<td class="column">テキストエリア</td>
	<td class="column">
<textarea
	name="text"
	cols="60"
	rows="15"
><?= $text ?></textarea>
	</td>
</tr>

</table>
</form>


</body>
</html>





タグ:PHP htmlentities
posted by lightbox at 2014-09-27 16:20 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

PHP : 超簡易ログ

複雑な処理ですと、画面に表示しづらい場合があります。そんな時、その場限りのログです
file_put_contents( uniqid().".log", $vaiue );

// 以下は配列やオブジェクトを出力したい場合

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




posted by lightbox at 2014-09-27 16:20 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

PHP : 入力値のデバッグ

ソースコードの最下部に追加すれば良いと思います。
<?php
print "<pre>";
print_r($_GET);
print_r($_POST);
print "</pre>";
?>

デバッグする文字列に HTML が含まれている場合は、以下のようにするといいと思います。
<?php
foreach( $_POST as $key => $value ) {
	$_mypost[$key] = htmlentities( $value, ENT_NOQUOTES, "utf-8" );
}
print "<pre>";
print_r($_mypost);
print "</pre>";
?>



タグ:PHP
posted by lightbox at 2014-09-27 16:20 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2014年09月26日


GD で画像縮小。『1) 単純縮小、2) 幅にあわす 3) 高さにあわす 4) 任意の幅と高さ』をその他の処理も含めてクラスでまとめ( class GD )

読み出す画像は、Google の短縮 URL で動作確認しています。使用目的としては、画像をアップロードして縮小して保存する事ですが、保存前に必要ならば GD を使って修正をする事も想定しています。
<?php
# 新しいオブジェクト
$GD = new GD();

# WEB よりイメージを作成
# Google の短縮url で動作します
$GD->LoadJpeg( "http://goo.gl/CO1XaJ" );

# 赤のパレットを作成
$red = $GD->CreateColor( 255, 0, 0 );

# 線の太さを設定
$GD->SetLineWidth( 3 );

# パラメータの処理
if ( ctype_digit( $_GET['x'] ) ) {
	$x = $_GET['x'];
}
else {
	$x = 135;
}
if ( ctype_digit( $_GET['y'] ) ) {
	$y = $_GET['y'];
}
else {
	$y = 118;
}

# 楕円を描画
$GD->Arc( $x, $y, 60, 35, $red );

# 黒のパレットを作成
$black = $GD->CreateColor( 0, 0, 0 );

# 白のパレットを作成
$white = $GD->CreateColor( 255, 255, 255 );

# 点線のスタイルを作成
$style = array(
	$black,$black,$black,$black,$black,
	$white,$white,$white,$white,$white
);

# 線の太さを設定
$GD->SetLineWidth( 1 );

# スタイルを使用して斜め線を描画
$GD->Line( 20, 30, 200, 100, $style );

# 指定の大きさで新しいオブジェクトを作成
//$GD->Copy( $GD2, 0.3 );
//$GD->CopyW( $GD2, 100 );
//$GD->CopyH( $GD2, 200 );
$GD->CopyWH( $GD2, 600, 400 );

# 縮小画像をファイルとして保存
$GD2->SaveJpeg( "uf3_001.jpg" );

# ブラウザに表示
$GD2->Response( );

# 後処理
$GD->DestroyColor( $red );
$GD->Destroy( );
$GD2->Destroy( );


# ***********************
# クラス
# ***********************
class GD {

	var $im;
	var $type;

# ***********************
# コンストラクタ
# ***********************
	function GD( ) {
	}

# ***********************
# キャンバス作成
# ***********************
	function CreateCanvas( $Width, $Height, $Type="PNG" ) {
		$this->type = $Type;
		$this->im = imagecreatetruecolor($Width, $Height);
	}

# ***********************
# PNG ロード
# ***********************
	function LoadPng( $Target ) {
		$this->type = "PNG";
		$this->im = ImageCreateFromPng($Target);
	}
 
# ***********************
# JPEG ロード
# ***********************
	function LoadJpeg( $Target ) {
		$this->type = "JPEG";
		$this->im = ImageCreateFromJpeg($Target);
	}

# ***********************
# 色リソース作成
# ***********************
	function CreateColor( $Red, $Green, $Blue ) {
		$ret = ImageColorAllocate (
			$this->im,
			$Red, $Green, $Blue );
		return $ret;
	}

# ***********************
# 線幅設定
# ***********************
	function SetLineWidth( $Width ) {
		ImageSetThickness( $this->im, $Width );
	}

# ***********************
# 直線の描画
# ***********************
	function Line( $x1, $y1, $x2, $y2, $Option ) {
		if ( is_array( $Option ) ) {
			ImageSetStyle( $this->im, $Option );
			ImageLine(
				$this->im, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED );
		}
		else {
			ImageLine(
				$this->im, $x1, $y1, $x2, $y2, $Option );
		}
	}

# ***********************
# 矩形の描画
# ***********************
	function Box( $x, $y, $w, $h, $Color, $fill=FALSE ) {
		if ( $fill ) {
			imageFilledRectAngle(
				$this->im, $x, $y, $x+$w, $y+$h, $Color );
		}
		else {
			ImageRectAngle(
				$this->im, $x, $y, $x+$w, $y+$h, $Color );
		}
	}

# ***********************
# 楕円の描画
# ***********************
	function Arc( $x, $y, $w, $h, $Color ) {
		ImageArc( $this->im, $x, $y, $w, $h, 0, 359, $Color );
	}

# ***********************
# ブラウザへ出力
# ***********************
	function Response( ) {
		switch( $this->type ) {
			case "PNG":
				header('Content-Type: image/png');
				ImagePng( $this->im );
				break;
			case "JPEG":
				header('Content-Type: image/jpeg');
				ImageJpeg( $this->im );
				break;
		}
	}

# ***********************
# PNG 保存
# ***********************
	function SavePng( $FilePath ) {
		ImagePng( $this->im, $FilePath );
	}

# ***********************
# JPEG 保存
# ***********************
	function SaveJpeg( $FilePath, $Quality=75 ) {
		ImageJpeg( $this->im, $FilePath, $Quality );
	}

# ***********************
# 色リソース開放
# ***********************
	function DestroyColor( $Color ) {
		ImageColorDeallocate( $this->im, $Color );
	}

# ***********************
# イメージの破棄
# ***********************
	function Destroy( ) {
		ImageDestroy ( $this->im );
	}

# ***********************
# 伸縮された新しいイメージの作成
# ***********************
	function Copy( &$New, $rate ) {
		$w = ImageSx( $this->im );
		$h = ImageSy( $this->im );
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w * $rate, $h * $rate );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}

	function CopyW( &$New, $w_new ) {
		$w = ImageSx( $this->im );
		$rate = $w_new / $w;
		$h = ImageSy( $this->im );
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w_new, $h * $rate );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}

	function CopyH( &$New, $h_new ) {
		$w = ImageSx( $this->im );
		$h = ImageSy( $this->im );
		$rate = $h_new / $h;
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w * $rate, $h_new );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}

	function CopyWH( &$New, $w_new, $h_new ) {
		$w = ImageSx( $this->im );
		$h = ImageSy( $this->im );
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w_new, $h_new );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}
}


タグ:gd PHP
posted by lightbox at 2014-09-26 22:18 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

PHP : 曲線が使い物にならない GD ライブラリ / Canvas の楕円と比較

単純な画像加工ならば、フォントも普通に使えるますし、レンタルサーバーでも普通に実装されているので利用しやすいですが、曲線が美しく無いので、最近ではブラウザ側の canvas を使ったほうがいいでしょう。





▼ 四角形
<?php
header("Content-type: image/png");
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "pragma: no-cache" );
header( "Cache-control: no-cache" );

// ******************************
// キャンバス作成( 300 x 300 )
// ******************************
$im = imagecreatetruecolor( 300, 300 );
imageantialias( $im, true );	// アンチエイリアス

// ******************************
// 色
// ******************************
$gray = imagecolorallocate( $im, 0xC0, 0xC0, 0xC0 );
$black = imagecolorallocate( $im, 0, 0, 0 );
$white = imagecolorallocate( $im, 255, 255, 255 );

// キャンバスを灰色で塗りつぶす
imagefilledrectangle ( $im ,0, 0, 300, 300, $gray );

// ******************************
// 線幅
// ******************************
imagesetthickness ( $im, 4 );

// ******************************
// BOX
// ******************************
imagerectangle( $im, 50, 50, 250, 250, $black );

// ******************************
// BOX内部塗りつぶし
// ******************************
imagefilltoborder ( $im , (50+250)/2, (50+250)/2, $black, $white );

// ******************************
// PNG 出力
// ******************************
imagepng($im);

// ******************************
// 終了処理
// ******************************
imagecolordeallocate( $im, $black );
imagecolordeallocate( $im, $white );
imagedestroy($im);

?>


▼ 楕円
<?php
header("Content-type: image/png");
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "pragma: no-cache" );
header( "Cache-control: no-cache" );

// ******************************
// キャンバス作成( 300 x 300 )
// ******************************
$im = imagecreatetruecolor( 300, 300 );
imageantialias( $im, true );	// アンチエイリアス

// ******************************
// 色
// ******************************
$gray = imagecolorallocate( $im, 0xC0, 0xC0, 0xC0 );
$black = imagecolorallocate( $im, 0, 0, 0 );
$white = imagecolorallocate( $im, 255, 255, 255 );

// キャンバスを灰色で塗りつぶす
imagefilledrectangle ( $im ,0, 0, 300, 300, $gray );

// ******************************
// 線幅
// ******************************
imagesetthickness ( $im, 4 );

// ******************************
// 楕円
// ******************************
imagefilledarc( $im, 150, 150, 200, 180, 0, 360, $black, IMG_ARC_NOFILL );

// ******************************
// 塗りつぶし
// ******************************
imagefilltoborder ( $im , 150, 150, $black, $white );

// ******************************
// PNG 出力
// ******************************
imagepng($im);

// ******************************
// 終了処理
// ******************************
imagecolordeallocate( $im, $black );
imagecolordeallocate( $im, $white );
imagedestroy($im);

?>

imagefilledarc は、円弧、塗りつぶしと全てまかなえるので使っています

関連する記事

PHP : 曲線が必要ならば ImageMagick ( 但し使えるかどうかはサーバー次第 )

canvas で楕円

<style type="text/css">
#circle {
	border: solid 1px #000000;
}
</style>
<canvas id="circle"></canvas>
<script type="text/javascript">
	var canvas = document.getElementById("circle");
	canvas.width = 400;
	canvas.height = 330;
	var draw = canvas.getContext("2d");

	draw.beginPath();
	draw.fillStyle = "#c0c0c0";
	
	draw.save();
	draw.scale( 1, 0.8 );
	draw.arc(200, 200, 150, 0, Math.PI*2, false);
	draw.fill();
	draw.restore();

	draw.lineWidth = 3;
	draw.stroke();
</script>



posted by lightbox at 2014-09-26 21:28 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2013年11月23日


PHP : 曲線が必要ならば ImageMagick ( 但し使えるかどうかはサーバー次第 )



GD と比べてはるかに美しい曲線を描画できます。

さくらインターネットでは、php.ini に extension=imagick.so を追加
するだけで使用できるようになります

▼ 楕円( クリックすると拡大して、もう一度クリックすると戻ります )
<?
header("Content-type: image/png");
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "pragma: no-cache" );
header( "Cache-control: no-cache" );

$canvas = new Imagick(); 
$canvas->newImage(300, 300, "#C0C0C0"); 

$draw = new ImagickDraw(); 
$draw->setFillColor("#FFFFFF"); 
$draw->setStrokeColor( "#000000" ); 
$draw->setStrokeWidth(4); 
$draw->arc( 50, 60, 250, 240, 0, 360 ); 

$canvas->drawImage($draw); 

// フォーマット
$canvas->setImageFormat('png'); 

// 出力
print $canvas; 
?>


▼ 四角形( クリックすると拡大して、もう一度クリックすると戻ります )
<?
header("Content-type: image/png");
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "pragma: no-cache" );
header( "Cache-control: no-cache" );

$canvas = new Imagick(); 
$canvas->newImage(300, 300, "#C0C0C0"); 

$draw = new ImagickDraw(); 
$draw->setFillColor("#FFFFFF"); 
$draw->setStrokeColor( "#000000" ); 
$draw->setStrokeWidth(4); 
$draw->rectangle( 50, 50, 250, 250 );

$canvas->drawImage($draw); 

// フォーマット
$canvas->setImageFormat('png'); 

// 出力
print $canvas; 
?>

関連する記事

ImageMagickをWindowsのPHPで利用する


PHP : 曲線が使い物にならない GD ライブラリ


さくらインターネットでは、PHP で extension=imagick.so するだけで
ImageMagick が使えます


マニュアル

画像処理 [ImageMagick] : php オンラインマニュアル



posted by lightbox at 2013-11-23 02:04 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2013年09月22日


Twitter API 汎用テスター

Twitter API 汎用テスター


SkyDrive へ移動
twitteroauth.php を使っているので、処理部はとても少ないです。
<?php
session_start();
require_once('twitteroauth/twitteroauth.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" );

$_SESSION['twitter_keys'] = $_POST['keys'];

$_POST['keys'] = str_replace("\r","",$_POST['keys']);
$_POST['keys'] = str_replace("\n","",$_POST['keys']);
$twitter_keys = explode(",", $_POST['keys'] );

$result = twitter_api(
		$twitter_keys[0],
		$twitter_keys[1],
		$twitter_keys[2],
		$twitter_keys[3],
		$_POST['tpost']
);

$_SESSION['consumer_key'] = $twitter_keys[0];
$_SESSION['consumer_secret'] = $twitter_keys[1];
$_SESSION['access_token'] = $twitter_keys[2];
$_SESSION['access_token_secret'] = $twitter_keys[3];

print "<a href='twitter_api.php?tpost=" . urlencode($_POST['tpost']) . "'>戻る</a>";
print "<pre>";
print_r(json_decode($result));
print "</pre>";

// *************************************************************************
// twitteroauth による処理
// *************************************************************************
function twitter_api( $apikey, $secret, $token, $token_secret, $text ) {

	$param = explode("\r\n", $text);

	$oauth = new TwitterOAuth(
		$apikey,
		$secret,
		$token,
		$token_secret
	);

	$imax = count( $param );
	$parameters = array();
	for( $i = 2; $i < $imax; $i++ ) {
		$data = explode("=", $param[$i]);
		if ( $data[0] != '' ) {
			$parameters[$data[0]] = $data[1];
		}
	}
 
	$result = $oauth->oAuthRequest(
		$param[1],
		$param[0],
		$parameters
	);

	return $result;

}
?>

GET users/show
GET
https://api.twitter.com/1.1/users/show.json
screen_name=sworc
GET search/tweets
GET
https://api.twitter.com/1.1/search/tweets.json
q=進撃の巨人
count=30
POST statuses/retweet/:id ( リツイート / id は詳細ページの URL の最後の番号 )
POST
https://api.twitter.com/1.1/statuses/retweet/381781849153884160.json
posted by lightbox at 2013-09-22 23:07 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする
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 終わり