Smartyの最近のブログ記事

多重配列のエンコード

| コメント(0)
PHP+Smartyで携帯サイトを制作すると絶対にぶつかる問題。

「文字コードの変換」

パソコン用であれば、「UTF-8」で統一しておけば何も問題ないのだが
携帯サイトに関しては、基本的に「SHIFT-JIS」

ドコモの一部機種とソフトバンクは、「UTF-8」対応しているが
auは対応しておらず、すべての携帯で見れる文字コードは
今のところ「SHIFT-JIS」のみ。

ただし、PHP+Smartyは「UTF-8」か「EUC」しか対応していないので
PHPは上記どちらかで保存し、ビュー用のテンプレートファイルを「SHIFT-JIS」で保存。

そして、アウトプットさせるデータを出力時に「SHIFT-JIS」にエンコード。
これでうまくいくはずが・・・文字コードはハマると結構面倒なんだなぁ(泣)

今回気がついたことは、エンコードの関数「mb_convert_encoding」って
配列に対応してないのね・・・(><)

ということで、多重配列に対応したエンコード関数を作ってみました。
これで携帯でうまく表示されました!

/* -------------------------------------------
 文字列(配列)のエンコード
 $param = ターゲットとなる配列もしくは文字列
 $to_encoding = 変換後の文字コード
 $from_encoding = 変換前の文字コード(デフォルトはauto)
------------------------------------------- */
function arr_mb_convert_encoding($param, $to_encoding, $from_encoding="auto"){
    if(is_array($param)){
        foreach($param as $key => $val){
            if(is_array($val)){
                foreach($val as $k => $v){
                    $param[$key][$k] = mb_convert_encoding($v, $to_encoding, $from_encoding);
                }//end foreach
            }else{
                $param[$key] = mb_convert_encoding($val, $to_encoding, $from_encoding);
            }//end if
        }//end foreach
    }else{
        $param = mb_convert_encoding($param, $to_encoding, $from_encoding);
    }//end if
    return $param;
}//end function


一つのURLにアクセスしてもらって、PCか携帯かに
振り分けるリダイレクトプログラムを入れたら
ドコモだけ「サイトが移動しました(301)」と一旦表示されて
その後正常に表示される。

Smartyを使って、DisplayしているのでURLは変えないんだから
移動しましたっていちいち言うなよっ!という感じです。

結果的に超単純な方法で改善しましたが、これを改善といっていいのかどうか。
URLの最後に"/"(スラッシュ)を必ずつけるということでした。

QRコードや広告、名刺に記載するモバイルURLの最後に
しっかりと"/"(スラッシュ)を付けてもらうということでしょうか・・・。
何だか腑に落ちませんが。

例えば、1, 2, 3をすべて、001, 002, 003と表示させたい場合は
下記のような使い方をする。

{$cnt|string_format:"%03d"}

// $cntに数値が入るとする。

そして、それをfor文でまわすと下記のようなコードになる。

{section name=cnt start=1 loop=3}
   {$smarty.section.cnt.index|string_format:"%03d"}."<br />"
{/section}
先の記事で、fgetcsv関数を紹介しましたが
どうもこの関数は処理速度が遅いらしい。

ともかく少しでも速くしたいので、別の方法を試してみた。
fgetcsvに変えて、file_get_contentsを使ってみる。
ただし、file_get_contentsだと1行ずつ取り出してくれないので
explodeを2回入れる必要がある。
改行(\n)での分割とカンマ(,)での分割。
ちょっとコードが長くなるが、速いに越したことはない。

$fname = "csv/sample.csv";
$file = file_get_contents($fname);
$file_line = explode("\n", $file);
$i = 0;
foreach($file_line as $value) {
    list($sp_date, $sp_title, $sp_detail, $sp_url, $sp_photo) = explode(",", $value);
    $sp_data[$i]["sp_date"] = $sp_date;
    $sp_data[$i]["sp_title"] = $sp_title;
    $sp_data[$i]["sp_detail"] = $sp_detail;
    $sp_data[$i]["sp_url"] = $sp_url;
    $sp_data[$i]["sp_photo"] = $sp_photo;    
    $i++;
}// end foreach

ストップウォッチ片手にベンチマークしてみると
Firefoxにおいては、たしかに1秒ほど速くなった。

ただIE7.0でのテストは、わずかに速いかなという程度で
ほとんど変わらなかった・・・というかどちらも遅い。

DBが使える環境であれば、CSVよりも間違いなく
DBをおすすめする・・・当たり前か(^^;)

どちらにせよ、DBが使えない特殊な環境もしくは
制限がある場合は、CSVを使うしかないのだが
データを取り出す際には、fgetcsvよりもfile_get_contentsの方が
いいかもしれない。
他にもfile関数やfopen関数があるが、あまり変わらない
ということなので今回は試していない。

参考にしたサイト: 2Y's BLOG

CSVファイルから取り出したデータを配列に入れて
Smartyで呼び出してみる。
DBが使えない環境でとりあえずの策として利用してみた。

$fname = "csv/sample.csv";
$file = fopen($fname, "r");
$i = 0;
while(list($sp_date, $sp_title, $sp_detail, $sp_url, $sp_photo) = fgetcsv($file, 1000, ",")) {
    $sp_data[$i]["sp_date"] = $sp_date;
    $sp_data[$i]["sp_title"] = $sp_title;
    $sp_data[$i]["sp_detail"] = $sp_detail;
    $sp_data[$i]["sp_url"] = $sp_url;
    $sp_data[$i]["sp_photo"] = $sp_photo;    
    $i++;
}//end while
fclose($file);

$smarty = new Smarty();
$smarty -> assign("sp_data", $sp_data);
一覧ページにダラダラと長い文章が入っているのは見づらい。
詳細ページに詳しく書いてあるんだから、ちょっとでいいんだよってときに
使いたいのが、Smartyの関数 「truncate」

よく使う方法は、{$string|truncate:20:"...More"} 
20文字で切り捨ててその後に...More と付け加える。

ただし、日本語などのマルチバイトで使用すると
たびたび最後の文字が文字化けを起こすという残念な関数でもある。

そこで、マルチバイト対応のtruncateを作るとよい。

関数は簡単で下記のコードだけ。
<?php
//文字の切捨て(マルチバイト対応) 
function smarty_modifier_mb_truncate($string, $length = 80, $etc = '...') {
if ($length == 0) {return '';}

if (mb_strlen($string) > $length) {
return mb_substr($string, 0, $length).$etc;
} else {
return $string;
}
}
?>

そして、上記のコードを「modifier.mb_truncate.php」という名前で保存し、
「smarty/libs/plugins」の中に入れればOK。

【ソース元】 詳細はこちら
マルチバイト文字に対応した truncate 修飾子を作る | バシャログ。

使い方はまったく同じ
{$string|mb_truncate:20:"...More"} 

知らずに危うく文字化け地獄にはまるところだった(笑)
いやーありがたい。

つうか、これくらい最初からSmartyにあっていいんじゃないの?

メンテナンス終了後、突然エラーが発生したロリポップサーバー。
原因はどうもSmartyを認識していないようだ。

Smartyを使用したウェブは他のサイトも一斉にストップ。
おいおいそりゃないだろって(^^;)
すぐに原因が解消されない可能性が高いので
一時的に静的なHTMLサイトに可能な限り変更した。

で、パスが変わったのだろうか・・・。
散々試してみたが解消されず、時間だけが刻々と過ぎる。
結局自前でSmartyをインストールすることにした。
どちらにせよロリポのSmartyには勝手にPluginを追加できないので
調度いいかも・・・これからは制限を気にせずにできるし。

Smartyのダウンロードはこちら。

ダウロード後、解凍してできたSmartyフォルダを
適当なフォルダにアップすればいい。
一般的にはルートディレクトリにlibsというフォルダを作って
その中に入れることが多い。
もちろんインクルードする際のパスはそちらへ。

ただ今回のサーバー問題はこれだけでは終わらなかった・・・。


今までimg要素のwidth、heightの属性は入れた方がいいと思っていました。
なくても普通に表示されますが、あった方が多少でも表示が速くなると考えていたので・・・。

しかし、最近の動向を見てみるとこの属性を入れない方がいいのではという
流れになりつつようです。

その理由としては、まず表示が速くなるとというレンダリングの問題は
ただの思い込みだったということ・・・もちろんNetscape Navigator 4.xくらいまで
さかのぼると入れなきゃ不具合が出るそうですが・・・もういいでしょ(^^;)

また、画像が表示されないときに、widthとheightが指定されていると、
指定したサイズからaltのテキストがはみ出すと、IEでは文字が切れて表示されます。

しかも100枚の異なる画像を表示させるという実験結果では、widht/height属性を与えた場合
と与えなかった場合において、微妙に属性がない方が速かったということです。
Web Designing誌2004年8月号の特集記事

ということで指定しなくても大丈夫というよりも
指定しない方がコーディングの手間も省けて
メリットが断然大きいようです。

PHPを使ってSmartyでページを表示させる際にwidht/height属性が
ちょっとうっとおしいなと思っていたのでかなりありがたい話題でした。


やっとロリポップがPHP4からPHP5になりました。
来年春ごろにはPHP4のサポートが終了するので
切り替えるなら早目がいいだろうと本日切り替えました。

・・・が、ホームページがまったく表示されなくなってしまい
超あたふた(^^;) 仕事で依頼されているお客様のサイト
だっただけにかなりあせりました。
しかも明日から新キャンペーンの告知予定だったし・・・。

PHP5に対応して作っていたはずなのですが、どうやら
Smartyがひっかかってしまったようです・・・でもなんで?

ロリポップだとSmartyへのパスは通常下記のように
記述するだけでよかったのですが

require_once('Smarty.class.php');

このままPHP5に切り替えるとSmartyが認識されず
エラーになってしまいます。

エラーメッセージ内のパスがちょっとおかしい気がしたので、
下記のようにパスをしっかりと記述してみました。

require_once('/usr/local/lib/php/Smarty/Smarty.class.php');

これで何とか対処できました。
ふぅ。

ページが多い場合は、.htaccessにinclude_pathを書いた方がいいでしょうね。

php_value include_path ".:/usr/local/lib/php/Smarty/"

Smartyのインストール

| コメント(0)
さくらレンタルサーバーに変更してから、初めてPHPを使ってみることに・・・。
あれ・・・Smarty入ってないの!? (^^;)

ということでSmartyのインストールから。
http://www.smarty.net/ から最新バージョンをダウンロード。

zipファイルの方をダウンロードし、PC上で解凍。
ルートディレクトリにlibs/smartyというフォルダを作って
そこに解凍したlibsフォルダの中身をごっそりアップ。

あとは、php.iniにインクルードパスを追加して何とか使えるようになりました。
include_path=".:/home/ドメインまたはアカウント/libs/smarty"

Smartyくらい最初から用意しておいてくれてもいいんじゃねーの?

ウェブページ

★過去に製作したウェブサイト(一部紹介)
イビキノン
いびきでよく眠れない方のサプリ
日本トレーラーハウス協会
トレーラーハウスの協会(JTHA)
トレーラーハウスデベロップメント
トレーラーハウスの製造・販売 シュミレーションゴルフのレンタル スクリーンゴルフのレンタル
健楽ショップ 【ボイスリッチEX】
声が出にくい症状の方に朗報
早稲田大学 スキー部
2007年 インカレ総合優勝!
NPO体験学習支援センター
ブナの植林100年計画実行中
AJC油汚染研究所
油ゲル化剤オイルフェンスの販売
ジャズシンガー 奥土居美可
NYで絶賛されたジャズボーカル