복붙노트

PHP에서 JavaScript로 변수와 데이터를 전달하는 방법?

PHP

PHP에서 JavaScript로 변수와 데이터를 전달하는 방법?

PHP에서 변수가 있는데 자바 스크립트 코드에서 그 값이 필요합니다. 내 변수를 PHP에서 JavaScript로 가져 오려면 어떻게해야합니까?

다음과 같은 코드가 있습니다.

<?php
     ...
     $val = $myService->getValue(); // makes an api and db call
?>

저는 val을 필요로하는 자바 스크립트 코드를 가지고 있습니다.

<script>
    myPlugin.start($val); // tried this, didn't work
    <?php myPlugin.start($val); ?> // this didn't work either
    myPlugin.start(<?=$val?> // this works sometimes, but sometimes it fails
</script>

해결법

  1. ==============================

    1.

    이를 수행하는 데 실제로 여러 가지 방법이 있습니다. 일부는 다른 것보다 더 많은 오버 헤드를 필요로하며, 어떤 것은 다른 것보다 더 좋게 간주됩니다.

    특별한 순서없이 :

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

    서버 쪽과 클라이언트 쪽 스크립트가 완전히 별개이기 때문에이 방법이 가장 적합한 것으로 간주됩니다.

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

    /* 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.
    
    
    <!-- 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에 경고합니다.

    이 방법은 AJAX보다 덜 바람직하지만 여전히 장점이 있습니다. 자바 스크립트에서 PHP가 직접적으로 없다는 점에서 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 -->
    

    이것은 아마도 가장 이해하기 쉽고, 가장 끔찍한 사용법입니다. 당신이하는 일을 알지 못하면 이것을하지 마십시오.

    구현은 비교적 간단합니다.

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

    행운을 빕니다!

  2. ==============================

    2.

    나는 더 간단한 대답을 시도 할 것이다 :

    먼저 서버에서 페이지를 제공 할 때 발생하는 이벤트의 흐름을 이해해 보겠습니다.

    따라서 실제로 기억해야 할 핵심은 HTTP가 무국적이라는 것입니다. 요청이 서버를 떠난 후에는 서버가 서버를 만질 수 없습니다. 그래서, 우리의 선택은 다음과 같습니다 :

    그것이 당신이 스스로에게 묻어야 할 핵심 질문입니다 :

    웹 사이트는 주로 페이지 기반이며 페이지로드 시간은 가능한 한 빨라야합니다 (예 : Wikipedia). 웹 애플리케이션은 AJAX가 더 많고 고객에게 빠른 정보를 얻기 위해 왕복 여행을 많이합니다 (예 : 재고 대시 보드).

    초기 요청이 완료된 후 클라이언트에서 더 많은 요청을 보내려면 상당한 오버 헤드가있는 더 많은 HTTP 요청이 필요하므로 속도가 느립니다. 또한 AJAX 요청을 처리 할 때 핸들러가 필요하므로 비동기가 필요합니다.

    사이트에서 서버의 정보를 가져 오는 응용 프로그램이 아닌 이상 다른 요청을하지 않는 것이 좋습니다.

    전환 및로드 시간에 큰 영향을주는 빠른 응답 시간을 원합니다. ajax 요청을하는 것은이 경우 초기 가동 시간이 느리고 불필요합니다.

    문제를 해결할 수있는 두 가지 방법이 있습니다.

    쿠키를 설정하는 것은 그다지 어려운 일이 아니며, 값을 할당하면됩니다.

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

    그런 다음 document.cookie를 사용하여 JavaScript로 읽을 수 있습니다.

    여기에 짧은 파서를 굴린 파서가 있지만이 바로 위에 링크 된 대답은 더 나은 테스트를 거친 파서입니다.

    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.
    

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

    더 많은 데이터가 있으면 JS 변수로 JSON으로 인코딩 할 수 있습니다.

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

    PHP 측에서 $ value가 json_encodeable이라고 가정합니다 (일반적으로). 이 기술은 예를 들어 StackOverflow가 채팅으로 수행하는 것입니다 (PHP 대신 .net 만 사용).

    애플리케이션을 작성하는 경우 갑자기 초기로드 시간이 앱의 지속적인 성능만큼 중요하지 않으며 데이터 및 코드를 별도로로드하기 위해 성과를 거두기 시작합니다.

    여기 내 대답은 JavaScript로 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 db call
     echo json_encode($val); // write it to the output
     $>
    

    이렇게하면 JS 파일에서 코드를 요청하거나 레이아웃을 요청하는 대신 데이터를 묻고 표시합니다. 이것은 더 깨끗해졌으며 응용 프로그램이 높아질수록 성과가 나타납니다. 또한 관심사를 더 잘 구분할 수 있으며 서버 측 기술을 사용하지 않고도 클라이언트 측 코드를 테스트 할 수 있다는 점도 장점입니다.

    추신 : PHP에서 JavaScript에 무엇이든 삽입 할 때 XSS 공격 벡터를 잘 알아야합니다. 값을 올바르게 벗어나기가 매우 어렵고 상황에 민감합니다. XSS를 다루는 방법을 모르거나 알지 못하는 경우이 OWASP 기사,이 질문 및이 질문을 읽어보십시오.

  3. ==============================

    3.

    나는 보통 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');
    
            // service variable now contains the value of $myService->getValue();
        });
    });
    </script>
    

    이 예제는 jQuery를 사용하지만 다른 라이브러리 또는 바닐라 자바 ​​스크립트에 적용 할 수 있습니다.

    다음에서 데이터 세트 속성에 대해 자세히 알아볼 수 있습니다. https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset

  4. ==============================

    4.

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

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

  5. ==============================

    5.

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

    <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>
    
  6. ==============================

    6.

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

    호출 대기열에 담기 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-ui'에 정의되어 있기 때문에 이전에 인쇄됩니다. '사용자 정의 스크립트'에 대한 추가 데이터는 새로운 스크립트 블록 내부에 있으며 그 앞에 배치됩니다. 추가 데이터를 보유하고있는 mydata 객체를 포함하고 있으며 이제는 '사용자 정의 스크립트'에 사용할 수 있습니다.

  7. ==============================

    7.

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

    javascript에 관한 한 $ val은 정의되지 않았기 때문에 작동하지 않습니다. PHP는 $ val에 대해 아무 것도 출력하지 않습니다. 브라우저에서 소스를 보면 다음과 같이 표시됩니다.

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

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

    이것은 php가 myPlugin을 상수로 취급하려고 시도하기 때문에 작동하지 않습니다. 실패하면 myPlugin을 PHP 함수 start ()의 출력과 연결하려고 시도하는 문자열 'myPlugin'으로 처리하려고 시도합니다. 그 이후로 정의되지 않으면 심각한 오류가 발생합니다.

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

    PHP가 예상되는 인수로 유효한 javascript를 생성하고 있기 때문에 이것이 작동 할 확률이 높지만, 실패하면 myPlugin이 아직 준비되지 않았기 때문에 가능성이 있습니다. 실행 순서를 확인하십시오.

    또한 PHP 출력은 안전하지 않으므로 json_encode ()로 필터링해야합니다.

    편집하다

    myPlugin.start ( : - \)에 빠진 괄호를 알지 못했기 때문에

    @Second Rikudo가 지적했듯이 올바르게 작동하려면 $ val에 닫는 괄호가 있어야합니다 (예 : $ val = "42);"

    PHP가 이제 myPlugin.start (42)를 생성한다는 것을 의미합니다. javascript에 의해 실행될 때 예상대로 작동합니다

  8. ==============================

    8.

    이 시도

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

    --

    - 잠시 후 그러나 작동하지만 성능이 저하됩니다. PHP는 서버 측 스크립트이고 javascript는 사용자 측 스크립트입니다.

  9. ==============================

    9.

    필자는 PHP를 사용하여 JavaScript 변수를 할당하는 쉬운 방법을 발표했습니다.

    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
    

    Hers는 JS 코드입니다.

    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");
    }
    
  10. ==============================

    10.

    여기에 옵션으로 게시 된 것으로 보이지 않는 것이 있습니다. 그것은 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 javascripts 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;
    ?>
    
  11. ==============================

    11.

    여기에 속임수입니다 :

    <?php 
     $name = 'PHP variable';
     echo '<script>';
     echo 'var name = ' . json_encode($name) . ';';
     echo '</script>';
    <?
    <script>
      console.log("i am everywhere " + name);
    </script>
    
  12. ==============================

    12.

    전송할 데이터가 문자열이라고 가정합니다.

    다른 의견 제시 자들이 말했듯이, AJAX는 하나의 가능한 해결책이지만, 단점은 프로들을 능가합니다 : 프로그래밍이 쉽지 않습니다 (서버 측과 클라이언트 측의 값을 검색하는 코드가 필요합니다). 이스케이프 기능으로 충분할 것입니다.

    그래서, 우리는 도망 가기로 돌아 왔습니다. json_encode가 UTF-8 데이터를 필요로하기 때문에 소스 문자열을 UTF-8로 먼저 인코딩하면 json_encode ($ string)가 작동합니다. 문자열이 ISO-8859-1이면 json_encode (utf8_encode ($ string));를 사용하면됩니다. 그렇지 않으면 항상 iconv를 사용하여 변환을 먼저 수행 할 수 있습니다.

    그러나 큰 문제가 있습니다. 이벤트에서 사용하는 경우 올바른 코드를 만들기 위해 결과에 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>";
    

    그러나 일반 JS 코드 (