smartyでsessionの値が参照できない
3/31追記
色々グーグル先生に聞きまくって行きついたサイト。
Smarty 2.6.25 はダメ: 粗忽(そこつ)のぶろぐ ― a hasty fellow diary ―
http://bitchesbrew.asablo.jp/blog/2010/01/15/4815658
自作の伝言板アプリが動かなくなった。
原因はsmartyの予約変数、$smarty.sessionが
参照できなくなっていたのだけど、何故なのかを探る
のにえらい時間とられた。。結局、ネットで検索したところ、2.6.25のバグということで、
本当の最新版2.6.26にしたところ、ようやく動いた。。
ぬぁんだとぅーーーーー!!(若本風
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
3時間ほど試行錯誤して全くいい結果が得られず。
PHP側で$_SESSION['hoge']は参照できるのに、Smartyの.tpl側で{$smarty.session.hoge}が参照できません。
環境
さくらレンタルサーバ
どなたか原因が分かる方、思い当たることがある方、ご教授ください。お願いします。
施してみたこと
-
- セッションIDを手動でsesにしてみた(変化なし)
- コンパイル済みのテンプレートファイルを削除して再生成(変化なし)
- mod_rewriteを疑い、rewriteが無関係なページでsessionのテスト(ここでも参照出来ず)
- php.iniを確認。(文字エンコやインクルードパスの設定のみなので思い当たる所なし。)
<?php require("smarty/Smarty.class.php"); require("MDB2.php"); class MySmarty extends Smarty{ private $_db; public function __construct(){ $this->Smarty(); $this->template_dir="〜〜php/smarty/templates/"; $this->compile_dir="〜〜php/smarty/templates_c/"; $this->config_dir="〜〜php/smarty/config/"; $this->config_load("config.conf",basename($_SERVER['SCRIPT_NAME'],".php")); $this->caching=2; $this->cache_dir="〜〜php/smarty/cache/"; $this->cache_lifetime=60*15; //$this->security=False; $dsn=array("phptype"=>"***","username"=>"***","password"=>"***","hostspec"=>"***","database"=>"***"); $this->_db=MDB2::connect($dsn); $this->_db->query("SET NAMES utf8"); } public function __destruct(){ $this->_db->disconnect(); } public function getDb(){ return $this->_db; } }
<?php //login.php 〜〜略〜〜 if($mb->getObject()->isDoCoMo()){ //docomoならばTrue ini_set('session.auto_start', 0); ini_set("session.use_cookies",0); ini_set("session.use_trans_sid",1); ini_set("session.name", "ses"); if(isset( $_GET['ses'])){ $sessionId = $_GET['ses']; session_id($sessionId); } } 〜〜略〜〜 session_start(); $_SESSION['name'] = $data['name']; if($mb->getObject()->isDoCoMo()){ //端末がdocomoならTrue header("Location: /tr/home?guid=ON&".session_name()."=".strip_tags(session_id())); }else{ header("Location: /tr/home?guid=ON"); } ?>
<?php // /tr/home $smarty = new MySmarty(); $smarty->caching=0; $smarty->load_filter('output', 'convert_encoding'); //UTF-8からShift-jisに変換するフィルタ if($mb->getObject()->isDoCoMo()){ ini_set('session.auto_start', 0); ini_set("session.use_cookies",0); ini_set("session.use_trans_sid",1); ini_set("session.name", "ses"); if ( isset( $_GET['ses'] )){ $sessionId = $_GET['ses'] ; session_id( $sessionId ) ; } } session_start(); if($_SESSION['name']===NULL){ $smarty->assign("err_mes","セッションが切れています。<br />発行されたURLから再ログインしてください。"); $smarty->display("templates/mobile/common/error.tpl"); exit(); } $smarty->display("templates/mobile/home.tpl"); ?>
<!--home.tpl--> {include file="mobile/common/header.tpl"} {$smarty.session.name}さんのマイページ <hr> <ol style="padding:0 5px;"> <li><a href="/tr/gps?guid=ON" accesskey="1">メニュー1</a></li> <li><a href="/tr/friend?guid=ON" accesskey="2">メニュー2</a></li> <br /> <li><a href="/tr/logout?guid=ON">ログアウト</a></li> </ol> <hr> {include file="mobile/common/footer.tpl"}
PHPで携帯電話からのアクセスかを判別するスクリプト書いた(その3)
前回までのソースを0からファクトリーパターンで書き直したことで拡張性が増した。
ここにはソース全て書ききれないのでスクリプトの詳細な解説は省きます。
ソースのDL:夢幻
変更点
-
- ファクトリーパターンで0から書き直した。
- Net_UserAgent_Mobileで取得出来る端末情報が取り出せるようになった。
利用方法
<? include_once("CheckMobile.php"); try { $mb = CheckMobile::factory(); } catch (CheckMobile_Exception $e) { var_dump($e->getMessage()); exit(); } if($mb->Check()===TRUE){ print"携帯からのアクセスです"; $mb->getObject()->getUID(); //個体識別番号 if($mb->getObject()->isEZweb()){ print "auからのアクセスです"; }else{ print "その他機種からのアクセスです"; } }else{ print"携帯以外からのアクセスです"; } $mb->GetDoctype(); $mb->GetHtmlTags(); $mb->GetContentType(); ?>
メソッド解説
static object factory()
ユーザーエージェントによる簡易的な機種判別をします。
object getObject()
携帯端末の情報が入ったオブジェクトを取得できます。
メソッドはこちらを参照してください
Net_UserAgent_Mobile
http://pear.php.net/package/Net_UserAgent_Mobile/docs
bool Check()
IPアドレス帯域でより厳格な判別を行います。
携帯ならばTrueが返りそれ以外ならFalseが返ります。
String GetDoctype();
各機種に対応したXHTML1.0
準拠のドキュメントタイプが返されます
auの場合、
<!DOCTYPE html PUBLIC \"-//OPENWAVE//DTD XHTML 1.0//EN\" \"http://www.openwave.com/DTD/xhtml-basic.dtd\" />となります。
String GetHtmlTags();
各機種に対応したXHTML1.0
準拠のHTMLタグが返されます
auの場合、
<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"ja\" xml:lang=\"ja\" />
となります。
PHPで携帯電話からのアクセスかを判別するスクリプト書いた(その2)
前回の記事からクラスを少し修正しました。
ここにはソース全て書ききれないのでスクリプトの解説は省きます。
ソースのDL:夢幻
変更点
-
- ユーザーエージェントを取得出来るメソッドを追加した
これでキャリア別に振り分けることが出来るように。
利用方法
<? require_once("check_mobile.php"); $mb = new MobileCheck; if($mb->Check()===TRUE){ print $mb->GetUserAgent(); print "携帯電話からのアクセスです"; }else{ print "携帯電話以外からのアクセスです"; } ?>
メソッド詳細
String :: GetUserAgent()
ユーザーエージェントを取得します。
bool :: Check()
携帯電話からのアクセスかを判別します。
- 携帯からのアクセスと判別・・・TRUEを返す
- 携帯以外のアクセスと判別・・・FALSEを返す
PHPで携帯電話からのアクセスかを判別するスクリプト書いた
携帯からのみアクセスを許したいページを作りたいとき、何で判別していますか?
UserAgentで判別。それだけではいけません。
UserAgentなんて簡単に偽装されてしまいます。
そこで、IPアドレス帯域を検査することで大丈夫。
携帯電話は各キャリアのサーバを経由してWebサーバにアクセスします。
その際、Webサーバに対して各キャリアのサーバのIPアドレスがリクエスト要求元のIPアドレスとして通知されます。
これは偽装しようが無いので信頼できる情報です。
ソース
<?php class MobileCheck{ private $zone; private function SetZone($env){ /* IP帯域の設定 */ if($env === 'docomo'){ //i-mode(NTT DoCoMo)のIPアドレス帯域を設定 //更新日時:2010-03-10 //http://www.nttdocomo.co.jp/service/imode/make/content/ip/index.html $this->zone[0] = '210.153.84.0/24'; $this->zone[1] = '210.136.161.0/24'; $this->zone[2] = '210.153.86.0/24'; $this->zone[3] = '124.146.174.0/24'; $this->zone[4] = '124.146.175.0/24'; }elseif($env === 'au'){ //EZWeb(au)のIPアドレス帯域を設定 //更新日時:2010-03-10 //http://www.au.kddi.com/ezfactory/tec/spec/ezsava_ip.html $this->zone[0] = '210.230.128.224/28'; $this->zone[1] = '121.111.227.160/27'; $this->zone[2] = '61.117.1.0/28'; $this->zone[3] = '219.108.158.0/27'; $this->zone[4] = '219.125.146.0/28'; $this->zone[5] = '61.117.2.32/29'; $this->zone[6] = '61.117.2.40/29'; $this->zone[7] = '219.108.158.40/29'; $this->zone[8] = '219.125.148.0/25'; $this->zone[9] = '222.5.63.0/25'; $this->zone[10] = '222.5.63.128/25'; $this->zone[11] = '222.5.62.128/25'; $this->zone[12] = '59.135.38.128/25'; $this->zone[13] = '219.108.157.0/25'; $this->zone[14] = '219.125.145.0/25'; $this->zone[15] = '121.111.231.0/25'; $this->zone[16] = '121.111.227.0/25'; $this->zone[17] = '118.152.214.192/26'; $this->zone[18] = '118.159.131.0/25'; $this->zone[19] = '118.159.133.0/25'; $this->zone[20] = '118.159.132.160/27'; $this->zone[21] = '111.86.142.0/26'; $this->zone[22] = '111.86.141.64/26'; $this->zone[23] = '111.86.141.128/26'; $this->zone[24] = '111.86.141.192/26'; }elseif($env === 'softbank'){ //Yahoo!ケータイ(SoftBank)のIPアドレス帯域を設定 //更新日時:2010-03-10 //http://developers.softbankmobile.co.jp/dp/tech_svc/web/ip.php $this->zone[0] = '123.108.236.0/24'; $this->zone[1] = '123.108.237.0/27'; $this->zone[2] = '202.179.204.0/24'; $this->zone[3] = '202.253.96.224/27'; $this->zone[4] = '210.146.7.192/26'; $this->zone[5] = '210.146.60.192/26'; $this->zone[6] = '210.151.9.128/26'; $this->zone[7] = '210.175.1.128/25'; $this->zone[8] = '211.8.159.128/25'; }elseif($env === 'willcom'){ //AIR-EDGE PHONE(WILLCOM)のIPアドレス帯域を設定 //更新日時:2010-03-10 //http://www.willcom-inc.com/ja/service/contents_service/club_air_edge/for_phone/ip/ $this->zone[0] = '61.198.128.0/24'; $this->zone[1] = '61.198.129.0/24'; $this->zone[2] = '61.198.130.0/24'; $this->zone[3] = '61.198.131.0/24'; $this->zone[4] = '61.198.132.0/24'; $this->zone[5] = '61.198.133.0/24'; $this->zone[6] = '61.198.134.0/24'; $this->zone[7] = '61.198.135.0/24'; $this->zone[8] = '61.198.136.0/24'; $this->zone[9] = '61.198.137.0/24'; $this->zone[10] = '61.198.138.100/32'; $this->zone[11] = '61.198.138.101/32'; $this->zone[12] = '61.198.138.102/32'; $this->zone[13] = '61.198.138.103/32'; $this->zone[14] = '61.198.139.0/29'; $this->zone[15] = '61.198.139.128/27'; $this->zone[16] = '61.198.139.160/28'; $this->zone[17] = '61.198.140.0/24'; $this->zone[18] = '61.198.141.0/24'; $this->zone[19] = '61.198.142.0/24'; $this->zone[20] = '61.198.143.0/24'; $this->zone[21] = '61.198.160.0/24'; $this->zone[22] = '61.198.161.0/24'; $this->zone[23] = '61.198.162.0/24'; $this->zone[24] = '61.198.163.0/24'; $this->zone[25] = '61.198.164.0/24'; $this->zone[26] = '61.198.165.0/24'; $this->zone[27] = '61.198.166.0/24'; $this->zone[28] = '61.198.168.0/24'; $this->zone[29] = '61.198.169.0/24'; $this->zone[30] = '61.198.170.0/24'; $this->zone[31] = '61.198.171.0/24'; $this->zone[32] = '61.198.172.0/24'; $this->zone[33] = '61.198.173.0/24'; $this->zone[34] = '61.198.174.0/24'; $this->zone[35] = '61.198.175.0/24'; $this->zone[36] = '61.198.248.0/24'; $this->zone[37] = '61.198.249.0/24'; $this->zone[38] = '61.198.250.0/24'; $this->zone[39] = '61.198.251.0/24'; $this->zone[40] = '61.198.252.0/24'; $this->zone[41] = '61.198.253.0/24'; $this->zone[42] = '61.198.254.0/24'; $this->zone[43] = '61.198.255.0/24'; $this->zone[44] = '61.204.0.0/24'; $this->zone[45] = '61.204.2.0/24'; $this->zone[46] = '61.204.3.0/25'; $this->zone[47] = '61.204.3.128/25'; $this->zone[48] = '61.204.4.0/24'; $this->zone[49] = '61.204.5.0/24'; $this->zone[50] = '61.204.6.0/25'; $this->zone[51] = '61.204.6.128/25'; $this->zone[52] = '61.204.7.0/25'; $this->zone[53] = '61.204.92.0/24'; $this->zone[54] = '61.204.93.0/24'; $this->zone[55] = '61.204.94.0/24'; $this->zone[56] = '61.204.95.0/24'; $this->zone[57] = '114.20.49.0/24'; $this->zone[58] = '114.20.50.0/24'; $this->zone[59] = '114.20.51.0/24'; $this->zone[60] = '114.20.52.0/24'; $this->zone[61] = '114.20.53.0/24'; $this->zone[62] = '114.20.54.0/24'; $this->zone[63] = '114.20.55.0/24'; $this->zone[64] = '114.20.56.0/24'; $this->zone[65] = '114.20.57.0/24'; $this->zone[66] = '114.20.58.0/24'; $this->zone[67] = '114.20.59.0/24'; $this->zone[68] = '114.20.60.0/24'; $this->zone[69] = '114.20.61.0/24'; $this->zone[70] = '114.20.62.0/24'; $this->zone[71] = '114.20.63.0/24'; $this->zone[72] = '114.20.64.0/24'; $this->zone[73] = '114.20.65.0/24'; $this->zone[74] = '114.20.66.0/24'; $this->zone[75] = '114.20.67.0/24'; $this->zone[76] = '114.21.255.0/27'; $this->zone[77] = '125.28.0.0/24'; $this->zone[78] = '125.28.1.0/24'; $this->zone[79] = '125.28.15.0/24'; $this->zone[80] = '125.28.16.0/24'; $this->zone[81] = '125.28.17.0/24'; $this->zone[82] = '125.28.2.0/24'; $this->zone[83] = '125.28.3.0/24'; $this->zone[84] = '125.28.4.0/24'; $this->zone[85] = '125.28.5.0/24'; $this->zone[86] = '125.28.8.0/24'; $this->zone[87] = '210.168.246.0/24'; $this->zone[88] = '210.168.247.0/24'; $this->zone[89] = '210.169.92.0/24'; $this->zone[90] = '210.169.93.0/24'; $this->zone[91] = '210.169.94.0/24'; $this->zone[92] = '210.169.95.0/24'; $this->zone[93] = '210.169.96.0/24'; $this->zone[94] = '210.169.97.0/24'; $this->zone[95] = '210.169.98.0/24'; $this->zone[96] = '210.169.99.0/24'; $this->zone[97] = '211.126.192.128/25'; $this->zone[98] = '211.18.232.0/24'; $this->zone[99] = '211.18.233.0/24'; $this->zone[100] = '211.18.234.0/24'; $this->zone[101] = '211.18.235.0/24'; $this->zone[102] = '211.18.236.0/24'; $this->zone[103] = '211.18.237.0/24'; $this->zone[104] = '219.108.10.0/24'; $this->zone[105] = '219.108.11.0/24'; $this->zone[106] = '219.108.12.0/24'; $this->zone[107] = '219.108.13.0/24'; $this->zone[108] = '219.108.14.0/24'; $this->zone[109] = '219.108.15.0/24'; $this->zone[110] = '219.108.7.0/24'; $this->zone[111] = '219.108.8.0/24'; $this->zone[112] = '219.108.9.0/24'; $this->zone[113] = '221.119.0.0/24'; $this->zone[114] = '221.119.1.0/24'; $this->zone[115] = '221.119.2.0/24'; $this->zone[116] = '221.119.3.0/24'; $this->zone[117] = '221.119.4.0/24'; $this->zone[118] = '221.119.6.0/24'; $this->zone[119] = '221.119.7.0/24'; $this->zone[120] = '221.119.8.0/24'; $this->zone[121] = '221.119.9.0/24'; $this->zone[122] = '114.20.49.0/24'; $this->zone[123] = '114.20.50.0/24'; $this->zone[124] = '114.20.51.0/24'; $this->zone[125] = '114.20.52.0/24'; $this->zone[126] = '114.20.53.0/24'; $this->zone[127] = '114.20.54.0/24'; $this->zone[128] = '114.20.55.0/24'; $this->zone[129] = '114.20.56.0/24'; $this->zone[130] = '114.20.57.0/24'; $this->zone[131] = '114.20.58.0/24'; $this->zone[132] = '114.20.59.0/24'; $this->zone[133] = '114.20.60.0/24'; $this->zone[134] = '114.20.61.0/24'; $this->zone[135] = '114.20.62.0/24'; $this->zone[136] = '114.20.63.0/24'; $this->zone[137] = '114.20.64.0/24'; $this->zone[138] = '114.20.65.0/24'; $this->zone[139] = '114.20.66.0/24'; $this->zone[140] = '114.20.67.0/24'; $this->zone[141] = '114.21.255.0/27'; } }//func-SetZone function GetZone(){ return $this->zone; } private function CheckUA(){ require_once ('Net/UserAgent/Mobile.php'); $agent = Net_UserAgent_Mobile::singleton(); /* UserAgentからキャリアを返す */ if($agent->isDoCoMo()){ $this->SetZone("docomo"); }elseif($agent->isSoftbank()){ $this->SetZone("softbank"); }elseif($agent->isEZweb()){ $this->SetZone("au"); }elseif($agent->isWillcom()){ $this->SetZone("willcom"); }else{ return FALSE; } }//func-CheckUA private function CheckIP($area){ if($area===NULL){ throw new Exception('帯域リストの取得に失敗'); } require_once ('Net/IPv4.php'); /* IPアドレス帯域($area)に含まれているか検査 */ $flag = FALSE; foreach ($area as $value) { if (Net_IPv4::ipInNetwork($_SERVER["REMOTE_ADDR"], $value)) { $flag = TRUE; break; } } return $flag; }//func-CheckIP public function Check(){ $ua = $this->CheckUA(); if($ua===FALSE){ return FALSE; }else{ $zone = $this->GetZone($ua); return $this->CheckIP($this->GetZone()); } } }//class-MobileCheck ?>
利用方法
<?php try{ $mb = new MobileCheck; if($mb->Check()===TRUE){ print "(mobile access)<br>携帯電話からのアクセスですね?"; }else{ print "(not mobile access)<br>携帯電話以外からのアクセスですね?"; } }catch(Exception $e){ print $e->getMessage(); } ?>
MobileCheckクラスをインスタンス化して、Checkメソッドを呼び出すだけ。
Checkメソッドを呼び出すと、携帯と判別すればTRUE,携帯ではないと判別すればFalseが返る。
これだけ。
手法
PHPでレイヤー方式で画像を生成するavatar.phpが便利(修正)
情報がいまいち足りていなかったので追記して新しく上げました。
ソースのDL
PHPスクリプトのDLは以下のサイトから。(英語)
How to make custom avatars with PHP | BolducPress, a web design blog
avatar.phpはThe Source Files下のリンク、
「Download the PHP and Photoshop Files」からDL出来ます。
使用前の注意
-
- 使用する画像は全て同じ寸法であること
- 背景が透明であること
- 24ビットpngイメージであること(32ビットpngでも動作しました。)
<?php include_once("avatar.php"); //インスタンス化 $avatar = new avatar; //出力時の画像の横幅の設定(縦横比は維持されます。) $avatar->set_width(100); //画像の背景の設定 //画像のファイル名、または16進数カラーコード。 $avatar->set_background("my_background_image.png"); //または $avatar->set_background("#000000"); //保存する場合のファイル名(要拡張子) //ファイル名を指定しない場合は保存されずにそのまま出力されます。 $avatar->set_filename("avatar.jpg"); //ここからpngの透過画像をレイヤーとして追加していきます。 $avatar->add_layer("base.png"); $avatar->add_layer("beer.png"); $avatar->add_layer("hat.png"); $avatar->add_layer("shorts.png"); $avatar->add_layer("mustache.png"); //画像の出力 $avatar->build(); ?>
これだけ。ね?簡単でしょ?
配布元のサイトへ行けば詳しいソースの解説もあります。
How to make custom avatars with PHP | BolducPress, a web design blog
PHPでレイヤー方式で画像を生成するavatar.phpが便利
ソースコードのDL
PHPスクリプトのDLは以下のサイトから。(英語)
How to make custom avatars with PHP | BolducPress, a web design blogのThe Source Files下のリンク、
「Download the PHP and Photoshop Files」からDL出来ます。
利用方法
<?php include_once("avatar.php"); //インスタンス化 $avatar = new avatar; //出力時の画像の横幅の指定(単位:px 縦横比は維持されます。) $avatar->set_width(100); //画像の背景色の設定 $avatar->set_background("#000000"); //ベースとなる背景画像(例えば衣服を着ていないキャラクターの画像、背景となる風景の写真など) $avatar->set_background("my_background_image.png"); //ここからpngの透過画像をレイヤーとして追加していきます。 $avatar->add_layer("base.png"); $avatar->add_layer("beer.png"); $avatar->add_layer("hat.png"); $avatar->add_layer("shorts.png"); $avatar->add_layer("mustache.png"); //画像の出力 $avatar->build(); ?>
これだけ。ね?簡単でしょ?
配布元のサイトへ行けば詳しいソースの解説もあります。
How to make custom avatars with PHP | BolducPress, a web design blog
ただ、レイヤーを何枚も重ねる場合、出力された画像を別ライブラリで
キャッシュしないと毎度毎度出力するには少し処理が遅くなります。