ฉันจะส่งตัวแปรและข้อมูลจาก PHP ไปยัง JavaScript ได้อย่างไร
ฉันมีตัวแปรใน PHP และฉันต้องการค่าของมันในโค้ด JavaScript ของฉัน ฉันจะรับตัวแปรจาก PHP เป็น JavaScript ได้อย่างไร
ฉันมีรหัสที่มีลักษณะดังนี้:
<?php
...
$val = $myService->getValue(); // Makes an API and database call
?>
ฉันมีรหัส JavaScript ที่ต้องการval
และดูตามบรรทัดของ:
<script>
myPlugin.start($val); // I tried this, but it didn't work
<?php myPlugin.start($val); ?> // This didn't work either
myPlugin.start(<?=$val?> // This works sometimes, but sometimes it fails
</script>
คำตอบ
มีหลายวิธีในการทำเช่นนี้ บางคนต้องการค่าใช้จ่ายมากกว่าคนอื่นและบางคนก็ถือว่าดีกว่าคนอื่น ๆ
ไม่เรียงตามลำดับ:
- ใช้ AJAX เพื่อรับข้อมูลที่คุณต้องการจากเซิร์ฟเวอร์
- สะท้อนข้อมูลลงในหน้าเว็บและใช้ JavaScript เพื่อรับข้อมูลจาก DOM
- สะท้อนข้อมูลไปยัง JavaScript โดยตรง
ในโพสต์นี้เราจะตรวจสอบแต่ละวิธีข้างต้นและดูข้อดีข้อเสียของแต่ละวิธีรวมถึงวิธีการนำไปใช้
1. ใช้ AJAX เพื่อรับข้อมูลที่คุณต้องการจากเซิร์ฟเวอร์
วิธีการนี้ถือว่าดีที่สุดเพราะฝั่งเซิร์ฟเวอร์และฝั่งไคลเอ็นต์สคริปต์ของคุณจะแยกจากกันอย่างสมบูรณ์
ข้อดี
- แยกชั้นได้ดีขึ้น - หากพรุ่งนี้คุณหยุดใช้ PHP และต้องการย้ายไปที่ servlet, REST API หรือบริการอื่น ๆ คุณไม่จำเป็นต้องเปลี่ยนโค้ด JavaScript มากนัก
- อ่านได้มากขึ้น - JavaScript คือ JavaScript, PHP คือ PHP คุณจะได้รับโค้ดที่อ่านง่ายขึ้นในทั้งสองภาษาโดยไม่ต้องผสมทั้งสอง
- อนุญาตให้ถ่ายโอนข้อมูลแบบอะซิงโครนัส - การรับข้อมูลจาก PHP อาจใช้เวลา / ทรัพยากรที่มีราคาแพง บางครั้งคุณก็ไม่ต้องการรอข้อมูลโหลดหน้าเว็บและเข้าถึงข้อมูลได้ทุกเมื่อ
- ไม่พบข้อมูลโดยตรงบนมาร์กอัปซึ่งหมายความว่ามาร์กอัปของคุณจะได้รับการดูแลให้สะอาดสำหรับข้อมูลเพิ่มเติมใด ๆ และมีเพียง JavaScript เท่านั้นที่มองเห็น
จุดด้อย
- เวลาแฝง - AJAX สร้างคำขอ HTTP และคำขอ HTTP จะดำเนินการผ่านเครือข่ายและมีเวลาแฝงของเครือข่าย
- สถานะ - ข้อมูลที่ดึงผ่านคำขอ HTTP แยกต่างหากจะไม่รวมข้อมูลใด ๆ จากคำขอ HTTP ที่ดึงเอกสาร HTML คุณอาจต้องใช้ข้อมูลนี้ (เช่นหากเอกสาร HTML ถูกสร้างขึ้นเพื่อตอบสนองต่อการส่งแบบฟอร์ม) และหากคุณต้องการข้อมูลนี้จะต้องโอนย้ายไปด้วย หากคุณตัดไม่ให้ฝังข้อมูลในเพจ (ซึ่งคุณมีหากคุณใช้เทคนิคนี้) จะ จำกัด ให้คุณใช้คุกกี้ / เซสชันซึ่งอาจอยู่ภายใต้เงื่อนไขการแข่งขัน
ตัวอย่างการใช้งาน
ด้วย AJAX คุณต้องมีสองหน้าหนึ่งคือที่ PHP สร้างผลลัพธ์และหน้าที่สองคือที่ที่ JavaScript ได้รับผลลัพธ์นั้น:
รับ data.php
/* Do some operation here, like talk to the database, the file-session
* The world beyond, limbo, the city of shimmers, and Canada.
*
* AJAX generally uses strings, but you can output JSON, HTML and XML as well.
* It all depends on the Content-type header that you send with your AJAX
* request. */
echo json_encode(42); // In the end, you need to echo the result.
// All data should be json_encode()d.
// You can json_encode() any value in PHP, arrays, strings,
//even objects.
index.php (หรืออะไรก็ตามที่มีชื่อเพจจริง)
<!-- snip -->
<script>
function reqListener () {
console.log(this.responseText);
}
var oReq = new XMLHttpRequest(); // New request object
oReq.onload = function() {
// This is where you handle what to do with the response.
// The actual data is found on this.responseText
alert(this.responseText); // Will alert: 42
};
oReq.open("get", "get-data.php", true);
// ^ Don't block the rest of the execution.
// Don't wait until the request finishes to
// continue.
oReq.send();
</script>
<!-- snip -->
การรวมกันของทั้งสองไฟล์ข้างต้นจะแจ้งเตือน42
เมื่อไฟล์เสร็จสิ้นการโหลด
เนื้อหาสำหรับอ่านเพิ่มเติม
- ใช้ XMLHttpRequest - MDN
- การอ้างอิงอ็อบเจ็กต์ XMLHttpRequest - MDN
- ฉันจะตอบกลับการตอบกลับจากการโทรแบบอะซิงโครนัสได้อย่างไร
2. สะท้อนข้อมูลลงในหน้าเว็บและใช้ JavaScript เพื่อรับข้อมูลจาก DOM
วิธีนี้ไม่นิยมใช้กับ AJAX แต่ก็ยังมีข้อดีอยู่ มันยังค่อนข้างแยกระหว่าง PHP และ JavaScript ในแง่ที่ว่าไม่มี PHP โดยตรงใน JavaScript
ข้อดี
- รวดเร็ว - การดำเนินการ DOM มักจะรวดเร็วและคุณสามารถจัดเก็บและเข้าถึงข้อมูลจำนวนมากได้อย่างรวดเร็ว
จุดด้อย
- มาร์กอัปที่ไม่คาดคิดที่อาจเกิดขึ้น - โดยปกติสิ่งที่เกิดขึ้นคือคุณใช้บางประเภทใน
<input type=hidden>
การจัดเก็บข้อมูลเนื่องจากง่ายต่อการดึงข้อมูลออกมาinputNode.value
แต่การทำเช่นนั้นหมายความว่าคุณมีองค์ประกอบที่ไม่มีความหมายใน HTML ของคุณ HTML มี<meta>
องค์ประกอบสำหรับข้อมูลเกี่ยวกับเอกสารและ HTML 5 แนะนำdata-*
แอตทริบิวต์สำหรับข้อมูลเฉพาะสำหรับการอ่านด้วย JavaScript ที่สามารถเชื่อมโยงกับองค์ประกอบเฉพาะได้ - ทำให้แหล่งที่มาไม่สมบูรณ์ - ข้อมูลที่ PHP สร้างขึ้นจะส่งตรงไปยังซอร์ส HTML ซึ่งหมายความว่าคุณจะได้รับแหล่งที่มา HTML ที่ใหญ่กว่าและเน้นน้อยกว่า
- ยากที่จะรับข้อมูลที่มีโครงสร้าง - ข้อมูลที่มีโครงสร้างจะต้องเป็น HTML ที่ถูกต้องมิฉะนั้นคุณจะต้องหลีกเลี่ยงและแปลงสตริงด้วยตัวเอง
- จับคู่ PHP เข้ากับตรรกะข้อมูลของคุณอย่างแน่นหนา - เนื่องจาก PHP ใช้ในการนำเสนอคุณจึงไม่สามารถแยกทั้งสองอย่างออกจากกันได้
ตัวอย่างการใช้งาน
ด้วยวิธีนี้แนวคิดคือการสร้างองค์ประกอบบางประเภทซึ่งจะไม่แสดงให้ผู้ใช้เห็น แต่จะมองเห็นได้กับ JavaScript
index.php
<!-- snip -->
<div id="dom-target" style="display: none;">
<?php
$output = "42"; // Again, do some operation, get the output.
echo htmlspecialchars($output); /* You have to escape because the result
will not be valid HTML otherwise. */
?>
</div>
<script>
var div = document.getElementById("dom-target");
var myData = div.textContent;
</script>
<!-- snip -->
3. สะท้อนข้อมูลโดยตรงไปยัง JavaScript
นี่อาจเป็นเรื่องที่เข้าใจง่ายที่สุด
ข้อดี
- ใช้งานได้ง่ายมาก - ใช้เวลาเพียงเล็กน้อยในการปรับใช้และทำความเข้าใจ
- ไม่ใช่แหล่งที่มาสกปรก - ตัวแปรจะถูกส่งออกไปยัง JavaScript โดยตรงดังนั้น DOM จึงไม่ได้รับผลกระทบ
จุดด้อย
- จับคู่ PHP เข้ากับตรรกะข้อมูลของคุณอย่างแน่นหนา - เนื่องจาก PHP ใช้ในการนำเสนอคุณจึงไม่สามารถแยกทั้งสองอย่างออกจากกันได้
ตัวอย่างการใช้งาน
การนำไปใช้นั้นค่อนข้างตรงไปตรงมา:
<!-- snip -->
<script>
var data = <?php echo json_encode("42", JSON_HEX_TAG); ?>; // Don't forget the extra semicolon!
</script>
<!-- snip -->
โชคดี!
ฉันจะลองคำตอบที่ง่ายกว่านี้:
คำอธิบายของปัญหา
ก่อนอื่นมาทำความเข้าใจกับกระแสของเหตุการณ์เมื่อมีการแสดงเพจจากเซิร์ฟเวอร์ของเรา:
- เรียกใช้ PHP ครั้งแรกจะสร้าง HTML ที่ให้บริการแก่ลูกค้า
- จากนั้น HTML จะถูกส่งไปยังไคลเอนต์หลังจาก PHP เสร็จสิ้นฉันต้องการเน้นย้ำว่าเมื่อโค้ดออกจากเซิร์ฟเวอร์ - PHP เสร็จสิ้นและไม่สามารถเข้าถึงได้อีกต่อไป
- จากนั้น HTML ที่มี JavaScript จะไปถึงไคลเอนต์ซึ่งสามารถเรียกใช้งาน JavaScript บน HTML นั้นได้
ดังนั้นจริงๆสิ่งหลักที่ต้องจำไว้ว่านี่คือHTTP เป็นไร้สัญชาติ เมื่อคำขอออกจากเซิร์ฟเวอร์เซิร์ฟเวอร์จะไม่สามารถสัมผัสได้ ดังนั้นจึงทำให้ตัวเลือกของเราเป็น:
- ส่งคำขอเพิ่มเติมจากไคลเอนต์หลังจากการร้องขอเริ่มต้นเสร็จสิ้น
- เข้ารหัสสิ่งที่เซิร์ฟเวอร์ต้องพูดในคำขอเริ่มต้น
แนวทางแก้ไข
นั่นคือคำถามหลักที่คุณควรถามตัวเองคือ:
ฉันกำลังเขียนเว็บไซต์หรือแอปพลิเคชัน?
เว็บไซต์ส่วนใหญ่อิงตามหน้าเว็บและเวลาในการโหลดหน้าเว็บจะต้องเร็วที่สุด (เช่น - Wikipedia) แอปพลิเคชันบนเว็บมี AJAX หนักกว่าและทำการเดินทางไปกลับจำนวนมากเพื่อรับข้อมูลที่รวดเร็วของลูกค้า (เช่น - แดชบอร์ดหุ้น)
เว็บไซต์
การส่งคำขอเพิ่มเติมจากไคลเอ็นต์หลังจากการร้องขอครั้งแรกเสร็จสิ้นนั้นช้าเนื่องจากต้องใช้คำขอ HTTP เพิ่มเติมซึ่งมีค่าใช้จ่ายที่สำคัญ ยิ่งไปกว่านั้นต้องใช้ความไม่พร้อมกันในการทำคำขอ AJAX ต้องมีตัวจัดการเมื่อเสร็จสมบูรณ์
ฉันไม่แนะนำให้ส่งคำขออื่นเว้นแต่ไซต์ของคุณจะเป็นแอปพลิเคชันสำหรับรับข้อมูลนั้นจากเซิร์ฟเวอร์
คุณต้องการเวลาตอบสนองที่รวดเร็วซึ่งมีผลอย่างมากต่อการแปลงและเวลาในการโหลด การร้องขอ Ajax นั้นช้าสำหรับช่วงเวลาการให้บริการครั้งแรกในกรณีนี้และไม่จำเป็น
คุณมีสองวิธีในการแก้ไขปัญหา
- ตั้งค่าคุกกี้ - คุกกี้คือส่วนหัวที่ส่งในคำขอ HTTP ที่ทั้งเซิร์ฟเวอร์และไคลเอนต์สามารถอ่านได้
- เข้ารหัสตัวแปรเป็น JSON - JSON มีลักษณะใกล้เคียงกับวัตถุ JavaScript มากและออบเจ็กต์ JSON ส่วนใหญ่เป็นตัวแปร JavaScript ที่ถูกต้อง
การตั้งค่าคุกกี้ไม่ใช่เรื่องยากคุณเพียงแค่กำหนดค่า:
setcookie("MyCookie", $value); // Sets the cookie to the value, remember, do not
// Set it with HTTP only to true.
จากนั้นคุณสามารถอ่านด้วย JavaScriptโดยใช้document.cookie
:
นี่คือตัวแยกวิเคราะห์แบบรีดด้วยมือสั้น ๆ แต่คำตอบที่ฉันเชื่อมโยงไปด้านบนนี้มีการทดสอบที่ดีกว่า:
var cookies = document.cookie.split(";").
map(function(el){ return el.split("="); }).
reduce(function(prev,cur){ prev[cur[0]] = cur[1];return prev },{});
cookies["MyCookie"] // Value set with PHP.
คุกกี้เป็นสิ่งที่ดีสำหรับข้อมูลเล็กน้อย นี่คือสิ่งที่บริการติดตามมักทำ
เมื่อเรามีข้อมูลมากขึ้นเราสามารถเข้ารหัสด้วย JSON ภายในตัวแปร JavaScript แทน:
<script>
var myServerData = <?=json_encode($value)?>; // Don't forget to sanitize
//server data
</script>
สมมติว่า$value
จะjson_encode
สามารถในด้าน PHP (มันมักจะเป็น) เทคนิคนี้เป็นสิ่งที่ Stack Overflow ทำกับการแชท (ใช้เฉพาะ. NET แทน PHP)
ใบสมัคร
หากคุณกำลังเขียนแอปพลิเคชัน - ทันใดนั้นเวลาในการโหลดครั้งแรกก็ไม่สำคัญเท่ากับประสิทธิภาพการทำงานที่ต่อเนื่องของแอปพลิเคชันเสมอไปและจะเริ่มจ่ายเพื่อโหลดข้อมูลและโค้ดแยกกัน
คำตอบของฉันที่นี่อธิบายวิธีโหลดข้อมูลโดยใช้ AJAX ใน JavaScript:
function callback(data){
// What do I do with the response?
}
var httpRequest = new XMLHttpRequest;
httpRequest.onreadystatechange = function(){
if (httpRequest.readyState === 4) { // Request is done
if (httpRequest.status === 200) { // successfully
callback(httpRequest.responseText); // We're calling our method
}
}
};
httpRequest.open('GET', "/echo/json");
httpRequest.send();
หรือด้วย jQuery:
$.get("/your/url").done(function(data){
// What do I do with the data?
});
ตอนนี้เซิร์ฟเวอร์จำเป็นต้องมี/your/url
เส้นทาง / ไฟล์ที่มีรหัสที่รับข้อมูลและดำเนินการบางอย่างกับมันในกรณีของคุณ:
<$php
...
$val = myService->getValue(); // Makes an API and database call
echo json_encode($val); // Write it to the output
$>
ด้วยวิธีนี้ไฟล์ JavaScript ของเราจะขอข้อมูลและแสดงข้อมูลแทนที่จะขอโค้ดหรือเลย์เอาต์ สิ่งนี้สะอาดกว่าและเริ่มจ่ายออกเมื่อแอปพลิเคชันสูงขึ้น นอกจากนี้ยังแยกข้อกังวลได้ดีขึ้นและช่วยให้สามารถทดสอบโค้ดฝั่งไคลเอ็นต์ได้โดยไม่ต้องมีเทคโนโลยีฝั่งเซิร์ฟเวอร์ใด ๆ ที่เกี่ยวข้องซึ่งเป็นข้อดีอีกประการหนึ่ง
Postscript:คุณต้องระวังเวกเตอร์โจมตี XSS ให้มากเมื่อคุณฉีดอะไรจาก PHP ไปยัง JavaScript เป็นการยากมากที่จะหลีกเลี่ยงค่าอย่างเหมาะสมและมีความอ่อนไหวตามบริบท หากคุณไม่แน่ใจวิธีการจัดการกับ XSS หรือไม่รู้มัน - โปรดอ่านบทความ OWASP นี้ , คนนี้และคำถามนี้
ฉันมักจะใช้ data- * attributes ใน HTML
<div class="service-container" data-service="<?php echo $myService->getValue(); ?>">
</div>
<script>
$(document).ready(function() {
$('.service-container').each(function() {
var container = $(this);
var service = container.data('service');
// Variable "service" now contains the value of $myService->getValue();
});
});
</script>
ตัวอย่างนี้ใช้ jQuery แต่สามารถปรับใช้กับไลบรารีอื่นหรือวานิลลา JavaScript ได้
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับคุณสมบัติชุดข้อมูลได้ที่นี่: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset
<script>
var jsvar = <?php echo json_encode($PHPVar); ?>;
</script>
json_encode () ต้องการ:
- PHP 5.2.0 ขึ้นไป
$PHPVar
เข้ารหัสเป็น UTF-8, Unicode
เพียงใช้หนึ่งในวิธีต่อไปนี้
<script type="text/javascript">
var js_variable = '<?php echo $php_variable;?>';
<script>
หรือ
<script type="text/javascript">
var js_variable = <?php echo json_encode($php_variable); ?>;
</script>
ฉันค่อนข้างชอบวิธีที่ WordPress ทำงานกับฟังก์ชันenqueueและlocalizeดังนั้นฉันจึงเขียนคลาสง่ายๆสำหรับการใส่สคริปต์ลงในหน้าตามการอ้างอิงของสคริปต์และเพื่อให้มีข้อมูลเพิ่มเติมสำหรับสคริปต์
class mHeader {
private $scripts = array();
/**
* @param string $id Unique script identifier
* @param string $src Script src attribute
* @param array $deps An array of dependencies ( script identifiers ).
* @param array $data An array, data that will be json_encoded and available to the script.
*/
function enqueue_script($id, $src, $deps = array(), $data = array()) {
$this->scripts[$id] = array('src' => $src, 'deps' => $deps, 'data' => $data);
}
private function dependencies($script) {
if ($script['deps']) {
return array_map(array($this, 'dependencies'), array_intersect_key($this->scripts, array_flip($script['deps'])));
}
}
private function _unset($key, &$deps, &$out) {
$out[$key] = $this->scripts[$key];
unset($deps[$key]);
}
private function flattern(&$deps, &$out = array()) {
foreach($deps as $key => $value) {
empty($value) ? $this->_unset($key, $deps, $out) : $this->flattern( $deps[$key], $out);
}
}
function print_scripts() {
if (!$this->scripts)
return;
$deps = array_map(array($this, 'dependencies'), $this->scripts);
while ($deps)
$this->flattern($deps, $js);
foreach($js as $key => $script) {
$script['data'] && printf("<script> var %s = %s; </script>" . PHP_EOL, key($script['data']), json_encode(current( $script['data'])));
echo "<script id=\"$key-js\" src=\"$script[src]\" type=\"text/javascript\"></script>" . PHP_EOL;
}
}
}
การเรียกใช้enqueue_script()
ฟังก์ชันนี้ใช้สำหรับการเพิ่มสคริปต์การตั้งค่าซอร์สและการอ้างอิงกับสคริปต์อื่นและข้อมูลเพิ่มเติมที่จำเป็นสำหรับสคริปต์
$header = new mHeader();
$header->enqueue_script('jquery-ui', '//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js', array('jquery'));
$header->enqueue_script('jquery', '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js');
$header->enqueue_script('custom-script', '//custom-script.min.js', array('jquery-ui'), array('mydata' => array('value' => 20)));
$header->print_scripts();
และprint_scripts()
วิธีการของตัวอย่างข้างต้นจะส่งผลลัพธ์นี้:
<script id="jquery-js" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
<script id="jquery-ui-js" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js" type="text/javascript"></script>
<script> var mydata = {"value":20}; </script>
<script id="custom-script-js" src="//custom-script.min.js" type="text/javascript"></script>
ไม่ว่าความจริงที่ว่าสคริปต์ 'jquery' จะถูกสร้างขึ้นหลังจาก 'jquery-ui' มันจะถูกพิมพ์มาก่อนเนื่องจากถูกกำหนดไว้ใน 'jquery-ui' ซึ่งขึ้นอยู่กับ 'jquery' ข้อมูลเพิ่มเติมสำหรับ 'สคริปต์ที่กำหนดเอง' อยู่ในบล็อกสคริปต์ใหม่และวางอยู่ด้านหน้าของมันประกอบด้วยmydata
ออบเจ็กต์ที่เก็บข้อมูลเพิ่มเติมซึ่งตอนนี้มีให้สำหรับ 'สคริปต์ที่กำหนดเอง'
ลองสิ่งนี้:
<?php
echo "<script> var x = " . json_encode($phpVariable) . "</script>";
?>
-
- หลังจากลองใช้งานได้สักพัก
แม้ว่าจะได้ผล แต่ก็ทำให้ประสิทธิภาพช้าลง เนื่องจาก PHP เป็นสคริปต์ฝั่งเซิร์ฟเวอร์ในขณะที่ JavaScript เป็นฝั่งผู้ใช้
myPlugin.start($val); // Tried this, didn't work
มันใช้งานไม่ได้เพราะ$val
ไม่ได้กำหนดไว้เท่าที่ JavaScript เกี่ยวข้องนั่นคือโค้ด PHP ไม่ได้ส่งออกอะไร$val
เลย ลองดูแหล่งที่มาในเบราว์เซอร์ของคุณและนี่คือสิ่งที่คุณจะเห็น:
myPlugin.start(); // I tried this, and it didn't work
และ
<?php myPlugin.start($val); ?> // This didn't work either
สิ่งนี้ไม่ได้ผลเพราะ PHP จะพยายามถือว่าmyPlugin
เป็นค่าคงที่และเมื่อล้มเหลวก็จะพยายามถือว่าเป็นสตริง'myPlugin'
ซึ่งจะพยายามเชื่อมต่อกับเอาต์พุตของฟังก์ชัน PHP start()
และเนื่องจากไม่ได้กำหนดไว้มันจะทำให้เกิดอันตรายถึงชีวิต ข้อผิดพลาด
และ
myPlugin.start(<?=$val?> // This works sometimes, but sometimes it fails
แม้ว่าจะเป็นไปได้มากที่สุดเนื่องจากโค้ด PHP สร้าง JavaScript ที่ถูกต้องพร้อมกับอาร์กิวเมนต์ที่คาดไว้หากล้มเหลวโอกาสที่จะเป็นเพราะmyPlugin
ยังไม่พร้อม ตรวจสอบลำดับการดำเนินการของคุณ
นอกจากนี้คุณควรทราบว่าเอาต์พุตโค้ด PHP ไม่ปลอดภัยและควรกรองด้วยjson_encode()
.
แก้ไข
เพราะฉันไม่สังเกตเห็นวงเล็บที่หายไปในmyPlugin.start(<?=$val?>
: - \
ดังที่ @Second Rikudo ชี้ให้เห็นเพื่อให้ทำงานได้อย่างถูกต้อง$val
จะต้องมีวงเล็บปิดตัวอย่างเช่น:$val="42);"
หมายความว่า PHP จะผลิตmyPlugin.start(42);
และจะทำงานตามที่คาดไว้เมื่อดำเนินการโดยโค้ด JavaScript
ฉันมีวิธีง่ายๆในการกำหนดตัวแปร JavaScript โดยใช้ PHP
ใช้แอตทริบิวต์ข้อมูล HTML5 เพื่อจัดเก็บตัวแปร PHP จากนั้นกำหนดให้กับ JavaScript ในการโหลดหน้าเว็บ
กวดวิชาสมบูรณ์สามารถพบได้ที่นี่
ตัวอย่าง:
<?php
$variable_1 = "QNimate";
$variable_2 = "QScutter";
?>
<span id="storage" data-variable-one="<?php echo $variable_1; ?>" data-variable-two="<?php echo $variable_2; ?>"></span>
<?php
นี่คือรหัส JavaScript
var variable_1 = undefined;
var variable_2 = undefined;
window.onload = function(){
variable_1 = document.getElementById("storage").getAttribute("data-variable-one");
variable_2 = document.getElementById("storage").getAttribute("data-variable-two");
}
- แปลงข้อมูลเป็นJSON
- เรียกAJAXเพื่อรับไฟล์JSON
- แปลงJSONเป็นวัตถุJavascript
ตัวอย่าง:
ขั้นตอนที่ 1
<?php
$servername = "localhost";
$username = "";
$password = "";
$dbname = "";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT id, name, image FROM phone";
$result = $conn->query($sql);
while($row = $result->fetch_assoc()){
$v[] = $row;
}
echo json_encode($v);
$conn->close();
?>
ขั้นตอนที่ 2
function showUser(fnc) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// STEP 3
var p = JSON.parse(this.responseText);
}
}
}
นี่คือสิ่งที่ฉันไม่เห็นโพสต์เป็นตัวเลือก จะคล้ายกับการใช้ Ajax แต่แตกต่างกันอย่างชัดเจน
ขั้นแรกตั้งค่าซอร์สของสคริปต์ไปยังไฟล์ PHP โดยตรง
<script type="text/javascript" src="url_to_your_php_file.php" /></script>
คุณสามารถส่งตัวแปรกลับไปยังไฟล์ PHP ได้เช่นตัวอย่างนี้:
<script type="text/javascript" src="url_to_your_php_file.php?var1=value1" /></script>
จากนั้นใน "your_php_file.php":
<?php
// THIS IS A SIMPLE EXAMPLE
// it demonstrates one method of using the src attribute to link
// to a PHP file which can generate JavaScript code dynamically
// and share data between PHP and JavaScript
// you may take this learning example and develop it further
// relying on your own coding skills for validating data
// and avoiding errors, of course
header('content-type: text/javascript');
// If you pass a $_GET variable from the JavaScript
// you should add code to validate your $_GET variable(s)
// You can add code to query a database
// using $_GET['var1'] or some other criteria
// You can add simple variable assignments
$value = 'some value';
// For the OP's needs (assumes the class object has been defined)
$val = $myService->getValue();
?>
function name() {
// Pay attention because you need to use quotes properly
// and account for possible quotes in the variable strings
// to avoid both PHP and JavaScript errors
// example assumes $val has been returned as a string
// validate $val as needed using your method of choice
var example1 = <?php echo '"' . $val . '"'; ?>;
var example2 = <?php echo '"' . $value . '"'; ?>;
var example3 = <?php echo '"some other data"'; ?>;
alert( example1 + ' / ' + example2 );
}
<?php
// You may even want to include additional files (.php or .js, etc.)
@include 'local_path_to_some_other_js_file.js';
@include 'local_path_to_some_other_php_file.php';
exit;
?>
นี่คือเคล็ดลับ:
นี่คือ'PHP'ของคุณที่จะใช้ตัวแปรนั้น:
<?php $name = 'PHP variable'; echo '<script>'; echo 'var name = ' . json_encode($name) . ';'; echo '</script>'; ?>
ตอนนี้คุณมีตัวแปร JavaScript ที่เรียกว่า
'name'
และนี่คือรหัส JavaScript ของคุณที่จะใช้ตัวแปรนั้น:<script> console.log("I am everywhere " + name); </script>
สมมติว่าตัวแปรของคุณเป็นจำนวนเต็มเสมอ ในกรณีนี้จะง่ายกว่า:
<?PHP
$number = 4;
echo '<script>';
echo 'var number = ' . $number . ';';
echo 'alert(number);';
echo '</script>';
?>
เอาท์พุต :
<script>var number = 4;alert(number);</script>
สมมติว่าตัวแปรของคุณไม่ใช่จำนวนเต็ม แต่ถ้าคุณลองใช้วิธีการข้างต้นคุณจะได้สิ่งนี้:
<script>var number = abcd;alert(number);</script>
แต่ใน JavaScript นี่เป็นข้อผิดพลาดทางไวยากรณ์
ดังนั้นใน PHP เราจึงมีการเรียกใช้ฟังก์ชันjson_encode
ที่เข้ารหัสสตริงเป็นออบเจ็กต์ JSON
<?PHP
$number = 'abcd';
echo '<script>';
echo 'var number = ' . json_encode($number) . ';';
echo 'alert(number);';
echo '</script>';
?>
เนื่องจากabcd
ใน JSON มี"abcd"
ลักษณะดังนี้:
<script>var number = "abcd";alert(number);</script>
คุณสามารถใช้วิธีการเดียวกันสำหรับอาร์เรย์:
<?PHP
$details = [
'name' => 'supun',
'age' => 456,
'weight' => '55'
];
echo '<script>';
echo 'var details = ' . json_encode($details) . ';';
echo 'alert(details);';
echo 'console.log(details);';
echo '</script>';
?>
และโค้ด JavaScript ของคุณมีลักษณะดังนี้:
<script>var details = {"name":"supun","age":456,"weight":"55"};alert(details);console.log(details);</script>
เอาต์พุตคอนโซล
หลังจากการค้นคว้ามากมายฉันพบวิธีที่ง่ายที่สุดคือการส่งผ่านตัวแปรทุกชนิดอย่างง่ายดาย
ในสคริปต์เซิร์ฟเวอร์คุณมีสองตัวแปรและคุณกำลังพยายามส่งไปยังสคริปต์ไคลเอ็นต์:
$php_var1 ="Hello world";
$php_var2 ="Helloow";
echo '<script>';
echo 'var js_variable1= ' . json_encode($php_var1) . ';';
echo 'var js_variable2= ' . json_encode($php_var2) . ';';
echo '</script>';
ในโค้ด JavaScript ของคุณที่เรียกบนหน้าเว็บให้เรียกตัวแปรเหล่านั้น
ฉันจะถือว่าข้อมูลที่จะส่งเป็นสตริง
ตามที่ผู้แสดงความคิดเห็นรายอื่นกล่าวไว้ AJAX เป็นวิธีแก้ปัญหาที่เป็นไปได้วิธีหนึ่ง แต่ข้อเสียมีมากกว่าข้อดี: มีเวลาแฝงและโปรแกรมยากกว่า (ต้องใช้รหัสเพื่อดึงค่าทั้งฝั่งเซิร์ฟเวอร์และฝั่งไคลเอ็นต์) เมื่อง่ายกว่า ฟังก์ชัน Escape ควรเพียงพอ
ดังนั้นเรากลับไปที่การหลบหนี json_encode($string)
ใช้งานได้ถ้าคุณเข้ารหัสสตริงต้นทางเป็น UTF-8 ก่อนในกรณีที่ยังไม่มีเนื่องจากjson_encode
ต้องใช้ข้อมูล UTF-8 หากสตริงอยู่ใน ISO-8859-1 คุณสามารถใช้json_encode(utf8_encode($string))
; มิฉะนั้นคุณสามารถใช้iconv
เพื่อทำการแปลงก่อนได้เสมอ
แต่มี gotcha ขนาดใหญ่ หากคุณใช้ในเหตุการณ์คุณต้องเรียกใช้htmlspecialchars()
ผลลัพธ์เพื่อให้รหัสถูกต้อง จากนั้นคุณจะต้องระมัดระวังในการใช้เครื่องหมายคำพูดคู่เพื่อปิดเหตุการณ์หรือเพิ่มลงENT_QUOTES
ใน htmlspecialchars เสมอ ตัวอย่างเช่น:
<?php
$myvar = "I'm in \"UTF-8\" encoding and I have <script>script tags</script> & ampersand!";
// Fails:
//echo '<body onload="alert(', json_encode($myvar), ');">';
// Fails:
//echo "<body onload='alert(", json_encode($myvar), ");'>";
// Fails:
//echo "<body onload='alert(", htmlspecialchars(json_encode($myvar)), ");'>";
// Works:
//echo "<body onload='alert(", htmlspecialchars(json_encode($myvar), ENT_QUOTES), ");'>";
// Works:
echo '<body onload="alert(', htmlspecialchars(json_encode($myvar)), ');">';
echo "</body>";
อย่างไรก็ตามคุณไม่สามารถใช้htmlspecialchars
กับโค้ด JavaScript ปกติ (โค้ดที่อยู่ในแท็ก<script>
... </script>
) ทำให้การใช้ฟังก์ชันนี้มีแนวโน้มที่จะผิดพลาดโดยลืมhtmlspecialchars
ผลลัพธ์เมื่อเขียนโค้ดเหตุการณ์
เป็นไปได้ที่จะเขียนฟังก์ชันที่ไม่มีปัญหานั้นและสามารถใช้ได้ทั้งในเหตุการณ์และในโค้ด JavaScript ปกติตราบใดที่คุณใส่เหตุการณ์ของคุณไว้ในเครื่องหมายคำพูดเดียวหรือเสมอในเครื่องหมายคำพูดคู่ นี่คือข้อเสนอของฉันที่กำหนดให้พวกเขาอยู่ในเครื่องหมายคำพูดคู่ (ซึ่งฉันชอบ):
<?php
// Optionally pass the encoding of the source string, if not UTF-8
function escapeJSString($string, $encoding = 'UTF-8')
{
if ($encoding != 'UTF-8')
$string = iconv($encoding, 'UTF-8', $string);
$flags = JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_UNESCAPED_SLASHES;
$string = substr(json_encode($string, $flags), 1, -1);
return "'$string'";
}
ฟังก์ชันนี้ต้องใช้ PHP 5.4+ ตัวอย่างการใช้งาน:
<?php
$myvar = "I'm in \"UTF-8\" encoding and I have <script>script tags</script> & ampersand!";
// Note use of double quotes to enclose the event definition!
echo '<body onload="alert(', escapeJSString($myvar), ');">';
// Example with regular code:
echo '<script>alert(', escapeJSString($myvar), ');</script>';
echo '</body>';
ตามรหัสของคุณ
<$php
$val = $myService->getValue(); // Makes an API and database call
echo '<span id="value">'.$val.'</span>';
$>
ตอนนี้คุณสามารถรับค่าโดยใช้ DOM ใช้ innerHTML ของ span id ในกรณีนี้คุณไม่จำเป็นต้องโทรไปยังเซิร์ฟเวอร์หรือ Ajax หรืออย่างอื่น
หน้าของคุณจะพิมพ์โดยใช้ PHP และ JavaScript ของคุณจะได้รับค่าโดยใช้ DOM
<?php
$val = $myService->getValue(); // Makes an API and database call
echo "
<script>
myPlugin.start({$val});
</script> ";
?>