JavaScriptにPHPを含めることは悪い習慣と見なされますか?


55

このサイトでは何度もこのようなことをしようとしている人がいます:

<script type="text/javascript">
  $(document).ready(function(){

     $('<?php echo $divID ?>').click(funtion(){
       alert('do something');
     });

  });
</script>

これは、人々が自然に陥るようなパターンではないと思います。これを示しているチュートリアルや学習資料がそこになければなりません。そうでなければ、それはあまり見られません。私が求めているのは、これをあまりにも大きくしているのですか、これは本当に悪い習慣ですか?

編集: これについて私の友人に話していました。彼はしばしばJavaScriptにルビーを入れて、この点を持ち出しました。

JavaScriptにアプリケーション全体の定数を動的に配置して、2つのファイルを編集する必要はありませんか?例えば...

MYAPP.constants = <php echo json_encode($constants) ?>;

また、ライブラリで使用する予定のデータを直接エンコードしてもかまいません

ChartLibrary.datapoints = <php echo json_encode($chartData) ?>;   

または毎回AJAX呼び出しを行う必要がありますか?


4
私にはthis question will likely solicit opinion, debate, arguments, polling, or extended discussion.
DaveRandom

7
@ M.Babcockこれは.phpファイルの一部になるため、phpコードはサーバー側で実行され、クライアントはエコーの結果のみを表示します。

8
動的に生成されたJavaScriptを作成した人は誰でも取り戻し、対処されます
Raynos

5
@Mattその後、私は戻って、Googleとその対処取るよ
レイノス

4
「私のPHPでjavascriptを入手しました!」「いいえ、私の javascriptにPHPがあります!」
ジョシュダーネル

回答:


83

通常、言語Xを使用して言語Yでコードを生成すること悪い習慣です。

データを唯一のインターフェースにして、2つの言語を切り離してみてください。コードを混同しないでください。

この例では、PHPをcfg使用して、JavaScriptで使用可能な構造を設定することでコードを改善できます。

<script type="text/javascript">
  var cfg = {
    theId: "<?php echo $divID ?>",
    ...
  };

  $(document).ready(function(){
     $("#" + cfg.theId).click(funtion(){
       alert('do something');
     });
  });
</script>

このように、PHPはデータ構造の生成のみを考慮し、JavaScriptはデータ構造の消費のみを考慮します。

このデカップリングは、将来的に非同期(JSON)でデータをロードする方法にもつながります。

更新:

更新で尋ねた追加の質問に答えるために、はい、DRY原則を適用し、PHPとJavaScriptが同じ構成オブジェクトを共有することをお勧めします。

<script type="text/javascript">
  var cfg = <?php echo json_encode($cfg) ?>;

  ...

このように、設定のJSON表現をページに直接挿入しても害はありません。必ずしもXHR経由で取得する必要はありません。


21
ただし、MySQLパスワードを$ cfgに入れないでください!!
トーマス・ボニーニ

13
「データを唯一のインターフェイスにします。コードを混同しないでください。」これは本当に問題の核心を切り取って、2つの言語を一緒に使用するときの経験則としては良いと思います。洞察力をありがとう。
グレッグ・グイダ

6
data-HTMLの属性にそのJSONを含めることもできます。のようなもの<body data-cfg="{...}">
カパ

1
@bazmegakapa私はそれが最良の選択肢かもしれないと思う。特に、XSSインジェクションのリスクを大幅に削減するHTML DOMなどのAPIを使用できます。
luiscubal

1
インターフェースとしてデータを使用し、コードを生成するコードを妨害することを提案するための+1。
ブランドン

21

動的に生成されたJavaScriptは恐ろしく、悪い習慣です。

あなたがすべきことは、懸念の分離と進歩的強化の意味を理解することです。

これは基本的に、動的HTMLと静的JavaScript(HTMLを拡張する)があることを意味します。

あなたの場合、おそらくあなたのdivにクラスが必要で、クラスセレクタでそれを選択してください


10

スニペットの最大の問題は、#それを有効なjQueryセレクターにするための行方不明です;)。

可能であれば、JavaScriptにPHPを含めないようにしてください。click()ハンドラー内のセレクターをクラスに変更し、ハンドラーを起動したい場合はその要素をクラスに追加し、そうでない場合は何が問題なのですか。

<script type="text/javascript">
  $(document).ready(function(){

     $('.foo').click(funtion(){
       alert('do something');
     });

  });
</script> 

<div id="bar" class="<?php echo ($someCond ? 'foo' : ''); ?>">Hello</div>

そこているあなたはJavaScriptでPHPを含める必要があり事情が。しかし、これらはごくわずかであることを認めなければなりません。

1つの例は、異なる環境がある場合です。テスト、ステージング、ライブ。それらはそれぞれ、アセット(主に画像)の異なる場所を持っています。JavaScriptで使用できるようにパスを設定する最も簡単な方法は次のようなものです。

var config = { assets: "<?php echo $yourConfig['asset_url']; ?>" };

私の想像上のphpコードの残りの部分では、すでに#=)を追加していますが、真剣に、あなたはそれがより良い方法であることに同意します。私もそのようにするのが自然に思えます。それで、なぜ私たちはそれがそれが必要でない場所でそんなに頻繁に見ますか?
グレッグ・グイダ

環境をすべて同じ方法で設定することで、構成ファイル内の静的データのエコーを簡単に回避できることに注意してください。
Raynos

4
@GregGuida:私の推測では、プログラマーがWeb開発で得られるようなクライアント/サーバーアーキテクチャーに対処することはほとんどないでしょう。DB <-> PHP <-> HTML / JS / CSSを1つとして扱い、どこに行くべきか、レイヤーをどのように分離するべきかを完全には理解していません。
マット

@Matt私はそれがおそらく最も良い説明だと思う
グレッグGuida

2
$divID = '#' . $element_id_value;-セレクターボスには問題ありません;)
rlemon

8

このファイルをsomething.phpと呼ぶ必要があり、たとえば圧縮することはできず、サーバーのものとJavaScriptを混在させることはできないことは言及していないため、これは私の意見では悪い習慣です。PHPとJSの混合をできるだけ制限するようにしてください。

代わりにいつでもこれを行うことができます:

function setOnClick(divid) {
 $(divid).click(funtion(){
   alert('do something');
 });
}

そして、これらのミキシングをできるだけ小さくするために、phpファイルでこの関数を呼び出すことができます。

$(function() {
  setOnClick('<?php echo $divId; ?>');
});

これを行うことで(重要ではない2〜3行ではなく、より大きなJSファイルを持つ)、JSファイルを圧縮することを活用でき、フロントエンド開発者は私の意見ではJavaScriptだけで作業することを非常に快適に感じることができますPython、Rubyなど、PHPだけでなく、コードは、そこで何をする必要があるかによってますます大きくなる可能性があります。


2
私はJSにPHPを決して入れないので、完全に同意します。私はいつもこのサイトでそれを見ています。
グレッグ・グイダ

PHPコードがブラウザに到達することはありません!単純なJavaScriptになっているはずの評価されたコードだけです。したがって、ファイルサイズ/圧縮は問題ではありません。まだ悪い練習だと思いました!
ジェームス・アンダーソン14年

@JamesAnderson alessioalexは縮小(Uglifyなど)を指していると思います。phpを実行し、後処理php関数で応答を解析し、スクリプトタグを特定し、それをUglifyで実行し、元のphpで生成されたJSを縮小版に置き換えてから応答を送信することもできます。しかし、すべてのリクエストでそれを行うことは、いいね!アプローチ。
ジングレスチュラ

6

これは悪い習慣ではないと思います。JavaScriptで必要なIDが動的な場合、これを行う他の方法はありません。


5
なぜカスルの不浄な名前の中で、あなたはIDタグの名前を知らないのですか?
シークレット

3
@ Incognito、IDがわからない場合が多くあります... ajaxを使用して新しいコードブロックを生成している場合、新しいJSと共に一意のIDを生成している可能性があります...参照されるIDは、結果のコードブロックにあるjsと同じであることを確認してください。このようなインスタンスはさらに多くあり、ajaxが関係している場合、またはサーバー側のif-elseステートメントなどに依存するコードの大きなブロックがある場合、かなり一般的です

7
@raynjamin私はそれがあなたがしていることである状況に自分自身を置く方法を理解していません...またはクラスで選択してからタグをリストし、次に隠されたCSS値を持つID属性、そのセレクターマン...実際に見るのは苦痛です...どこから始めればよいかさえわかりません... 大量のコードブロックなどをカットアンドペーストして、複数のIDで機能するようにしますか?私も...好きではない...私の脳。ここで爆発しています。
シークレット

3
dom / html / whateverについて読んでください...検索エンジンを使用してください...なぜこのようなことをダイナミックHTMLで行う必要がなかったのですか?
シークレット

5
番号。IDタグがどのように機能するか理解できません。私はあなたが言っていることを正確に理解しています。
シークレット

6

この悪い習慣を考えます。スクリプトブロック内に動的コンテンツを配置する場合、javascriptコンテキスト内でのエスケープは期待するほど単純ではないという事実に常に注意する必要があります。値は、ユーザが提供した場合、ない、それらを、HTMLエスケープするのに十分な。

OWASP XSSチートシートは、より多くの詳細を持っていますが、基本的には、このパターンを採用すべきです:

<script id="init_data" type="application/json">
    <?php echo htmlspecialchars(json_encode($yourdata)); ?>
</script>

次に、メインhtmlからリンクされた別の.jsファイルで、次のコードをロードします。

var dataElement = document.getElementById('init_data');
var jsonText = dataElement.textContent || dataElement.innerText  // unescapes the content of the span
var initData = JSON.parse(jsonText);

別の.jsファイルを使用する理由は2つあります。

  • キャッシュ可能であるため、パフォーマンスが向上します
  • HTMLパーサーはトリガーされないため、誰かがどこかにクイック<?phpタグを置くことによってXSSバグがすり抜けるリスクはありません。

XSS角度を完全に説明するための+1!JSONはdomready前にロードされているので、あなたのアプローチは、より速くロードされますが、私は使用してから解析し自動JSONを好む$.ajaxまたは類似
roo2

5

一部の人々は、それは悪い習慣だと主張するでしょう。これはJS内のPHPであるためではなく、インラインJSであるため、次回の読み込みを容易にするためにブラウザによってキャッシュされないためです。

IMOでは、2つの言語間で変数を渡すためにJSONを使用することを常にお勧めしますが、それはあなた次第だと思います。


5

私は一般的にそれをしないと言うでしょう。しかし、PHP-> Javascriptからデータを渡したい場合、以下に示す形式のコードがあるインラインJavascriptブロックを持っているのに夢中になることはありません。ここでは、コードはPHPからjavascriptにデータを渡すだけで、オンザフライなどでロジックを作成していません。これを行う場合とajax呼び出しを行うことの良い点は、ページが読み込まれるとすぐにデータが利用可能になり、サーバーへの余分なトリップが不要になることです。

<script>
window.config = <?php echo json_encode($config);?>;
</script>

もちろん、他のオプションは、.jsファイルに配置する何らかの形式のビルドスクリプトを介してPHPからjavascript構成ファイルをビルドすることです。


4

本当に問題を引き起こす可能性があると私が考えることができる唯一のことは、PHPエラーが表示されるように設定されているため、JavaScriptにPHPエラーを示すHTMLの負荷を押し込みます。

また、スクリプト内でそれが表示されないため、スクリプトが壊れている理由を理解するのに時間がかかることがあります。


これが大きなエラーを引き起こす素晴らしいケース
グレッグギーダ

3

それはだれに依存します、そして、あなたが私に尋ねるならば、はい、私はいくつかの理由でそれを逆行練習と考えます。まず第一に、PHPパーサーがアクセスできないJavaScriptファイルを独自のJSファイルに入れたいと思います。

第二に、phpはサーバー時にのみ実行されるため、phpの変数に依存してjavascriptを変更する場合、うまく動作しない可能性があります。JavaScriptで制御したいページロード設定がある場合、私は通常、その値をphpでDOMに追加して、javascriptが必要なときに必要に応じてアクセスできるようにします(たとえば、隠されたdiv内)。

最後に、組織的な目的のためだけに、これは非常に迷惑になります。(私の意見では)htmlとphpを混在させるのは十分に悪いです。


1

PHPをconfigデータオブジェクトに含める方法は90%ですが、ベストプラクティスはそれを完全に分離することです。RESTful APIを使用して、必要なデータのみを要求できます。これはもう少しJavaScriptですが、いくつかの利点があります。

  • スクリプトは静的であり、永続的にキャッシュできます
  • PHPはXSSベクトルではなくなりました
  • 懸念の完全な分離

欠点:

  • 追加のHTTPリクエストが必要
  • より複雑なjavascript

脚本

//pure javascript
$.on('domready',function({
    //load the data
    $.get({
       url:'/charts/3D1A2E', 
       success: function(data){
           //now use the chart data here
           ChartModule.init(data);
       }
    });
})

-3

JavaScriptコードの初期化に使用する場合のみ悪い習慣ではありません(WordPressのテーマでは、それを処理する唯一の方法であるため、site_url()のようなphp関数でjavascriptオブジェクトを初期化します(取得するためにajaxリクエストを使用できます) json、など...しかし、それはお尻の痛みです)。

いい練習:

新しいjavascriptObject( "");

悪い習慣:

/ *いくつかのコード* / document.get_element_by_id(); / *コード* /
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.