Home > PHP Archive

PHP Archive

全角スペース、複数の半角スペースを半角スペースひとつに置換

入力フォーム内の「名前」において、名字と名前を区切るのに半角スペースを使用し
全角や複数の半角スペースが入っていた場合、これをひとつの半角スペースに置換する例。
(内容の前後にスペースがあった場合、これは除去する)

入力内容に全角スペースがあった場合、これを半角スペースひとつに置換。
また、半角スペースであっても、これが複数入っていた場合、これをひとつに置換する。

  • 入力された要素に対して、まずは「全角スペース」を「半角スペース」に置換する。(複数あっても、とにかく全て半角スペースに置換する)
  • 続いて、入力された要素の前後にスペース(前段階で半角スペースに置換されている)があった場合、これをtrimで削除
  • その上で、名字と名前の間にあるスペースが複数だった場合、これをひとつに置換する

連続する半角スペースのパターンは正規表現によるパターンマッチを使い、preg_replaceで置換する。
この場合1回以上の繰り返しなので「\s」に「+」をつける。
(「\s」はタブ、スペース、改行などの空白文字を、「+」は、1回以上の繰り返しを意味する)

そして、Perl互換の正規表現ではひとつのパターンの前後にデリミタ(/)をつけて区切る必要があるので「/\s+/」となる。

以上を踏まえて、以下のような記述になる。(該当部分は4, 5行目)

if( ! $name){ // 変数$nameに値が存在しない場合
    $message.= "お名前を入力して下さい。\n"; // このメッセージを表示
}else{ // それ以外の場合(変数$nameに値が存在する場合)
    $name = str_replace(" ", " ", $name); // 変数$nameの値に含まれる全角スペースを半角スペースに置換して変数$nameに代入
    $name = preg_replace("/\s+/", " ", trim($name)); // 変数$nameの値の前後に半角スペースが含まれていた場合それを削除し、半角スペースが複数あった場合、正規表現を使ってそれをひとつに置換し、変数$nameに代入
    $name_r = explode(" ", $name);    // 半角スペースで分割
    if( ! ($name_r[0] && $name_r[1]) || $name_r[2]){
        // ( 名字・名前の入力不備 || 名字・名前以外に入力あり )
        $message.= "お名前の名字と名前の間に半角スペースを入れて下さい。\n";
    }
}

念のため、簡単な実行例も。

フォームのhtml

<form method="REQUEST" action="sample2.php">
名前:<input name="name" ><br />
<input type="submit" value="送信" />
</form>

送信内容を受け取って内容を表示するsample2.php

<?php
// フォームで送信された内容をデバッグ表示
print_r($_REQUEST);
 
// 配列の要素nameの値を$nameに代入
$name = $_REQUEST[name];
 
// $nameの値に含まれる全角スペースを半角に置換
$name = str_replace(" ", " ", $name);
 
// $nameの値の前後の半角スペースを除去してから連続する半角スペースがあった場合、それを半角スペースひとつに置換
$name = preg_replace("/\s+/", " ", trim($name));
 
echo "<div>$name</div>";

送信結果のhtmlソースを確認してみると
ピクチャ 2

配列の内容をprint_rでデバッグ表示。
これはフォームに入力されたまま、余計な全角スペースが入っている。

半角スペースひとつに置換する処理をした後にechoで出力した内容は、ちゃんと半角スペースひとつ(名字と名前の間)に置換されている。

PHPでCSVデータを表示する

前に「PHPでCSVデータを読み込んで内容を出力する」でやってみたものよりも、もうちょっとましに出来たと思うので、あらためてまとめておく。

▼ファイル一覧
_include.php // 共通の処理
dic_top.php // 各行の用語一覧ぺーじへ飛ばすトップページ(あ行、か行という風に表示し、リンクが張られている)
list.php // 各行の用語を一覧表示(全レコード数中何件かも表示)
detail.php // 各用語の内容を表示
sample.csv // 表示する用語のCSVデータファイル

▼sample.csv
※よみがなでソートしたいので、よみがな要素は一番最初に。
かいきいわい,ka,快気祝,病気の全快を祝うこと。
がいろじゅ,ka,街路樹,道路に沿って植えつらねた樹木。
あいことば,a,合い言葉,味方同士であらかじめ決めてある合図の言葉。
あおうなばら,a,青海原,青々として広い海。
あおてんじょう,a,青天井,青空。青空を天井に見立てていう言葉。
かかし,ka,案山子,鳥獣をおどしてその被害を防ぐために田畑に立てた人型。

▼_include.php

<?php
// sample.csvをcsvdataとして定数に定義
define(csvdata, "sample.csv");
 
// 1行を1レコードとして配列に格納
$record = array();
 
// csvdataを変数$dataに代入
$data = file(csvdata);
 
// 要素数を上限としてforループで全要素をカンマ区切りで$recordに代入
for ($i = 0; $i < count($data); $i++) {
    $record[$i] = split(",", $data[$i]);
}
 
// 全レコード数を変数$sumに代入
$sum = count($record);
 
// よみがなであいうえお順にソートする
// 多次元配列なのでasortではなくarray_multisort()関数を使う
array_multisort($record);
 
// リンクURLに付加した行名を判別するためのパラメータgyo_nameの値を変数$gyo_nameに代入
$gyo_name = $_REQUEST['gyo_name'];
 
// 読み仮名と単語名と意味の値をパラメータに含ませる文字列部分を変数$link_paramに代入
$link_param = "?yomi=0&tango=2&imi=3";
 
// リンクURLのパラメ「gyo_name」の値によって「○行」と表示させるために変数に値を代入
if ($_REQUEST['gyo_name'] == 'a') {
    $gyo = "あ";
} elseif ($_REQUEST['gyo_name'] == 'ka') {
    $gyo = "か";
}

▼dic_top.php

<a href="list.php?gyo_name=a">あ行</a><br />
<a href="list.php?gyo_name=ka">か行</a><br />

▼list.php

<?php
include_once '_include.php';
 
echo "<h1>".$gyo."行の用語</h1>";
 
// forループで全要素にアクセスし
for ($i = 0; $i <= count($data); $i++) {
/* 前ページのリンクURLパラメータからひきついだ行名判断の値が「a」であり
なおかつ$recordの読み仮名要素の値が「a」のものだけを出力する
(同様に「か行」なら「ka」という風に、他の行名の条件判断も加える)
*/
    if ($record[$i][1] == 'a' && $gyo_name == 'a') {
        // $link_paramはリンクURLに付加するパラメータで_includeに記述してある
        // 特定のレコードにアクセスするためにリンクURLのパラメにid=$iも付加
        // リンク文字列は$recordの単語名(添え字2)を表示
        echo '<a href="detail.php'.$link_param.'&id='.$i.'">'.$record[$i][2].'</a>'."<br />";
        // 一回ループするごとに変数$jをインクリメントすることで条件に合ったレコードの件数を求める
        $j++;
    // か行を出力
    } elseif ($record[$i][1] == 'ka' && $gyo_name == 'ka') {
        echo '<a href="detail.php'.$link_param.'&id='.$i.'">'.$record[$i][2].'</a>'."<br />";
        $j++;
    }
}
 
// 全てのレコード数と条件に合って表示している件数を表示
echo $j."件"."(全".$sum."件中)";

▼detail.php

<?php
include_once '_include.php';
 
// $_REQUEST変数で渡された各要素の値をそれぞれ変数に代入
$id = $_REQUEST['id']; // idの値を$idに代入
$tango = $_REQUEST['tango']; // tangoの値を$tangoに代入
$yomi = $_REQUEST['yomi']; // yomiの値を$yomiに代入
$imi = $_REQUEST['imi']; // imiの値を$imiに代入
 
// 単語名、読み、意味を配列$recordから指定して出力
echo "単語名:".$record[$id][$tango]."<br />";
echo "読み:".$record[$id][$yomi]."<br />";
echo "意味:".$record[$id][$imi]."<br />";

PEAR::Pagerをインストールして使ってみる

自宅iMacのVMware FusionにインストールしているUbuntu Server 9.0.4に、PHPのPEARライブラリ「PEAR::Pager」をインストール。

PEAR::Pagerはページネーション(ページ送りとか、ページングとも言う)機能を簡単に実装できるパッケージ。

PEARの各パッケージをインストールするには(この場合はPEAR::Pager)PEARパッケージマネージャの「php-pear」が必要。これがPEARの各パッケージをインストールするための窓口となってくれる。

ちなみに、Ubuntuではこのパッケージマネージャが未インストール状態で、PEARのパッケージをインストールしようとすると

$ pear install Pager
The program 'pear' is currently not installed.  You can install it by typing:
sudo apt-get install php-pear

と表示される。「pear」がインストールされてませんよと。そして、それをインストールするには「sudo apt-get install php-pear」とタイピングして実行するといいですよと。親切だ。

なので、このメッセージに従ってphp-pearをまずはインストールする。(sudoというのはroot権限でこのコマンドを実行するということ)

php-pearのインストール

$ sudo apt-get install php-pear

これでPEARのパッケージマネージャがインストールされた。つづいて本題のPEAR::Pagerパッケージのインストール。これも同様にsudoをコマンドの先頭につけて、管理者権限でインストールする。

PEAR::Pagerのインストール

$ sudo pear install Pager

Pagerパッケージをインストールして、何がどこに入ったのかを一応確認してみる。
(pearのlistというコマンドを使って)

$ pear list Pager
Installed Files For Pager
=========================
Type Install Path
doc  /usr/share/php/docs/Pager/examples/example.php
doc  /usr/share/php/docs/Pager/examples/Pager_Wrapper.php
test /usr/share/php/tests/Pager/tests/all_tests.php
test /usr/share/php/tests/Pager/tests/multibyte_post.php
test /usr/share/php/tests/Pager/tests/pager_include.php
test /usr/share/php/tests/Pager/tests/pager_jumping_noData_test.php
test /usr/share/php/tests/Pager/tests/pager_jumping_test.php
test /usr/share/php/tests/Pager/tests/pager_jumping_tests.php
test /usr/share/php/tests/Pager/tests/pager_noData_test.php
test /usr/share/php/tests/Pager/tests/pager_post_test.php
test /usr/share/php/tests/Pager/tests/pager_post_tests.php
test /usr/share/php/tests/Pager/tests/pager_post_test_simple.php
test /usr/share/php/tests/Pager/tests/pager_sliding_noData_test.php
test /usr/share/php/tests/Pager/tests/pager_sliding_notExpanded_test.php
test /usr/share/php/tests/Pager/tests/pager_sliding_test.php
test /usr/share/php/tests/Pager/tests/pager_sliding_tests.php
test /usr/share/php/tests/Pager/tests/pager_test.php
test /usr/share/php/tests/Pager/tests/pager_tests.php
test /usr/share/php/tests/Pager/tests/pager_test_xss.php
test /usr/share/php/tests/Pager/tests/pager_wrapper_include.php
test /usr/share/php/tests/Pager/tests/pager_wrapper_test.php
test /usr/share/php/tests/Pager/tests/README
test /usr/share/php/tests/Pager/tests/simple_include.php
php  /usr/share/php/Pager.php
php  /usr/share/php/Pager/Common.php
php  /usr/share/php/Pager/HtmlWidgets.php
php  /usr/share/php/Pager/Jumping.php
php  /usr/share/php/Pager/Pager.php
php  /usr/share/php/Pager/Sliding.php

簡単なコードを実際に記述して、このパッケージ(Pager)が利用出来る状態になっているのかを確認する。(パッケージをincludeで読み込んで機能を利用可能にし、ページネーションのナビゲーションリンクと現在のページ番号を表示してみる)

paging_sample.php

<?php
// Pagerパッケージの読み込み
require_once "Pager/Pager.php";
 
$options = array(
    "totalItems" => 200,
    "delta" => 10,
    "perPage" => 8
);
 
$pager =& Pager::factory($options);
$navi = $pager -> getLinks();
print($navi["all"]);
 
$currentPageID = $pager -> getCurrentPageID();
 
echo "<br />現在のページ番号は" . $currentPageID . "です。";

このファイルにブラウザでアクセスして表示してみると、こんな感じ。
ピクチャ 1

とりあえずPagerパッケージは無事インストールできて、機能も利用できている模様。

あとは、実際にページネーションが必要なコンテンツを作成して実践&確認していくという感じ。

PHPでCSVデータを読み込んで内容を出力する

CSVファイル(カンマと改行でレコード及び各要素を区切ったデータ)をPHPで開いて読み込み、それらを出力するサンプル。
追記:2009/12/15 PHPでCSVデータを表示する(もうちょっとうまく?出来たので、こっちもメモっておいた)

新しい勤め先でちょっと必要になったので、初めて自分自身で最初から書いてみたという、自分としてはとてもエポックメイキングな出来事。(もっとスマートに、利便性高く書けるのだろうけど、とりあえずはこれでも、、なのだ)

あ行、か行といったように、それぞれを「あかさたな」で分けてCSVファイルを用意し、各語群にとばすリンクURL内にそれを指すキーをパラメータとして付加し、該当のCSVファイルを読み込むようにする。

◎xhtmlファイル:index.html

内容:あ行、か行の語群を表示するページへのリンクを表示する。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<title>CSVデータを読み込んで表示する</title>
</head>
<body>
 
<!-- リンクURL末尾に?を使って連想配列名=キー名としてパラメータを追加する -->
<!-- こうすることでグローバル変数$_GETの配列として要素を取り出すことが出来る -->
<!-- 引き渡された要素は$_GET[キー名]でアクセス出来る -->
<a href="list.php?gyo=a" title="あ行">あ行</a><br />
<a href="list.php?gyo=ka" title="か行">か行</a>
 
</body>
</html>

◎CSVデータ:a.csv, ka.csv
サンプルとして、簡単な三文字熟語を使用。各熟語とその「読み」「意味」をカンマで区切って記述。ひとつひとつのレコード(熟語)は改行で分ける。

a.csvの内容(あ行の語群)
合い言葉,あいことば,味方同士であらかじめ決めてある合図の言葉。
青海原,あおうなばら,青々として広い海。
青天井,あおてんじょう,青空。青空を天井に見立てていう言葉。

ka.csvの内容(か行の語群)
快気祝,かいきいわい,病気の全快を祝うこと。
街路樹,がいろじゅ,道路に沿って植えつらねた樹木。
案山子,かかし,鳥獣をおどしてその被害を防ぐために田畑に立てた人型。

◎phpソースファイル:include_csv.php

一覧ページと各熟語詳細ページで共用するスクリプトを外部ファイルとして作成。

<?php
// $_GETの要素として渡された値(行を判別する)を変数$gyoに代入
$gyo = $_GET['gyo'];
 
 
 
// あかさたな行を判別してCSVファイルを読み込む
// この例ではあ行とか行のみ
// $gyoの値が「a」だったらa.csvを読み込む、「ka」だったらka.csvを読み込む
if ($gyo == 'a') {
    define(csvfile, "a.csv");
} elseif ($gyo == 'ka') {
    define(csvfile, "ka.csv");
}
 
 
 
// CSVファイルデータを多次元配列(ネストされた配列)として格納
// 親(ひとつひとつの熟語のレコード)配列が$recordで、子(カンマで区切られた各要素)が$TextData
if (file_exists(csvfile) == false) {
    return false;
} else {
    $record = array();
    $TextData = file(csvfile);
    for ($i = 0; $i < sizeof($TextData); $i++) {
        $record[$i] = split(",", $TextData[$i]);
    }
}

◎phpソースファイル:list.php

各行の語群を一覧表示し、リンクをクリックすると熟語詳細ページへとぶ。

<?php
// CSVファイルの読み込みとそのデータ内容を多次元配列に格納するスクリプトを読み込む
include_once "include_csv.php";
 
// レコードの総件数を取得して変数$sumに代入
$sum = count($record);
 
// forループで回して全てのレコードにおける単語名そ出力
// リンクURLには単語名と読みと意味とレコードidをパラメータで付与
// こうすることでリンク先ページで各単語の各要素にアクセスすることが出来る
for ($i = 0; $i <= $sum; $i++) {
    echo '<a href="detail.php?tango=0&yomi=1&imi=2&id=' . $i . '&gyo=' . $gyo . '">' . $record[$i][0] . '</a><br />';
}

◎phpソースファイル:detail.php

熟語群一覧から各熟語をクリックしたら表示する熟語詳細ページ
(熟語、読み、意味を表示)

<?php
// CSVファイルの読み込みとそのデータ内容を多次元配列に格納するスクリプトを読み込む
include_once "include_csv.php";
 
// $_GET変数で渡された配列の各要素の値をそれぞれ変数に代入
$tango = $_GET['tango']; // 熟語名
$yomi = $_GET['yomi']; // 読み
$imi = $_GET['imi']; // 意味
$id = $_GET['id']; // 配列recordの値(行のどの単語かを判別するための)
$gyo = $_GET['gyo']; // 行を判別するためのキーの値
 
// 熟語名・よみ・意味を出力
echo "熟語名:" . $record[$id][$tango] . "<br />";
echo "よみ:" . $record[$id][$yomi] . "<br />";
echo "意味:" . $record[$id][$imi] . "<br /><br />";
 
// 念のため配列の内容をデバッグ表示してみる
echo "▼前ページから引き渡された配列の内容をデバッグ表示してみる" . "<br />";/
print_r($_GET);

これで、index.htmlをブラウザで開いて、あ行なりか行なりのリンク文字列をクリックすると、CSVで用意されている各レコードを全て(行ごとに)表示して、各熟語名をクリックすると、該当する熟語の詳細(熟語名、読み、意味)を表示する。

もっとスマートにできるのだろうけれど、チュートリアルや写経で確認するといったやり方以外で、初めて仕事でプログラムを自分自身で最初から作成したというのがとてもいい経験になった気がする。

とくに配列(グローバル変数$_GETや$_POSTについても)に対する理解においては、今までのなぞっただけの「知識」じゃなくて、やっと利用できる、活用できる「知恵」になったような気がする。まだ入り口だけど。

CentOS 5.3 ServerにLAMP環境の構築

Mac OS X 10.5.7上のVMware FusionにインストールしたCentOS 5.3 ServerにLAMP環境を構築し、PHPとMySQLの接続が出来るかまでを確認するメモ。(PHPはパッケージマネージャを使わないでソースからコンパイルしてインストール)

Continue reading

セキュリティ面に気をつかったphp.iniの設定

Ubuntu Server ver.8.10 にインストールした PHP5 における php.ini の設定内容メモ。
(この設定をしたのは借り物の仕事用 macbook)

Continue reading

php.ini の場所

/opt 配下、XAMPP、Ubuntu Server(VMware fusion での仮想環境)と、勉強のための環境が複数あって混乱してきたのでメモ。

◎MacPorts環境
/opt/local/etc/php.ini

◎XAMPP(for mac osx) 環境(/Applications 配下にインストールした場合)
/Applications/xampp/etc/php.ini

◎Ubuntu Server環境
/etc/php5/apache2/php.ini

モバイルサイト制作にあたってのphp.iniの設定

ローカルでの、自分で php.ini を編集できる環境ではいいけれど、レンタルサーバではそれが出来ないので、以下のように .htaccess を使って、モバイルサイトを制作するにあたっての各項目の設定を変更する。

.htaccessで設定した項目

(これは php4 の場合。5の場合は mod_php5.c とすればいい)

<IfModule mod_php4.c>

# セッションIDを保存するのにCookieを使用するかどうか
# 携帯では基本的にCookieを利用出来ないのでオフに
php_value session.use_cookies 0

# URLにセッションIDを付加するかどうかを指定
# 携帯ではCookieにセッションIDを保存できないので、これはオン
php_value session.use_trans_sid 1

# 内部文字エンコーディングの設定
# 携帯の特殊文字にも対応出来るようにeucJP-winを使用する
php_value mbstring.internal_encoding eucJP-win

# 自動文字エンコーディングの検出の順番を設定
# モバイルサイトは幅広い文字に対応する必要があるので、eucJP-winとSJIS-winを利用する
# そのために検出の順番を明確に定義しておく
php_value mbstring.detect_order SJIS-win,eucJP-win,JIS,UTF-8,ASCII

</IfModule>

以下の5つの項目については、ホスティング先の設定がすでにそうだったので、今回はとくに指定しなかった。(イコールは、あくまでもphp.ini上での表記で、この.htaccessでの設定では使わない)

  • session.use_only_cookie = 0
  • mbstring.language = Japanese
  • mbstring.http_input = pass
  • mbstring.http_output = pass
  • mbstring.encoding_translation = Off

*注意:
mbstring.detect_order のところは、文字コード名を繋ぐカンマの後に半角スペースとか入れてはだめ(エラーになる)

絵文字変換スクリプト

フリーで配布されている絵文字変換スクリプトを試してみた

携帯サイトを作ろう!-ちょっと詳しいモバイルサイトの作り方-のエントリ「携帯絵文字変換スクリプトの改良版 (PHP・SSI対応版)を作りました」内で配布されていた、絵文字変換スクリプト(主要3キャリア対応)を試用してみたメモ。(メモもなにも、とてもくわしく該当エントリに記してある)

特徴としては

  • 3キャリア対応(docomo は iモードHTML4.0以上)
  • PHP、SSHに対応
  • Unicode数値参照方式を採用
  • PHP4と5で動作
  • PC閲覧時にも絵文字を表示(UI偽装とかじゃなくて普通にPCでのアクセス)
  • ドコモの絵文字が基準

らしい。

とりあえず PHP で使用する限りは、emoji_trans.php(絵文字変換スクリプト)の PC 用絵文字の格納ディレクトリへのパスだけ、自分の環境(これらのスクリプトをアップロードした)に合わせて書き換えれば OK だった。(モバイル端末でのアクセスは関係ない)

// WebRoot からの相対パス
$emoji_img_dir = “/emoji/include/emoji/images”;

まだ試用してみただけだけど、必要な場面では大変重宝しそうです。ありがとうございます。お世話になります。

DLしたソースファイル(zip)は Dropbox/Download/emoji 内に。

PEAR::Net_UserAgent_Mobileを使ってキャリア判別によるリダイレクト

PEAR::Net_UserAgent_Mobileを使ってキャリア判別によるリダイレクト

http://hogehoge.hoge/m

にアクセスすると、DoCoMo, au, SoftBank 端末とそれ以外を判別して、指定したディレクトリ(ページ)にリダイレクト。

PHP の PEAR パッケージのひとつ「Net_UserAgent_Mobile」を利用する。

Continue reading

Home > PHP Archive

Archives

Return to page top