JavaScript'inizde PHP olması kötü bir uygulama olarak mı kabul edilir?


55

Bu sitede pek çok kez insanların böyle şeyler yapmaya çalıştığını görüyorum:

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

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

  });
</script>

Bunun, insanların doğal olarak içine düştüğü bir kalıp olduğunu sanmıyorum. Dışarıda bunu gösteren bir çeşit öğretici veya öğrenme materyali olmalı, aksi halde çok fazla görmeyiz. Benim sorduğum şu, bununla ilgili çok büyük bir şey mi yapıyorum yoksa bu gerçekten kötü bir uygulama mı?

EDIT: Bir arkadaşımla bu konuyu sık sık JavaScript'ine yakut yapan ve bu konuyu gündeme getiren bir konuştum.

JavaScript'inize uygulama geniş sabitlerini dinamik olarak yerleştirmeniz uygun mudur, böylece iki dosyayı düzenlemek zorunda kalmazsınız. Örneğin...

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

ayrıca bir kütüphanede kullanmayı planladığınız verileri doğrudan kodlamak da sorun değil

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

yoksa her seferinde bir AJAX araması yapmalı mıyız?


4
Bana öyle geliyor ki this question will likely solicit opinion, debate, arguments, polling, or extended discussion....
DaveRandom

7
@ M.Babcock Bu.

8
Dinamik olarak oluşturulmuş JavaScript oluşturan herkes geri alınır ve ele alınır
Raynos

5
@Matt sonra geri alıp onlarla başa
çıkacağım

4
"Javascript'ini PHP'mde aldın!" "Hayır, sizin PHP var benim javascript!"
Josh Darnell

Yanıtlar:


83

Tipik olarak, bir dil Y'ye kodu oluşturmak için dil X'i kullanmak kötü uygulama

Verileri tek arabirimleri haline getirerek iki dili ayırmayı deneyin - kodu karıştırmayın .

Örnekte, cfgJavaScript'i kullanabilen bir yapı oluşturmak için PHP kullanarak kodu geliştirebilirsiniz :

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

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

Bu şekilde, PHP sadece veri yapısını doldurmaya ve JavaScript sadece veri yapısını tüketmeye önem verir.

Bu ayrıştırma ayrıca, verilerin gelecekte senkronize olmayan şekilde (JSON) yüklenmesine de yol açar.

Güncelleme:

Güncellemenizde sorduğunuz ek soruları yanıtlamak için, evet, DRY ilkesini uygulamak ve PHP ve JavaScript'in aynı yapılandırma nesnesini paylaşmasına izin vermek iyi bir uygulama olacaktır:

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

  ...

Yapılandırmanızın JSON temsilini doğrudan bu şekilde sayfanıza yerleştirmenin bir zararı yoktur. XHR yoluyla almak zorunda değilsiniz.


21
Yine de MySQL şifrenizi $ cfg olarak yazmamayı unutmayın!
Thomas Bonini

13
"Verileri tek arabirimleri haline getirmek - kodu karıştırmamak." Bunun gerçekten sorunun özünü kestiğini ve HERHANGİ iki dili bir arada kullanırken iyi bir kural olduğunu düşünüyorum. İçgörü için teşekkürler.
Greg Guida

6
Bu JSON’u data-HTML’nizdeki bir özelliğe de dahil edebilirsiniz. Gibi bir şey <body data-cfg="{...}">.
kapa

1
@bazmegakapa Bunun en iyi seçenek olabileceğini düşünüyorum. Özellikle, HTML DOM gibi API'lerin XSS enjeksiyon riskini büyük ölçüde azaltan kullanımına izin verir.
luiscubal

1
Arabirim olarak verilerin kullanılmasını ve kod üreten kodun cesaret kırılmasını önermek için +1.
Brandon

21

Dinamik olarak oluşturulan JavaScript, korkunç, kötü bir uygulamadır.

Yapmanız gereken şey, Endişelerin Ayrılması ve İlerici Geliştirmenin ne anlama geldiğini kavramaktır.

Bu, temel olarak, dinamik HTML ve statik JavaScript'iniz (HTML'yi geliştirir) anlamına gelir.

Sizin durumunuzda, muhtemelen div'inizde bir sınıf istiyorsunuz ve bunu bir sınıf seçiciyle seçin.


10

Snippet'inizdeki en büyük sorun, #geçerli bir jQuery seçicisi yapmak için eksik olduğunuzdur;).

Mümkün olduğunca JavaScript'inize PHP eklemekten kaçınmanız gerektiğini söyleyebilirim. click()İşleyicinizdeki seçiciyi bir sınıfa değiştirmek ve işleyicinin kovulmasını istiyorsanız ve istemiyorsanız, sınıfı söz konusu öğeye eklemek yanlış;

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

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

  });
</script> 

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

Orada olan JavaScript'inizde PHP eklemeniz gerekir durumlar; ama şunu itiraf etmeliyim ki bunlar çok azdı.

Bir kez örnek, farklı ortamlarınız olduğunda; test, evreleme ve yaşama. Her birinin mal varlığınızın farklı bir yeri var (çoğunlukla görüntüler). Yolu, JavaScript tarafından kullanılabilecek şekilde ayarlamanın en kolay yolu;

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

Hayali php kodumun geri kalanında zaten ekledim #=) ama ciddiyim ki bunun örnek olmanın daha iyi bir yol olduğuna katılıyorum. Bu şekilde yapmak da bana daha doğal geliyor. Öyleyse neden gerekli olmadığı yerlerde bu kadar sık ​​görüyoruz?
Greg Guida

Bir yapılandırma dosyasındaki statik verilerin yankılanması, ortamlarınızın aynı şekilde kurulmasını sağlayarak kolayca önlenebileceğini unutmayın.
Raynos

4
@GregGuida: Tahminimce programcılar nadiren web geliştirmede sizin gibi istemci / sunucu mimarileriyle uğraşmak için kullanılırlar. DB <-> PHP <-> HTML / JS / CSS’yi tek olarak ele alıyorlar ve neyin nereye gitmesi gerektiğini ve katmanların nasıl ayrılması gerektiğini tam olarak anlamıyorlar .
Matt

@Matt Ben muhtemelen bu en iyi açıklama olduğunu düşünüyorum
Greg Guida

2
$divID = '#' . $element_id_value;- seçici patronla sorun yok;)
17'de:

8

Bu benim için kötü bir uygulamadır, çünkü bu dosyayı bir şey olarak çağırmanız gerekecek ve daha sonra örneğin sıkıştıramazsınız, sunucu içeriklerinize JavaScript'inizi karıştırmanın uygun olmadığını söyleyerek. PHP ve JS arasındaki karışımı olabildiğince sınırlamaya çalışın.

Bunun yerine her zaman yapabilirsiniz:

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

Ve sonra bu karıştırma işlevini olabildiğince küçük yapmak için bu işlevi bir php dosyasında çağırabilirsiniz.

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

Bunu yaparak (daha büyük JS dosyalarına sahip, önemli olmadığı durumlarda 2-3 satırı değil), JS dosyasını ve ön uç geliştiricilerini sıkıştırarak (sadece yazabildiğiniz gibi) JavaScript kullanarak çalışmaktan çok rahatlayabilirsiniz. Python, Ruby vb sadece PHP değil - ve orada ne yapmanız gerektiğine bağlı olarak kod daha da büyüyebilirdi).


2
Tamamen katılıyorum, btw Asla PHP benim JS koymak. Sadece her zaman bu sitede görüyorum.
Greg Guida

Php kodu asla tarayıcıya yapmaz! Sadece şimdi düz olması gereken değerlendirilmiş kod javascript. Yani dosya boyutu / sıkıştırma bir sorun değildir. Yine de kötü pratik düşündüm!
James Anderson,

@JamesAnderson Ben alessioalex'in küçültülmeyi kastettiğini düşünüyorum (Uglify gibi). Php komutunun çalıştırılması ve ardından bir işlem sonrası php işlevinin yanıtı ayrıştırması, komut dosyası etiketini tanımlaması, Uglify üzerinden çalıştırması ve orijinal olarak php tarafından oluşturulan JS'yi yanıtı göndermeden önce küçültülmüş sürümü ile değiştirmek mümkün olabilir, ama bunu her istek üzerine yapmak yikes gibi geliyor! yaklaşmak, yanaşmak, yaklaşım.
jinglesthula

6

Bunun kötü bir uygulama olduğunu sanmıyorum. JavaScript'iniz için gereken kimlik dinamikse, bunu yapmanın başka yolu yoktur.


5
Neden cuthulu unholy isminde ID etiketinin adını bilmiyorsun?
Gizli

3
@Incognito, kimliği bilmediğiniz zamanlar vardır ... Yeni kod blokları oluşturmak için ajax kullanıyorsanız, yeni JS ile birlikte benzersiz kimlikler üretiyor olabilirsiniz ... bu durumlarda yapmanız gerekenler başvuruda bulunan ID'lerin js de aynı olduğundan emin olun, sonuçta kod bloğundalar. Bunun gibi daha pek çok örnek var ve ajax işin içine girdiğinde ya da sunucu tarafındaki if-else ifadesine vb. Bağlı büyük kod blokları olduğunda oldukça yaygın.

7
@raynjamin Kendinizi bunun ne yaptığınız durumlara nasıl soktuğunuzu bile anlamadım ... ya da neden sınıfa göre seçtiğinizi, ardından etiketleri listeleyeceğinizi, sonra gizli bir css değerine sahip kimlik özelliklerini ve bu seçici adamı ... aslında bana bakmak acı veriyor ... Nereden başlayacağımı bile bilmiyorum ... gibi ... ne? Devasa kod bloklarını kesip yapıştırıyor musunuz veya birden çok kimlik üzerinde işlem yapması için bir şey mi yapıştırıyorsunuz? Benden bile hoşlanmıyorum. burada patlıyor.
Gizli

3
Git dom / html / neyse hakkında bilgi edinin ... bir arama motoru kullanın ... Neden dinamik HTML ile böyle bir şey yapmak zorunda kalmadım?
Gizli

5
Hayır. ID etiketlerinin nasıl çalıştığını anlamıyorsunuz. Ne dediğini tam olarak anlıyorum.
Gizli

6

Bu kötü uygulamayı düşünürdüm. Betik bloklarının içine dinamik içerik koyarken, bir javascript bağlamından kaçmanın umduğunuz kadar basit olmadığı gerçeğinin farkında olmalısınız. Değerler kullanıcı tarafından sağlanmışsa, html'den kaçış yeterli değildir .

OWASP XSS kısa notları daha fazla ayrıntı vardır, ancak temelde bu desen benimsemeli:

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

Ardından, ana html'nize bağlı ayrı bir .js dosyasında şu kodu yükleyin:

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

Ayrı bir .js dosyası kullanmanın nedeni iki yönlüdür:

  • Önbelleklenebilir, böylece performans daha iyi
  • HTML ayrıştırıcısı tetiklenmez, bu nedenle bir yere hızlı bir <? Php etiketi koyan bir kişi tarafından kaybolan XSS hata riski yoktur.

XSS açısını tam olarak açıklamak için +1! Yaklaşımınız daha hızlı yüklenecektir çünkü json zaten önceden yüklenmiştir, ancak otomatik json ayrıştırmayı kullanmayı $.ajaxveya benzerini tercih ederim
roo2

5

Bazı insanlar bunun kötü bir uygulama olduğunu iddia eder. JS içinde PHP olduğu için değil, satır içi JS olduğundan ve bu yüzden bir sonraki seferde yükleme kolaylığı için tarayıcı tarafından önbelleğe alınmayacağından.

IMO, değişkenleri 2 dil arasında iletmek için JSON kullanmak her zaman daha iyidir, ancak sanırım size kalmış.


5

Genelde bunu yapmadığını söyleyebilirim. Ancak, PHP -> Javascript'ten veri iletmek istiyorsanız, aşağıda gösterilen formun koduna sahip olduğunuz bir satır içi Javascript bloğuna sahip olmak beni çılgına çevirmez. Burada kod sadece php'den javascript'e veri aktarıyor, anında ve benzeri bir mantık yaratmıyor. Bunu bir ajax çağrısı ile yapmanın iyi yanı, verilerin sayfa yüklenir yüklenmez kullanılabilir olması ve sunucuya fazladan bir gezi gerektirmemesidir.

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

Tabii ki başka bir seçenek de, bir .js dosyasına koyacak bir yapı betiği biçimi ile PHP'den bir javascript config dosyası oluşturmaktır.


4

Gerçekten sorunlara yol açabileceğini düşündüğüm tek şey, PHP hatalarının görüntülenmeye ayarlandığı ve böylece PHP hatasını JavaScript'inize gösteren bir HTML yüküdür.

Ayrıca bu nedenle komut dosyasında gösterilmez ve komut dosyanızın neden kırıldığını anlamak zaman alabilir.


bunun büyük bir hataya neden olduğu büyük dava
Greg Guida

3

Kime bağlıdır ve eğer bana sorarsanız, evet, birkaç nedenden dolayı uygulamayı geri alıyorum. Her şeyden önce, php ayrıştırıcısının dokunamayacağı kendi JS dosyasında javascript kodunun olmasını tercih ederim.

İkincisi, php yalnızca sunucu zamanında yürütülür, bu nedenle javascript'inizi değiştirmek için php'deki bazı değişkenlere bağlıysanız, bu işe yaramayabilir. Javascript ile kontrol etmek istediğiniz bazı sayfa yükleme ayarları varsa, genellikle jpascript ile DOM'a eklemeyi tercih ederim, böylece javascript istediği zaman (örneğin gizli bir div'de) istediğinde ulaşabilir.

Son olarak, sadece kurumsal amaçlar için, bu çok can sıkıcı olabilir. Html ve php karıştırmak için yeterince kötü (bence).


1

PHP'yi bir configveri nesnesine dahil etmek yolun% 90'ını geçiyor ancak en iyi uygulama onu tamamen ayırmak. Sadece ihtiyacınız olan verileri istemek için bir RESTful api kullanabilirsiniz, bu biraz daha javascript, ancak birkaç avantajı var.

  • Komut dosyası statiktir ve kalıcı olarak önbelleğe alınabilir
  • PHP artık bir XSS Vektörü değil
  • Eksiksiz endişelerin ayrılması

Downsides:

  • Ekstra bir HTTP isteği gerektirir
  • daha karmaşık javascript

Senaryo

//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

SADECE javascript kodunu başlatmak için kullanılıyorsa, (WordPress temalarımda, javascript nesnelerimi site_url () gibi php işlevleriyle başlatıyorum çünkü bunu ele almanın tek yolu bu (belki bir almak için bir ajax isteği kullanabiliriz) Bir json, ve böylece ... ama kıçından bir acı).

İyi pratik:

yeni javascriptObject ("");

Kötü uygulama:

/ * bazı kodlar * / document.get_element_by_id (); / * bazı kodlar * /
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.