[javascript] 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>



답변

실제로 몇 가지 방법이 있습니다. 일부는 다른 것보다 더 많은 오버 헤드를 필요로하며 일부는 다른 것보다 더 나은 것으로 간주됩니다.

특별한 순서는 없습니다 :

  1. AJAX를 사용하여 서버에서 필요한 데이터를 가져옵니다.
  2. 데이터를 페이지 어딘가에 에코하고 JavaScript를 사용하여 DOM에서 정보를 가져옵니다.
  3. 데이터를 JavaScript로 직접 에코하십시오.

이 글에서는 위의 각 방법을 살펴보고 각각의 장단점과 구현 방법을 살펴 보겠습니다.

1. AJAX를 사용하여 서버에서 필요한 데이터를 가져옵니다.

서버 측과 클라이언트 측 스크립트는 완전히 분리되어 있으므로이 방법이 가장 좋습니다 .

찬성

  • 계층 간 더 나은 분리 -내일 PHP 사용을 중단하고 서블릿, REST API 또는 다른 서비스로 이동하려는 경우 많은 JavaScript 코드를 변경할 필요가 없습니다.
  • 더 읽기 -JavaScript는 JavaScript, PHP는 PHP입니다. 둘을 혼합하지 않으면 두 언어 모두에서 더 읽기 쉬운 코드를 얻을 수 있습니다.
  • 비동기식 데이터 전송 가능 -PHP에서 정보를 얻는 데 시간 / 자원이 많이 소요될 수 있습니다. 때로는 정보를 기다렸다가 페이지를로드하고 정보가 도달 할 때까지 원하지 않습니다.
  • 마크 업에서 데이터를 직접 찾을 수 없음 -이는 마크 업에서 추가 데이터를 깨끗하게 유지하며 JavaScript 만 볼 수 있음을 의미합니다.

단점

  • 대기 시간 -AJAX는 HTTP 요청을 생성하고 HTTP 요청은 네트워크를 통해 전달되며 네트워크 대기 시간이 있습니다.
  • 상태 -별도의 HTTP 요청을 통해 가져온 데이터에는 HTML 문서를 가져온 HTTP 요청의 정보가 포함되지 않습니다. 이 정보가 필요할 수 있습니다 (예 : 양식 제출에 대한 응답으로 HTML 문서가 생성 된 경우). 필요한 경우 어떻게 든 전송해야합니다. 페이지에 데이터를 포함하지 않은 경우 (이 기술을 사용하는 경우) 경쟁 조건에 따라 쿠키 / 세션으로 제한됩니다.

구현 예

AJAX를 사용하면 두 페이지가 필요합니다. 하나는 PHP가 출력을 생성하는 곳이고 두 번째는 JavaScript가 해당 출력을 얻는 곳입니다.

get-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파일로드가 완료되면 경고 합니다.

더 읽을 거리

2. 데이터를 페이지 어딘가에 에코하고 JavaScript를 사용하여 DOM에서 정보를 가져옵니다.

이 방법은 AJAX보다 덜 바람직하지만 여전히 장점이 있습니다. 그것은 여전히 상대적으로 자바 스크립트에서 직접에는 PHP가 없다는 것을 의미에서 PHP와 자바 스크립트 사이에 분리.

찬성

  • 빠름 -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가 완료되어 더 이상 액세스 할 수 없다는 것을 강조하고 싶습니다.
  • 그런 다음 JavaScript가 포함 된 HTML이 클라이언트에 도달하여 해당 HTML에서 JavaScript를 실행할 수 있습니다.

따라서 여기서 기억해야 할 핵심은 HTTP는 stateless 입니다. 요청이 서버를 떠나면 서버는이를 만질 수 없습니다. 따라서 우리의 옵션은 다음과 같습니다.

  1. 초기 요청이 완료된 클라이언트에서 더 많은 요청을 보냅니다 .
  2. 초기 요청에서 서버가 말한 내용을 인코딩하십시오.

솔루션

그것은 당신이 스스로에게 물어봐야 할 핵심 질문입니다.

웹 사이트 나 응용 프로그램을 작성하고 있습니까?

웹 사이트는 주로 페이지 기반이며 페이지로드 시간은 최대한 빨라야합니다 (예 : 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.

쿠키는 작은 데이터에 좋습니다. 이것이 추적 서비스가 자주하는 일입니다.

더 많은 데이터가 있으면 대신 JavaScript 변수 내에서 JSON으로 인코딩 할 수 있습니다.

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

가정 $value되고 json_encode는 PHP 측에 수 (보통이다). 이 기술은 예를 들어 스택 오버플로가 채팅에서 수행하는 작업입니다 (PHP 대신 .NET 만 사용).

신청

응용 프로그램을 작성하는 경우-갑자기 초기로드 시간이 항상 응용 프로그램의 지속적인 성능만큼 중요하지는 않으며 데이터와 코드를 별도로로드하기 위해 비용을 지불하기 시작합니다.

내 대답은 여기에 어떻게 자바 스크립트에서 AJAX를 사용하여로드 데이터에 대한 설명 :

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 파일은 코드를 요구하거나 레이아웃을 요구하지 않고 데이터를 요구하고 보여줍니다. 이것은 더 깨끗하고 응용 프로그램이 높아질수록 지불을 시작합니다. 또한 문제를보다 효과적으로 분리 할 수 ​​있으며 서버 측 기술없이 클라이언트 측 코드를 테스트 할 수 있습니다.

포스트 스크립트 : 당신은 할 필요가 매우 당신이 PHP에서 자바 스크립트 아무것도 주입 할 때 XSS 공격 벡터를 알고 있습니다. 그건 아주 제대로 값을 탈출하기 어렵다과는 상황이다. XSS를 처리하는 방법을 잘 모르거나 모르는 경우이 OWASP 기사 , 기사이 질문을 읽으십시오 .


답변

나는 보통 HTML에서 data- * 속성을 사용합니다.

<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 에서 dataset 속성에 대한 자세한 내용을 확인할 수 있습니다.


답변

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

json_encode ()에는 다음이 필요합니다.

  • PHP 5.2.0 이상
  • $PHPVar UTF-8, 유니 코드로 인코딩됩니다.

답변

다음 방법 중 하나를 사용하십시오.

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


답변

나는 워드 프레스가 그 enqueuelocalize 함수 와 함께 작동하는 방식을 매우 좋아한다. 따라서이 모델에 따라 스크립트 의존성에 따라 스크립트를 페이지에 넣고 스크립트에 추가 데이터를 제공하는 간단한 클래스를 작성했다.

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’에 의존하는 ‘jquery-ui’에 정의되어 있기 때문에 이전에 인쇄됩니다. ‘custom-script’에 대한 추가 데이터는 새 스크립트 블록 안에 있으며 그 앞에 배치되며 mydata, 이제 ‘custom-script’에 사용할 수있는 추가 데이터를 보유하는 객체가 포함 됩니다.


답변

이 시도:

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

-한동안 시도한 후

작동하지만 성능이 느려집니다. PHP는 서버 측 스크립트이고 JavaScript는 사용자측입니다.