smartyで発生する先頭行の空白のメモ


追記2010/12

以下の関数で出力用バッファをクリア(消去)し、出力のバッファリングをオフにする事もできます

<?php
ob_end_clean();
?>


2007 10 21
時々、ここに来る人がいる様子なので、追記。
5月16日に書いたようなことと、

phpの?>を省略したりしている。

ヒアドキュメントを使った場合は、?>を省くとエラーになることがあるけれど、なくても、実害はない様子。

DreamWeaver8を使って、ページを開くと、文字コード混在していると、いつの間にか他の文字コードで、開いてしまうことがある。

<meta http-equiv="Content-Type" content="text/php; charset=euc-jp">
をページ先頭に入れると、その文字コードで読んでくれるので、よさそうだが、それでも、時々おかしくなることがある。

他のエディタで、確認したりしながら、使っている。


5月16日 追記

結局のところ、また、先頭行に空白が出来る。
原因?その時々で、いろんな文字コードで書くため、euc-jpで書いたドキュメントを、utf-8で開いて、気づかないで、eucで保存。といったところが、とても匂う。

phpファイルの、先頭に、XML宣言を書く。で、しばらく忘れる事にした。

5月、敗北感。

だらだら、長いので要約

スマーティ = ホワイトスペース の先入観強し。


先頭行の改行は、XML表示出来ずに致命傷。

先頭行の改行の清掃に挑戦した。

結果:よく解らないが、smartyじゃなかったかも。

$mime="text/xml"; 
header("Content-type: $mime");

この部分に改行が入っている。???

$mime="text/xml"; 
header("Content-type: trim($mime)");


という備忘です。

2006/04/07このやり方は、間違いでした。

Firefoxについては、これで表示できるようになりましたが、
IEでは、表示できなくなってしまった。

調べなおすと、
NNでtrim($mime)は、こんなの知らない。といわれる。
htmllintでヘッダー情報を表示させるとtrim(text/xml)等となっている。

Firefoxで表示できるようになったのは、
返されたヘッダーがおかしいものなので、
text/htmlで表示してやれと、判断したため、
エラーではなくて、表示をしただけかも、、、、。

またまた、振り出しに戻して、最終的には、

$smarty->load_filter('output', 'trimwhitespace');

スマーティのアウトプットフィルタで、表示できています。

Operaがtext/htmlで表示しているようです(???)が、

NN fireFox IEは良いようでした。

書いてしまった事柄なので、訂正等があれば、
また直していきます。

$smarty->load_filter('output', 'trimwhitespace');

$mime="text/xml"; 
header("Content-type: $mime");







Smartyはテンプレートエンジンと呼ばれたりして、インターネット上で動作するプログラムを作るための、phpというスクリプトの舎弟で、結構普及している。

phpでスクリプトを書く時には、ホームページなどでおなじみのhtmlと組み合わせて書いていく。だから、作っている時には、当然のように書いたプログラムも、後で見ると何がなんだかわからなくなる事が多い。

htmlと、スクリプトの部分をすみわけするためのプログラム。
これは、html的に言うと、テーブルタグで作ったhtmlが、テーブルが複雑に入れ子になっていて、とても見辛かったため、今じゃ、スタイルとhtml分けてすっきりしようぜ。ということと似ている。

テンプレートエンジンは、smartyに限らない。日本製もある。
smartyは、その中でも、結構人気があるほうだと思う。使用する分には、人気は関係ないけれど、人気があると、WEBでの情報が増えるので重宝する。

もっと正しくて詳細な解説は、私には無理なので、興味のある人は、WEBで調べてみて欲しい。


で、それが、思い通りに動いてくれない。というメモ。

本当の解決方法を知っている人は、教えてくれると嬉しい。

先頭行の改行が邪魔になって、xmlなどの表示に支障が出る。


Smartyは、なんかの拍子に、先頭行から何個か改行が入ったり、わずらわしい。

  • 条件:
    • ver:Smarty Smarty version 2.6.8
    • charset:euc-jp
    • return:LF(\n)
    • php: 4と5
何で先頭行に、空白が入るとわずらわしいのか。
  • XMLを表示する時に、先頭行に空白があると、エラーで表示できない。(FF)
  • xhtmlでマークアップする時にも、同様に、エラーになるかも
  • マークアップの検証ソフトにかけると、XML宣言の前に、改行なんかがでしゃばるな、と注意され、気分が悪い。
経過
  • 秀丸ってエディタで、書き始めた。スクリプトは、euc-jp。データ用のテキストファイルは、utf-8。
  • ローカルの、PHP Version 5.0.5 で表示しながら、チェック。
  • php4で動いてるサーバで、再度確認。
  • 変数名など、doaho とか、bakaじゃいけないので、dreamweaverというホームページ作成ソフトを使って、変数名の置換などやってみる事にした。
  • dreamweaver を使う時には、最初の行に、><を追加する事にしている。(いろんなので書くから、、)
  • なんとなくローカルサーバで表示したら、
XML パースエラー: 外部実体の初めに XML 宣言がありません。
URL: http://www.****.com/m1/cm_view.php?chr=utf8&doc=ipod
行番号: 2, 列番号: 1:
<?xml version="1.0" encoding="utf-8"?>
^

との理不尽な言葉。

ここで、原因は、あれだろうか?これだろうか?どれだろうか? という仕儀になり・・・

とりあえず、目に付いた改行には、死んでもらう。というベクトルが定まった。 とほ、


親分の Smarty.class.php に かちこんだ。

スクリプト外の改行とスクリプト内行先頭の改行に全てヒットマンを送った。

プラグインにも、internalsまでも、ミショニポーの容赦ない攻撃が続いたわけだが。

戦況は、ゲリラ戦の様相を見せ始めるのであった。

XML パースエラー: 外部実体の初めに XML 宣言がありません。
URL: http://www.****.com/m1/cm_view.php?chr=utf8&doc=ipod
行番号: 6, 列番号: 1:
<?xml version="1.0" encoding="utf-8"?>
^

ふ、増えてるじゃねーかぁーー。

まさに泥沼である。しかし、司令官は、冴えていた。

撤退。逃げろ!。忘れろ。外は天気だ。と究極の「気分を変えよう。」コマンドを発行した。



もっかい、最初から。で、

結果オーラーィ。

**template_c 


<?php /* Smarty version 2.6.8, created on 2006-04-06
 12:05:10
         compiled from cm_block_ipod_b.tpl */ ?>
<?php require_once(SMARTY_CORE_DIR . 'core.load_plug
ins.php');
smarty_core_load_plugins(array('plugins' =>
 array(array('modifier', 'date_format', 
'cm_block_ipod_b.tpl', 11, false),)), $this); ?>
<?php if ($this->_tpl_vars['view'] == 'search'): ?>
<?php echo '<?xml'; ?>
 version="1.0" encoding="<?php echo $this->_tpl_vars
['get_enc']; ?>
"<?php echo '?>'; ?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast
-1.0.dtd" version="2.0">

**php


<?php
require("./libs/Smarty.class.php");
error_reporting(E_ALL);
$smarty = new Smarty;
$smarty->compile_dir = './templates_c/';
$smarty->template_dir = './templates/';
/*-----略---------*/
  $output       = $smarty->fetch("$b_template_selected");
  $encoded_data = mb_convert_encoding($output, $get_enc,
"UTF-8");
if(isset($_GET['chr']) or isset($_GET['doc'])){

  if($mime == "text/javascript"){

    $encoded_data = str_replace(array("\r\n","\r","\n"),
"",$encoded_data);
  }

  header("Content-type: trim($mime)");
  echo $encoded_data;
  exit;

}else{

    $smarty->assign("encoded_data", $encoded_data);
    $smarty->display("$a_template_selected");
}

$fp = fopen("temp.php","w");
fclose($fp);?>


ダメなヤツは、


**template_c


<?php /* Smarty version 2.6.8, created on 2006-04-06 
12:34:10
         compiled from cm_block_ipod_b.tpl */ ?>
<?php require_once(SMARTY_CORE_DIR . 'core.load_
plugins.php');
smarty_core_load_plugins(array('plugins' => 
array(array('modifier', 'date_format', 'cm_block_
ipod_b.tpl', 9, false),)), $this); ?>
<?php if ($this->_tpl_vars['view'] == 'search'): ?>
<rss xmlns:itunes="http://www.itunes.com/dtds/
podcast-1.0.dtd" version="2.0">

**php

<?php
require("./libs/Smarty.class.php");
error_reporting(E_ALL);
$smarty = new Smarty;
$smarty->compile_dir = './templates_c/';
$smarty->template_dir = './templates/';
/*-----略---------*/
$output = $smarty->fetch("$b_template_selected");
$encoded_data = mb_convert_encoding($output, 
$get_enc,"UTF-8");
if(isset($_GET['chr']) or isset($_GET['doc'])){
  if($mime == "text/javascript"){
    $encoded_data = str_replace(array("\r\n","\r",
"\n"),"",$encoded_data);
  }
header("Content-type: $mime");
echo $encoded_data;
exit;
}else{
    $smarty->assign("encoded_data", $encoded_data);
    $smarty->display("$a_template_selected");
}
$fp = fopen("temp.php","w");
fclose($fp);
?><

で、どうやったら消えたんだい。

$mimeって変数には $mime="text/xml"; となっていて、header("Content-type: $mime");という使い方をしていた。

どうにも旨くないので、一行目に、header(... と書いた。それでも、先頭行に、1っこ改行があった。

それで、物は試しだから、header("Content-type: trim($mime)");としたら、改行が消えた。

まとめ


なんでよ。

TOP