Làm cách nào để chuyển các biến và dữ liệu từ PHP sang JavaScript?


664

Tôi có một biến trong PHP và tôi cần giá trị của nó trong mã JavaScript của mình. Làm cách nào tôi có thể nhận được biến của mình từ PHP sang JavaScript?

Tôi có mã trông như thế này:

<?php
     ...
     $val = $myService->getValue(); // Makes an API and database call
?>

Tôi có mã JavaScript cần valvà xem dọc theo dòng:

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

2
Là dấu ngoặc đơn đóng thiếu trong myPlugin.start(<?=$val?>cố ý? Có đúng là "điều này đôi khi hoạt động"?
andrew

2
Chà, cái này thực ra là của Ben, nhưng hãy nói rằng nếu $ val thì "42)"nó sẽ hoạt động tốt: D
Madara's Ghost

Câu trả lời:


877

Thực tế có một số cách tiếp cận để làm điều này. Một số yêu cầu nhiều chi phí hơn những người khác, và một số được coi là tốt hơn so với những người khác.

Không theo thứ tự đặc biệt:

  1. Sử dụng AJAX để lấy dữ liệu bạn cần từ máy chủ.
  2. Echo dữ liệu vào trang ở đâu đó và sử dụng JavaScript để lấy thông tin từ DOM.
  3. Echo dữ liệu trực tiếp vào JavaScript.

Trong bài đăng này, chúng tôi sẽ kiểm tra từng phương pháp trên và xem ưu và nhược điểm của từng phương pháp, cũng như cách triển khai chúng.

1. Sử dụng AJAX để lấy dữ liệu bạn cần từ máy chủ

Phương pháp này được coi là tốt nhất, bởi vì các kịch bản phía máy chủ và phía máy khách của bạn hoàn toàn tách biệt .

Ưu

  • Phân tách tốt hơn giữa các lớp - Nếu ngày mai bạn ngừng sử dụng PHP và muốn chuyển sang một servlet, API REST hoặc một số dịch vụ khác, bạn không phải thay đổi nhiều mã JavaScript.
  • Dễ đọc hơn - JavaScript là JavaScript, PHP là PHP. Không trộn lẫn cả hai, bạn sẽ có được mã dễ đọc hơn trên cả hai ngôn ngữ.
  • Cho phép truyền dữ liệu không đồng bộ - Lấy thông tin từ PHP có thể tốn thời gian / tài nguyên. Đôi khi bạn không muốn đợi thông tin, tải trang và tiếp cận thông tin bất cứ khi nào.
  • Dữ liệu không được tìm thấy trực tiếp trên đánh dấu - Điều này có nghĩa là đánh dấu của bạn được giữ sạch mọi dữ liệu bổ sung và chỉ JavaScript nhìn thấy nó.

Nhược điểm

  • Độ trễ - AJAX tạo một yêu cầu HTTP và các yêu cầu HTTP được truyền qua mạng và có độ trễ mạng.
  • Trạng thái - Dữ liệu được tìm nạp thông qua một yêu cầu HTTP riêng sẽ không bao gồm bất kỳ thông tin nào từ yêu cầu HTTP đã tìm nạp tài liệu HTML. Bạn có thể cần thông tin này (ví dụ: nếu tài liệu HTML được tạo để đáp ứng với việc gửi biểu mẫu) và, nếu bạn làm như vậy, sẽ phải chuyển nó qua một cách nào đó. Nếu bạn đã loại trừ việc nhúng dữ liệu vào trang (mà bạn có nếu bạn đang sử dụng kỹ thuật này) thì điều đó giới hạn bạn với cookie / phiên có thể phải tuân theo các điều kiện cuộc đua.

Ví dụ thực hiện

Với AJAX, bạn cần hai trang, một trang là nơi PHP tạo đầu ra và trang thứ hai là nơi JavaScript có đầu ra đó:

lấy dữ liệu.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 (hoặc bất cứ điều gì trang thực tế được đặt tên như)

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

Sự kết hợp ở trên của hai tệp sẽ cảnh báo 42khi tải xong.

Một số tài liệu đọc thêm

2. Echo dữ liệu vào trang ở đâu đó và sử dụng JavaScript để lấy thông tin từ DOM

Phương pháp này ít được ưa thích hơn AJAX, nhưng nó vẫn có những ưu điểm. Nó vẫn tương đối tách biệt giữa PHP và JavaScript theo nghĩa là không có PHP trực tiếp trong JavaScript.

Ưu

  • Nhanh - Các thao tác DOM thường nhanh chóng và bạn có thể lưu trữ và truy cập nhiều dữ liệu tương đối nhanh chóng.

Nhược điểm

  • Đánh dấu tiềm năng không phổ biến - Thông thường, điều xảy ra là bạn sử dụng một số loại <input type=hidden>để lưu trữ thông tin, bởi vì việc lấy thông tin ra dễ dàng hơn inputNode.value, nhưng làm như vậy có nghĩa là bạn có một yếu tố vô nghĩa trong HTML. HTML có <meta>yếu tố dữ liệu về tài liệu và HTML 5 giới thiệu data-*các thuộc tính cho dữ liệu cụ thể để đọc bằng JavaScript có thể được liên kết với các yếu tố cụ thể.
  • Chỉ thị nguồn - Dữ liệu mà PHP tạo ra được xuất trực tiếp vào nguồn HTML, nghĩa là bạn có được nguồn HTML lớn hơn và ít tập trung hơn.
  • Khó lấy dữ liệu có cấu trúc hơn - Dữ liệu có cấu trúc sẽ phải là HTML hợp lệ, nếu không, bạn sẽ phải tự thoát và chuyển đổi chuỗi.
  • Kết hợp chặt chẽ PHP với logic dữ liệu của bạn - Vì PHP được sử dụng trong bản trình bày, bạn không thể tách rời hai thứ này một cách sạch sẽ.

Ví dụ thực hiện

Với điều này, ý tưởng là tạo ra một số loại phần tử sẽ không được hiển thị cho người dùng, nhưng hiển thị với 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. Echo dữ liệu trực tiếp đến JavaScript

Đây có lẽ là dễ hiểu nhất.

Ưu

  • Rất dễ thực hiện - Mất rất ít để thực hiện điều này và hiểu.
  • Nguồn không bẩn - Các biến được xuất trực tiếp sang JavaScript, vì vậy DOM không bị ảnh hưởng.

Nhược điểm

  • Kết hợp chặt chẽ PHP với logic dữ liệu của bạn - Vì PHP được sử dụng trong bản trình bày, bạn không thể tách rời hai thứ này một cách sạch sẽ.

Ví dụ thực hiện

Việc thực hiện tương đối đơn giản:

<!-- snip -->
<script>
    var data = <?php echo json_encode("42", JSON_HEX_TAG); ?>; // Don't forget the extra semicolon!
</script>
<!-- snip -->

Chúc may mắn!


70
"PHP không có các hàm thoát JavaScript tầm thường" - Điều gì sai với json_encode?
Quentin

34
Tôi không đồng ý với "Rất không an toàn !!" và "Dữ liệu có cấu trúc là khó". Mã hóa dữ liệu dưới dạng JSON ( ký hiệu đối tượng JavaScript , sau tất cả), và bạn sẽ đến đó!
el.pescado

14
Điều gì về tính không đồng bộ về chi phí và độ phức tạp mã đáng kể giới thiệu khi thực hiện một yêu cầu AJAX? Khi làm việc trên một trang web ánh sáng JavaScript - thực hiện một yêu cầu AJAX là tẻ nhạt và không phải là thực tiễn tốt nhất.
Benjamin Gruenbaum

8
@BenjaminGruenbaum - JS là JSON không hợp lệ là không liên quan. Tôi không thể nghĩ về bất kỳ JSON nào không hợp lệ trong JavaScript ở phía bên phải của một bài tập.
Quentin

7
@SecondRikudo Trong phương pháp 3, ví dụ đó có thể giết chết trang web. Ví dụ : <?php $output = '<!--<script>'; echo json_encode($output); ?>. Xem câu hỏi này để biết chi tiết. Giải pháp: Sử dụng JSON_HEX_TAGđể thoát <>(yêu cầu PHP 5.3.0).
Pang

90

Tôi sẽ thử một câu trả lời đơn giản hơn:

Giải thích vấn đề

Trước tiên, hãy hiểu luồng sự kiện khi một trang được phục vụ từ máy chủ của chúng tôi:

  • PHP đầu tiên được chạy, nó tạo ra HTML được phục vụ cho máy khách.
  • Sau đó, HTML được gửi đến máy khách, sau khi PHP được thực hiện với nó, tôi muốn nhấn mạnh rằng một khi mã rời khỏi máy chủ - PHP được thực hiện với nó và không thể truy cập được nữa.
  • Sau đó, HTML với JavaScript đến máy khách, có thể thực thi JavaScript trên HTML đó.

Vì vậy, thực sự, điều cốt lõi cần nhớ ở đây là HTTP là không trạng thái . Khi một yêu cầu rời khỏi máy chủ, máy chủ không thể chạm vào nó. Vì vậy, đó là lựa chọn của chúng tôi để:

  1. Gửi thêm yêu cầu từ khách hàng sau khi yêu cầu ban đầu được thực hiện.
  2. Mã hóa những gì máy chủ đã nói trong yêu cầu ban đầu.

Các giải pháp

Đó là câu hỏi cốt lõi bạn nên tự hỏi mình là:

Tôi đang viết một trang web hoặc một ứng dụng?

Trang web chủ yếu dựa trên trang và thời gian tải trang cần phải nhanh nhất có thể (ví dụ: Wikipedia). Các ứng dụng web nặng hơn AJAX và thực hiện nhiều chuyến đi khứ hồi để có được thông tin nhanh về máy khách (ví dụ: bảng điều khiển chứng khoán).

Trang mạng

Gửi thêm yêu cầu từ khách hàng sau khi yêu cầu ban đầu được thực hiện rất chậm vì nó yêu cầu nhiều yêu cầu HTTP hơn có chi phí đáng kể. Hơn nữa, nó đòi hỏi sự không đồng bộ khi thực hiện một yêu cầu AJAX yêu cầu xử lý khi hoàn thành.

Tôi không khuyên bạn nên thực hiện một yêu cầu khác trừ khi trang web của bạn là một ứng dụng để nhận thông tin đó từ máy chủ.

Bạn muốn thời gian phản hồi nhanh có ảnh hưởng lớn đến thời gian chuyển đổi và tải. Thực hiện các yêu cầu Ajax là chậm cho thời gian hoạt động ban đầu trong trường hợp này và không cần thiết.

Bạn có hai cách để giải quyết vấn đề

  • Đặt cookie - cookie là các tiêu đề được gửi trong các yêu cầu HTTP mà cả máy chủ và máy khách đều có thể đọc được.
  • Mã hóa biến là JSON - JSON trông rất gần với các đối tượng JavaScript và hầu hết các đối tượng JSON là các biến JavaScript hợp lệ.

Đặt cookie thực sự không khó lắm, bạn chỉ cần gán cho nó một giá trị:

setcookie("MyCookie", $value); // Sets the cookie to the value, remember, do not
                               // Set it with HTTP only to true.

Sau đó, bạn có thể đọc nó bằng JavaScript bằng cách sử dụng document.cookie:

Đây là một trình phân tích cú pháp cuộn tay ngắn, nhưng câu trả lời tôi liên kết ở bên trên này đã được thử nghiệm tốt hơn:

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.

Cookies là tốt cho một ít dữ liệu. Đây là những gì dịch vụ theo dõi thường làm.

Khi chúng tôi có nhiều dữ liệu hơn, chúng tôi có thể mã hóa nó bằng JSON bên trong một biến JavaScript:

<script>
    var myServerData = <?=json_encode($value)?>; // Don't forget to sanitize
                                                 //server data
</script>

Giả sử $valuejson_encodecó thể ở bên PHP (nó thường là). Kỹ thuật này là những gì Stack Overflow thực hiện với trò chuyện của nó chẳng hạn (chỉ sử dụng .NET thay vì PHP).

Ứng dụng

Nếu bạn đang viết một ứng dụng - đột nhiên thời gian tải ban đầu không phải lúc nào cũng quan trọng như hiệu suất liên tục của ứng dụng và nó bắt đầu trả hết để tải dữ liệu và mã riêng biệt.

Câu trả lời của tôi ở đây giải thích cách tải dữ liệu bằng AJAX trong 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();

Hoặc với jQuery:

$.get("/your/url").done(function(data){
    // What do I do with the data?
});

Bây giờ, máy chủ chỉ cần chứa một /your/urltuyến / tệp chứa mã lấy dữ liệu và thực hiện một cái gì đó với nó, trong trường hợp của bạn:

<$php
     ...
     $val = myService->getValue(); // Makes an API and database call
     echo json_encode($val); // Write it to the output
 $>

Bằng cách này, tệp JavaScript của chúng tôi yêu cầu dữ liệu và hiển thị nó thay vì yêu cầu mã hoặc bố cục. Điều này là sạch hơn và bắt đầu trả hết khi ứng dụng cao hơn. Nó cũng phân tách mối quan tâm tốt hơn và nó cho phép kiểm tra mã phía máy khách mà không có bất kỳ công nghệ phía máy chủ nào liên quan, đó là một điểm cộng khác.

Postcript: Bạn phải rất chú ý đến các vectơ tấn công XSS khi bạn tiêm bất cứ thứ gì từ PHP sang JavaScript. Đó là rất khó khăn để thoát khỏi các giá trị đúng và đó là bối cảnh nhạy cảm. Nếu bạn không chắc chắn làm thế nào để đối phó với XSS, hoặc không biết về nó - vui lòng đọc bài viết OWASP này , bài viết nàycâu hỏi này .


4
@cHao nói chung hơn - mã hóa được định nghĩa là một chuỗi các ký tự và sự tồn tại của các đối tượng khái niệm là một triết lý. Tuy nhiên, có những thứ như các đối tượng JSON và chúng được định nghĩa bởi ngữ pháp JSON. {}là một đối tượng JSON hợp lệ - xem json.org
Benjamin Gruenbaum

1
Tuy nhiên, nếu bạn đang sử dụng định nghĩa đó, thì tất cả "các đối tượng JSON" đều hợp lệ trong JS.
cHao

1
@cHao lưu ý sự tinh tế: JavaScript có khái niệm về đối tượng và JSON có khái niệm về đối tượng - chúng không giống nhau. Khi mọi người sử dụng sai thuật ngữ "đối tượng JSON", họ có nghĩa là một đối tượng JS, trong vùng đất JavaScript - JSON được sử dụng làm định dạng tuần tự hóa dữ liệu và các đối tượng JSON xuất hiện bên trong các chuỗi (giống như các truy vấn SQL trong ngôn ngữ phía máy chủ). Tuy nhiên, trong câu trả lời này, phương thức JSON dựa trên thực tế là hầu hết các đối tượng JSON cũng là đối tượng JavaScript hợp lệ nên chúng tôi viết một đối tượng JSON vào mã JavaScript.
Benjamin Gruenbaum

1
@cHao À, nhưng tôi đã thấy trước khoảnh khắc này ngày hôm qua :) stackoverflow.com/questions/23752156/
Benjamin Gruenbaum

2
OK, bạn đã đưa tôi đến đó. :) Tuy nhiên, nó vẫn an toàn; Hành vi mặc định của PHP là thoát khỏi các ký tự như vậy (cùng với các ký tự không phải ASCII khác), vì vậy chúng không bao giờ đi vào đầu ra ngoại trừ, \u2028v.v. Bạn phải nói rõ rằng không được làm điều đó.
cHao

85

Tôi thường sử dụng các thuộc tính data- * trong 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>

Ví dụ này sử dụng jQuery, nhưng nó có thể được điều chỉnh cho một thư viện hoặc JavaScript vanilla khác.

Bạn có thể đọc thêm về thuộc tính bộ dữ liệu tại đây: https://developer.mozilla.org/en-US/docs/Web/API/HTMLEuity.dataset


4
Tôi đồng ý, không muốn phân tích quá mức và thực hiện một giải pháp ưa thích cho một vấn đề đơn giản. Phương pháp này tách PHP khỏi Javascript, do đó PHP vẫn chỉ tạo HTML, trong khi Javascript có thể nằm ngoài tệp PHP.
alds

2
Tôi đồng ý đây là lựa chọn tốt nhất. Nó giải quyết tất cả các vấn đề bảo mật, không có độ trễ. Bạn có thể giữ hoàn toàn JS khỏi các trang HTML của bạn. HTML cần được phục vụ bởi máy chủ ứng dụng, nhưng JS (và CSS) thì không. Nó cũng có nhiều ngữ nghĩa hơn.
Ryan

1
@Quentin Bạn nên thoát TẤT CẢ đầu ra, trừ khi đầu ra là chính HTML.
yuikonnu

2
@asdasd - Vâng, tôi chỉ giải quyết vấn đề cụ thể với mã trong câu trả lời của bạn chứ không phải là trường hợp chung.
Quentin

1
@kanji - không có thực hành tốt nhất; divlà tốt, nhưng bạn có thể sử dụng bất kỳ thẻ nào bạn thích; phải được trong bodymặc dù.
Timm

38
<script>
  var jsvar = <?php echo json_encode($PHPVar); ?>;
</script>

json_encode () yêu cầu:

  • PHP 5.2.0 trở lên
  • $PHPVar được mã hóa dưới dạng UTF-8, Unicode.

19

Đơn giản chỉ cần sử dụng một trong các phương pháp sau.

<script type="text/javascript">
var js_variable  = '<?php echo $php_variable;?>';
<script>

HOẶC LÀ

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

4
Giá trị nào thêm vào câu trả lời hiện có?
Benjamin Gruenbaum

5
Giữ cho nó đơn giản và thẳng. Đối với tất cả người dùng có nhiều thời gian để tìm hiểu sâu về giải thích
Nishant Mendiratta

1
Đơn giản là tốt hơn
Doberon

Có thể đây là một câu hỏi ngớ ngẩn, nhưng tôi hoàn toàn mới đối với thế giới PHP. Khi chúng tôi viết mã ở trên vào tệp .php, làm cách nào để truy cập "js_variable" trong tệp JavaScript của tôi hoặc tệp "index.html" của tôi?
Ankit Prajapati

@AnkitPrajapati Hãy thử truy cập nó bằng cách kiểm tra trạng thái sẵn sàng của tài liệu. Sử dụng kịch bản sau đây. document.onreadystatechange = () => { if (document.readyState === 'complete') { // document ready alert(js_variable) } };
Nishant Mendiratta

11

Tôi khá thích cách WordPress hoạt động với các chức năng enqueuebản địa hóa của nó, vì vậy theo mô hình đó, tôi đã viết một lớp đơn giản để đưa tập lệnh vào trang theo các phụ thuộc của tập lệnh và để cung cấp thêm dữ liệu cho tập lệnh.

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;
        }
    }
}

Cuộc gọi đến enqueue_script()chức năng là để thêm tập lệnh, đặt nguồn và phụ thuộc vào tập lệnh khác và dữ liệu bổ sung cần thiết cho tập lệnh.

$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();

Và, print_scripts()phương thức của ví dụ trên sẽ gửi đầu ra này:

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

Bất kể thực tế là kịch bản 'jquery' bị mê hoặc sau 'jquery-ui', nó được in trước bởi vì nó được định nghĩa trong 'jquery-ui' rằng nó phụ thuộc vào 'jquery'. Dữ liệu bổ sung cho 'tập lệnh tùy chỉnh' nằm trong một khối tập lệnh mới và được đặt trước tập lệnh, nó chứa mydatađối tượng chứa dữ liệu bổ sung, hiện có sẵn cho 'tập lệnh tùy chỉnh'.


10

Thử cái này:

<?php
    echo "<script> var x = " . json_encode($phpVariable) . "</script>";
?>

-

-Sau khi thử điều này một lúc

Mặc dù nó hoạt động, tuy nhiên nó làm chậm hiệu suất. Vì PHP là tập lệnh phía máy chủ trong khi JavaScript là phía người dùng.


4
Chúng tôi đang tìm kiếm câu trả lời dài cung cấp một số giải thích và bối cảnh. Đừng chỉ đưa ra một câu trả lời một dòng; giải thích tại sao câu trả lời của bạn là đúng, lý tưởng với trích dẫn. Câu trả lời không bao gồm giải thích có thể được gỡ bỏ. Điều này được viết trên câu hỏi.
Madara's Ghost

3
không có gì nhiều để giải thích hãy ghi lại biến php của bạn trong <thẻ script> được lặp lại bằng mã php
Yosra Nagati

5
Bạn có chắc không? Bạn đã thấy câu trả lời hàng đầu cho câu hỏi này? Nó giải thích khá nhiều. Chưa kể rằng giải pháp của bạn không an toàn. $phpVariable = '42"; alert("I am evil!");';
Madara's Ghost

9
đây là gợi ý của tôi đã giải quyết vấn đề của tôi và tôi không tìm thấy nó trong các câu trả lời trước nên tôi đã thêm vào, với hy vọng ai đó thấy nó thú vị
Yosra Nagati

1
Là tiếng vang được thêm vào đây để in nó trên trang web có mã php này trong đó hay nó chỉ là một phần của cú pháp để đưa dữ liệu vào biến js. @ YosraNagati
SUMIT KUMAR SINGH

8
myPlugin.start($val); // Tried this, didn't work

Nó không hoạt động vì $valkhông được xác định khi có liên quan đến JavaScript, tức là mã PHP không xuất ra bất cứ thứ gì cho $val. Hãy thử xem nguồn trong trình duyệt của bạn và đây là những gì bạn sẽ thấy:

myPlugin.start(); // I tried this, and it didn't work

<?php myPlugin.start($val); ?> // This didn't work either

Điều này không hoạt động vì PHP sẽ cố coi myPluginlà hằng số và khi thất bại, nó sẽ cố coi nó là chuỗi 'myPlugin'mà nó sẽ cố nối với đầu ra của hàm PHP start()và vì không xác định được nên nó sẽ tạo ra một lỗi nghiêm trọng lỗi.

 myPlugin.start(<?=$val?> // This works sometimes, but sometimes it fails

Mặc dù điều này rất có thể hoạt động, vì mã PHP đang tạo JavaScript hợp lệ với các đối số dự kiến, nếu thất bại, rất có thể là do myPluginchưa sẵn sàng. Kiểm tra thứ tự thực hiện của bạn.

Ngoài ra, bạn nên lưu ý rằng đầu ra mã PHP không an toàn và nên được lọc bằng json_encode().

BIÊN TẬP

Bởi vì tôi đã không nhận thấy dấu ngoặc đơn bị thiếu trong myPlugin.start(<?=$val?>: - \

Như @Second Rikudo chỉ ra, để nó hoạt động chính xác $valsẽ cần phải chứa dấu ngoặc đơn đóng, ví dụ:$val="42);"

Có nghĩa là PHP bây giờ sẽ sản xuất myPlugin.start(42);và sẽ hoạt động như mong đợi khi được thực thi bởi mã JavaScript.


JSON mã hóa dữ liệu của bạn:myPlugin.start(<?=json_encode($val)?>);
kingprawn

6

Tôi đã đưa ra một phương pháp dễ dàng để gán các biến JavaScript bằng PHP.

Nó sử dụng các thuộc tính dữ liệu HTML5 để lưu trữ các biến PHP và sau đó nó được gán cho JavaScript khi tải trang.

Một hướng dẫn đầy đủ có thể được tìm thấy ở đây .

Thí dụ:

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

Đây là mã 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");
}

2
Mặc dù các thuộc tính dữ liệu là một giải pháp hợp lý cho vấn đề, nhưng bạn sẽ gặp phải một vấn đề tương tự với câu hỏi ban đầu nếu bạn không thoát khỏi dữ liệu trong đó. Chỉ cần bạn thoát chúng ra khỏi HTML thay vì JS.
Quentin

5
  1. Chuyển đổi dữ liệu thành JSON
  2. Gọi AJAX để nhận tệp JSON
  3. Chuyển đổi JSON thành đối tượng Javascript

Thí dụ:

BƯỚC 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();
?>

BƯỚC 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);
      }
   }
}

5

Đây là một cái tôi không thấy đăng là một tùy chọn. Nó tương tự như sử dụng Ajax, nhưng rõ ràng khác nhau.

Đầu tiên, đặt nguồn của tập lệnh trực tiếp vào tệp PHP.

<script type="text/javascript" src="url_to_your_php_file.php" /></script>

Bạn thậm chí có thể chuyển một biến trở lại tệp PHP, ví dụ này:

<script type="text/javascript" src="url_to_your_php_file.php?var1=value1" /></script>

Sau đó, trong "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;
?>

Do biến tồn tại trong tập lệnh PHP đang tạo HTML, nên bạn đã bỏ lỡ bước quan trọng của việc tạo động var1=value1. Vì nó đứng kịch bản của bạn sẽ bị phá vỡ nếu dữ liệu bao gồm một 'ký tự.
Quentin

@Quentin mã VÍ DỤ hoạt động mà không có lỗi như được trình bày. nó là để chứng minh việc sử dụng. nếu một lập trình viên đi sâu vào mã hóa, họ sẽ hiểu ý nghĩa của dấu ngoặc đơn / dấu ngoặc kép trong các biến $ _GET - dù sao cũng nên được mã hóa bằng url. var1 != [some HTML code]... RAR RÀNG var1=="value1". Nói rõ hơn, bạn sai rằng tôi đã bỏ lỡ bất cứ điều gì. tập lệnh EXAMPLE đã hoàn tất và, như bạn có thể thấy, không tạo ra bất kỳ HTML nào - và OP không đề cập đến HTML. nó không xứng đáng với một downvote bởi một số người bỏ qua hạnh phúc kích hoạt - rút lại downvote
aequalsb

Mã trong câu hỏi chứng tỏ rằng OP không hiểu trích dẫn / thoát. Sự thiếu hiểu biết về điều đó là toàn bộ vấn đề! Trong khi ví dụ hoàn tất, nó không phải là một ví dụ về cách giải quyết vấn đề được nêu trong câu hỏi.
Quentin

@Quentin chính xác làm thế nào OP thể hiện họ không hiểu trích dẫn / thoát? Đây là một ví dụ về cách giải quyết vấn đề, bởi vì OP đã hỏi cách lấy dữ liệu PHP vào javascript - ví dụ của tôi là một phương pháp không được ghi chú trong bất kỳ câu trả lời nào khác
aequalsb

Với đoạn mã này không có gì để thoát hoặc mã hóa $valvà đôi khi hoạt động và đôi khi không:myPlugin.start(<?=$val?> // this works sometimes, but sometimes it fails
Quentin

3

Đây là mẹo:

  1. Đây là 'PHP' của bạn để sử dụng biến đó:

    <?php
        $name = 'PHP variable';
        echo '<script>';
        echo 'var name = ' . json_encode($name) . ';';
        echo '</script>';
    ?>
  2. Bây giờ bạn có một biến JavaScript được gọi 'name'và đây là mã JavaScript của bạn để sử dụng biến đó:

    <script>
         console.log("I am everywhere " + name);
    </script>

Có cách nào để có được nó để nó không thực sự in vào mã nguồn không? Tôi có một mảng lớn mà tôi đang vượt qua, và nó làm tắc nghẽn nguồn.
William Howley

1
Bạn có thể cung cấp một trường hợp thử nghiệm ví dụ?
Ramin Taghizada

Đây không phải là "3. Echo dữ liệu trực tiếp đến JavaScript" trong câu trả lời này ? Điều đó có vẻ tốt hơn.
kanji

3

Giả sử biến của bạn luôn là số nguyên. Trong trường hợp đó, điều này dễ dàng hơn:

<?PHP
    $number = 4;

    echo '<script>';
    echo 'var number = ' . $number . ';';
    echo 'alert(number);';
    echo '</script>';
?>

Đầu ra :

<script>var number = 4;alert(number);</script>

Giả sử biến của bạn không phải là số nguyên, nhưng nếu bạn thử phương pháp trên, bạn sẽ nhận được một cái gì đó như thế này:

<script>var number = abcd;alert(number);</script>

Nhưng trong JavaScript đây là một lỗi cú pháp.

Vì vậy, trong PHP chúng ta có một lệnh gọi hàm json_encodemã hóa chuỗi thành một đối tượng JSON.

<?PHP
    $number = 'abcd';

    echo '<script>';
    echo 'var number = ' . json_encode($number) . ';';
    echo 'alert(number);';
    echo '</script>';
?>

abcdtrong JSON là "abcd", nó trông như thế này:

<script>var number = "abcd";alert(number);</script>

Bạn có thể sử dụng cùng một phương thức cho mảng:

<?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>';
?>

Và mã JavaScript của bạn trông như thế này:

<script>var details = {"name":"supun","age":456,"weight":"55"};alert(details);console.log(details);</script>

Bảng điều khiển đầu ra

Nhập mô tả hình ảnh ở đây


2

Sau nhiều nghiên cứu, tôi thấy phương pháp đơn giản nhất là vượt qua tất cả các loại biến một cách dễ dàng.

Trong tập lệnh máy chủ, bạn có hai biến và bạn đang cố gửi chúng đến tập lệnh máy khách:

$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>';

Trong bất kỳ mã JavaScript nào của bạn được gọi trên trang, chỉ cần gọi các biến đó.


1

Tôi sẽ giả sử rằng dữ liệu cần truyền là một chuỗi.

Như các nhà bình luận khác đã tuyên bố, AJAX là một giải pháp khả thi, nhưng nhược điểm lớn hơn ưu điểm: nó có độ trễ và khó lập trình hơn (nó cần mã để lấy giá trị cả phía máy chủ và máy khách), khi đơn giản hơn chức năng thoát nên đủ.

Vì vậy, chúng tôi trở lại để trốn thoát. json_encode($string)hoạt động nếu bạn mã hóa chuỗi nguồn dưới dạng UTF-8 trước trong trường hợp chưa có, vì json_encodeyêu cầu dữ liệu UTF-8. Nếu chuỗi nằm trong ISO-8859-1 thì bạn chỉ cần sử dụng json_encode(utf8_encode($string)); nếu không bạn luôn có thể sử dụngiconv để thực hiện chuyển đổi đầu tiên.

Nhưng có một vấn đề lớn. Nếu bạn đang sử dụng nó trong các sự kiện, bạn cần chạy htmlspecialchars()kết quả để làm cho mã chính xác. Và sau đó, bạn phải cẩn thận sử dụng dấu ngoặc kép để gửi kèm sự kiện hoặc luôn thêm ENT_QUOTESvào htmlspecialchars. Ví dụ:

<?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>";

Tuy nhiên, bạn không thể sử dụng htmlspecialcharstrên mã JavaScript thông thường (mã được đặt trong <script>... </script>thẻ). Điều đó làm cho việc sử dụng chức năng này dễ bị lỗi, bằng cách quên htmlspecialcharskết quả khi viết mã sự kiện.

Bạn có thể viết một hàm không có vấn đề đó và có thể được sử dụng cả trong các sự kiện và mã JavaScript thông thường, miễn là bạn gửi các sự kiện của mình luôn trong các dấu ngoặc đơn hoặc luôn luôn ở trong dấu ngoặc kép. Đây là đề xuất của tôi, yêu cầu họ phải ở trong dấu ngoặc kép (mà tôi thích):

<?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'";
    }

Hàm này yêu cầu PHP 5.4+. Ví dụ sử dụng:

<?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>';

0

Theo mã của bạn

<$php
     $val = $myService->getValue(); // Makes an API and database call
     echo '<span id="value">'.$val.'</span>';
$>

Bây giờ bạn có thể nhận giá trị bằng DOM, sử dụng InternalHTML của span id, trong trường hợp này bạn không cần thực hiện bất kỳ cuộc gọi nào đến máy chủ, hoặc Ajax hoặc điều khác.

Trang của bạn sẽ in nó bằng PHP và JavaScript của bạn sẽ nhận được giá trị khi sử dụng DOM.


Mã này dễ bị tổn thương bởi XSS, vì nó không thoát khỏi các ký tự như <>. Ngoài ra, các giải pháp tương tự đã được đề xuất.
Michał Perłakowski

0
<?php

    $val = $myService->getValue(); // Makes an API and database call

    echo "
        <script>
            myPlugin.start({$val});
        </script> ";

?>

0

PHP

$fruits = array("apple" => "yellow", "strawberry" => "red", "kiwi" => "green");
<script>
    var color = <?php echo json_encode($fruits) ?>;
</script>
<script src="../yourexternal.js"></script>

JS (yourexternal.js)

alert("The apple color is" + color['apple'] + ", the strawberry color is " + color['strawberry'] + " and the kiwi color is " + color['kiwi'] + ".");

ĐẦU RA

Màu táo là màu vàng, màu dâu tây là màu đỏ và màu kiwi là màu xanh lá cây.


-2

Đối với những người gặp một số vấn đề khi sử dụng mã bên dưới và nó vẫn hiển thị <?php echo $username?>hoặc đại loại như thế này, hãy chỉnh sửa httpd.conf trong phần mime_module bằng cách thêm 'Ứng dụng AddType / x-httpd-php .html .htm' này vì nó có thể bị tắt theo mặc định

<?php
    $username = 1;
?>

<script type="text/javascript">
    var myData = <?php echo $username ?>;
    console.log(myData);
    alert(myData);
</script>

@MadaraUchiha bạn có thể giải thích tại sao?
Nikita

3
Bởi vì nếu $username === "hello", sau đó bạn có var myData = hello;mà sẽ phá vỡ khủng khiếp.
Madara's Ghost

-2

Sử dụng:

<?php
    $your_php_variable= 22;
    echo "<script type='text/javascript'>var your_javascript_variable = $your_php_variable;</script>";
?>

và điều đó sẽ làm việc. Nó chỉ gán một biến JavaScript và sau đó chuyển giá trị của biến PHP hiện có. Vì PHP viết các dòng JavaScript ở đây, nên nó có giá trị của biến PHP và có thể truyền trực tiếp vào nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.