2018年01月31日


Form(サーバー送信)汎用スケルトン(5) : ディレクトリ内のファイル一覧





今回は、ファイルを3つに分けたので、common.php と、view.php はダウンロードパッケージの中にあります。

dir.php
<?php
// *********************************************************
// 共通部分
// *********************************************************
require_once( 'common.php' );

// *********************************************************
// 変数
// *********************************************************
// データを作成するディレクトリ
$upload_dir = './upload';
// テーブルタグを含むファイル名リストの文字列
$upload_list = '';
// TABLE 一行の列数
$cols = 3;


////////////////////////////////////////////////////////////
// POST された場合の処理
////////////////////////////////////////////////////////////
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {

	if ( !file_exists( $upload_dir ) ) {
		mkdir( $upload_dir );
	}

	$Message = "POSTされました \n";

	// テスト用の簡単な ID 取得
	$srcid = uniqid();

	// ファイルへ入力されたデータを書き込み
	file_put_contents( "$upload_dir/$srcid.txt", pack('C*',0xEF,0xBB,0xBF) . $_POST['text'] );

}


////////////////////////////////////////////////////////////
// 常に実行するファイル一覧の取得
////////////////////////////////////////////////////////////
$dir_handle = @opendir($upload_dir);
if ( $dir_handle ) {

	// ループ処理
	while( 1 ) {

		$rows = read_row( $dir_handle, $cols );
		// 配列が空の場合はデータが全く存在しないので、
		// 何もしないですぐ終わる
		if ( count( $rows ) == 0 ) {
			break;
		}

		$upload_list .= "<tr>\n";
		for( $i = 0; $i < $cols; $i++ ) {
			$upload_list .= "<td>";
			$upload_list .= "<a href=\"$upload_dir/{$rows[$i]}\"";
			$upload_list .= " target=\"_blank\">{$rows[$i]}</a>";
			$upload_list .= "</td>\n";
		}
		$upload_list .= "</tr>\n";

	}
}


// *********************************************************
// HTML の TABLE の 一行分のデータを取得する関数
// 一行のデータを読んで、配列にデータをセットする
// ( 戻り値の配列数が 0 の場合、データは存在しない )
// $cols で、1行の列数を決定する
// *********************************************************
function read_row( $handle, $cols ) {

	$ret = array();

	while( 1 ) {
		$target = readdir( $handle );
		// データが完全な終了
		if ( $target === false ) {
			break;
		}
		// 対象外は読み飛ばし
		if ( $target == '.' || $target == '..' ) {
			continue;
		}

		$ret[] = $target;

		// 指定回数配列がセットされたらループを終了する
		if ( count( $ret ) == $cols ) {
			break;
		}
	}

	return $ret;
}

// *********************************************************
// 画面
// *********************************************************
require_once( 'view.php' );

?>


view.php
<!DOCTYPE html>
<html lang="ja">
<meta charset="utf-8">
<head>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">

// *********************************************************
// フォームのチェック
// *********************************************************
function checkdata() {

	var str = $("#text").get(0).value;
	str = str.trim();

	if ( str == '' ) {
		alert("必須入力です");
		$("#text").get(0).select();
		$("#text").get(0).focus();
		return false;
	}

	if ( !confirm( "更新しますか?" ) ) {
		return false;
	}

	// サーバーへ送信
	return true;

}

</script>

<style>
table {
	margin-top: 10px; 
	border-collapse: collapse;
	box-shadow: 0px 13px 17px -10px;
}
td { 
	border: solid 1px #444; 
	border-radius: 25px;
	padding: 10px;
}
</style>

</head>
<body>

<form
	name="frmMain"
	method="post"
	action="<?= $_SERVER['PHP_SELF'] ?>"
	onsubmit='return checkdata()'>
	<div>
		<input type="submit" name="send" value="送信"> <?= $Message ?>
		<input type="button" value="初期画面" onclick='location.href="<?= $_SERVER['PHP_SELF'] ?>"'>
	<div>
	<textarea id="text" name="text" cols="80" rows="15"><?= $_POST['text'] ?></textarea>
</form>

<table>
<?= $upload_list ?>
</table>

</body>
</html>


common.php
<?php
header( "Content-Type: text/html; charset=utf-8" );

header( "Expires: Thu, 19 Nov 1981 08:52:00 GMT" );
header( "Cache-control: no-cache" );
header( "Pragma: no-cache" );

foreach( $_GET as $key => $value ) {
	$_POST[$key] = $_GET[$key];
}

?>




posted by at 2018-01-31 16:17 | スケルトン | このブログの読者になる | 更新情報をチェックする

PHP 先頭


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

header( "Expires: Thu, 19 Nov 1981 08:52:00 GMT" );
header( "Cache-control: no-cache" );
header( "Pragma: no-cache" );

foreach( $_GET as $key => $value ) {
	$_POST[$key] = $_GET[$key];
}

?>

キャッシュ制御は Expires だけで十分だと思いますが、一応。

※ session_cache_limiter( 'nocache' ) で出力される内容とほぼ同じです

GET でも POST でも、$_POST で記述する方法なので、既存のソースコードに有効な場合があります。

それと、SQL の 文字列の一部として扱われる場合は ' を '' に変換しなおす必要があります。




タグ:PHP
posted by at 2018-01-31 16:09 | 小コードコピー | このブログの読者になる | 更新情報をチェックする

2017年04月21日


SortedDictionary クラス / Run Code( オンライン 実行 ) / C#



Run Code は、広告表示も無いしログインしなくても使い勝手がいいです。ideone は、ログインが Facebook ベースで可能なようだったのに、結局アカウント登録しないと使えませんでした。ログインしないと使い勝手が悪く、広告が邪魔です。

Run Code は Google アカウントで実際にログインでき、コメント投稿は Facebook、Twitter、Google が選択できます。

ただ、運営規模が小さいのか、ユーザが16人しかログインして利用していませんでした。自分の ID が1ページ目に出て、ページがまだ1ページしかありません。おそらく、ログインしなくても使える部分が多いので、自分のコードを登録して再利用する必要の無い人にとっては、その利用方法へと移行しないのだと思います。

Run Code のインターフェイスは、シンプルで使いやすいです。とにかく、ログインしなくてもコードテストが普通に繰り返しできるので便利です。
// ***********************************************************
// ソートされたディクショナリ
// ***********************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // インスタンス作成
            SortedDictionary<string, string> openWith = new SortedDictionary<string, string>();
    
            // ディクショナリに追加
            openWith.Add("txt", "notepad.exe");
            openWith.Add("bmp", "paint.exe");
            openWith.Add("dib", "paint.exe");
            openWith.Add("rtf", "wordpad.exe");

            // 一覧表示
            foreach( KeyValuePair<string, string> kvp in openWith ){
                
                Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
                
            }
        }
    }
}


Microsoft ドキュメント

.NET Framework 4 : SortedDictionary



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

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

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

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

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


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

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

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

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

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