アプリ版:「スタンプのみでお礼する」機能のリリースについて

<?php
 $mes = 123;
print<<<EOF
 <script Language="JavaScript">
 <!--
  JavaScript:alert( $mes );
 //-->
 </script>
EOF;
?>

↑のコードを実行すると123というメッセージボックスが表示されます。

<?php
 $mes = "aaa";
print<<<EOF
 <script Language="JavaScript">
 <!--
  JavaScript:alert( $mes );
 //-->
 </script>
EOF;
?>

しかしこのように数値変数でははく文字列変数を渡すと表示できません。
JavaScriptにPHPの文字列変数を受け渡すことはできるのでしょうか?

A 回答 (2件)

前提:


一旦PHPの事は忘れます。あとjavascript:alert("hoge");じゃなくてalert("hoge");にします
EcmaScriptのParserからみると
それぞれ

<script type="text/javascript">
alert( 123 );
</script>

<script type="text/javascript">
alert( aaa );
</script>

を解釈することになるんですが,
後者のaaaは
「文字列リテラル"aaa"ではなく宣言されずに使われている【変数】aaaです。」
前者は
「変数ではなく数値リテラルの123です。」

EcmaScriptの立場で

<script type="text/javascript">
alert("aaa");
</script>
となるように

<?php
$mes = "aaa";
print<<<EOF
<script type="text/javascript">
alert("$mes");
</script>
EOF;
?>

と書いてみると,確かにaaaという文字列がウィンドウに表示されます。
ただし,【原理を説明するためにこういうコードを書いたけど、正直お勧めできません。】

a(改行)bを表示しようとして

<?php
$mes = "a\nb";
print<<<EOF
<script type="text/javascript">
alert("$mes");
</script>
EOF;
?>

と書いてしまうと,PHPは正しく実行されますが,EcmaScriptでコンパイルエラーになります。
PHPと違い,文字列リテラル中に改行を入れることできないので。

<?php
$mes = "a\"";
print<<<EOF
<script type="text/javascript">
alert("$mes");
</script>
EOF;
?>

となってもやっぱりEcmascript側でコンパイルエラーが出るでしょう。(それぞれ正しく表示される書き方がありますね?)
その場限りの対処で,後手後手になってバグの温床になるのは防ぎたいものですな。

そこで・・・

二つ考えてみた。

パーセントエンコードはEcmascriptのdecodeURIComponent関数で
容易にデコードでき,PHP側にもそのようなエンコードを行う関数が存在し,
http://jsgt.org/ajax/ref/charset_test/responsete …
その中には\や"や'が出て来ず,Ecmascript側のソースの文字符号化方式が利用する文字集合を利用できる、と利点があるので

<?php
$mes = "あ\"\nb";
$encmes = (unicode)rawurlencode((binary)$mes);
print<<<EOF
<script type="text/javascript">
alert(decodeURIComponent("$encmes"));
</script>
EOF;
?>

とする。
PHP6でない場合は(binary)や(unicode)によるキャストしちゃ駄目でUTF-8の文字列にしないと駄目かも。
するとEcmaScript視点で

<script type="text/javascript">
alert(decodeURIComponent("%E3%81%82%22%0Ab"));
</script>

となり,
PHPの文字列リテラルが意味する文字列そのものが表示できるようになる。

この方法だと,クライアント側からのコードの可読性が低いので
もし,別なURIで内容を提供することができ,望ましいならば(この条件は認証とかいろんな問題が出てくるかもしれないから)
そっちに書き出しておいて
XMLHTTPRequestを使って読み取る形をとる。コードは書かないけど。
====================
ここからは余談。
1.俺はヒアドキュメントが好きじゃない。
俺の無知かもしれないが,ヒアドキュメント内で関数が使えなかったから
その外部で別な変数$enc_mesを使って可読性を低めざるを得なかった。

2.文字列リテラル中の変数展開も好きじゃない。
$fuga = "2";
$hoge = "りんごが{$fuga}個";
と書くくらいなら
"りんごが" . $fuga . "個";と書く。
'りんごが{$fuga}個'
という意味で書いたつもりでバグを作るのは嫌だから

3.一々コードを書くのも面倒くさいし,説明が解りにくくなるから書かなかったけど,
html要素,head要素,title要素,body要素等を全て省略したコードが好きじゃない。

4.PHPが吐き出すのはECMAScriptの部分だけで
別のhtmlから外部スクリプトとして読み込む形が好きだなあ。

#インタプリタなのでコンパイルエラーって表現はおかしいけど,許して。
    • good
    • 0
この回答へのお礼

すごく詳しい解説大変ありがとうございます!
本当に勉強になりました!!

お礼日時:2009/01/08 11:47

クォートしていないからでは?

    • good
    • 0
この回答へのお礼

クォートとは何のことでしょうか?

お礼日時:2009/01/02 08:26

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!