Viewed   120 times

I've seen some of the questions about the passing PHP arrays to an external JavaScript file, but I can't understand it. I know how to pass PHP arrays to internal JavaScript files but not how to pass them to external JavaScript files.

Coding

   <?php 
      $a = array("Apple","Orange","Grape");
   ?> 

  <script type="text/javascript">
      var jArray= <?php echo json_encode($a); ?>;
      for(var i=0;i<3;i++){
          alert(jArray[i]);
      } 

 Answers

4

use this code, JS File (test.js)

for(var i=0;i<jArray.length;i++){
alert(jArray[i]);
}

PHP File (test.php)

<?php 
      $a = array("Apple","Orange","Grape");
?>
<script type="text/javascript">var jArray =<?php echo json_encode($a); ?>;</script>
<script type="text/javascript" src="test.js"></script>
Friday, August 26, 2022
 
4

If you want them on a series of batches, then you'll have to do something other than implode since the behavior will be different from the one you need. You can use a simple for loop to create such array structure into series of batches:

// Controller
function insert()
{

    $hitung = count($_POST['pembicara']);
    $datapembicara = array();
    for($i = 0; $i < $hitung; $i++) {
        $datapembicara[] = array(
            'id_kegiatan' => $x,
            'nama_pembicara' => $_POST['pembicara'][$i],
            'materi' => $_POST['materi'][$i],
            'alasan' => $_POST['alasan'][$i],
        );
    }

    var_dump($datapembicara);

    $this->m_admin_smf->add_pembicara($datapembicara);
}

Sidenote: I'd suggest use input class of codeigniter since it can handle XSS for you.

$value = $this->input->post('value', true); // add true parameter flag

Then after said array is made, you can use ->insert_batch() of active record. It'll do the multiple insertions for you, plus, your values are automatically escaped.

// Model
public function add_pembicara($data)
{
    $this->db->insert_batch($data);
}
Thursday, September 22, 2022
1

Alright, I created 4 alternative versions of the PHP split string algorithm, along with the two provided by @hanshenrik, and did a basic benchmark on them:

function explode1(delimiter, str, limit) {
    if (limit == null) {
        return s.split(delimiter);
    }
    var a = [];
    var lastIndex = -1;
    var index = 0;
    for (var i = 0; i < limit; i++) {
        index = str.indexOf(delimiter, lastIndex + 1);
        if (i == limit - 1) {
            a.push(str.substring(lastIndex + 1));
        } else {
            a.push(str.substring(lastIndex + 1, index));
        }
        lastIndex = index;
    }
    return a;
}

function explode2(delimiter, str, limit) {
    if (limit == null) {
        return s.split(delimiter);
    }
    var a = str.split(delimiter);
    var ret = a.slice(0, limit - 1);
    ret.push(a.slice(limit - 1).join(delimiter));
    return ret;
}

function explode3(delimiter, str, limit) {
    if (limit == null) {
        return s.split(delimiter);
    }
    var a = s.split(delimiter, limit - 1);
    var index = 0;
    for (var i = 0; i < limit - 1; i++) {
        index = s.indexOf(delimiter, index + 1);
    }
    a.push(str.substring(index + 1));
    return a;
}

function explode4(delimiter, str, limit) {
    if (limit == null) {
        return s.split(delimiter);
    }
    var a = str.split(delimiter, limit - 1);
    a.push(str.substring(a.join(delimiter).length + 1));
    return a;
}

function explode5(delimiter, string, limit) {
    //  discuss at: http://locutus.io/php/explode/
    // original by: Kevin van Zonneveld (http://kvz.io)
    //   example 1: explode(' ', 'Kevin van Zonneveld')
    //   returns 1: [ 'Kevin', 'van', 'Zonneveld' ]

    if (arguments.length < 2 ||
        typeof delimiter === 'undefined' ||
        typeof string === 'undefined') {
        return null
    }
    if (delimiter === '' ||
        delimiter === false ||
        delimiter === null) {
        return false
    }
    if (typeof delimiter === 'function' ||
        typeof delimiter === 'object' ||
        typeof string === 'function' ||
        typeof string === 'object') {
        return {
            0: ''
        }
    }
    if (delimiter === true) {
        delimiter = '1'
    }

    // Here we go...
    delimiter += ''
    string += ''

    var s = string.split(delimiter)

    if (typeof limit === 'undefined') return s

    // Support for limit
    if (limit === 0) limit = 1

    // Positive limit
    if (limit > 0) {
        if (limit >= s.length) {
            return s
        }
        return s
            .slice(0, limit - 1)
            .concat([s.slice(limit - 1)
                .join(delimiter)
            ])
    }

    // Negative limit
    if (-limit >= s.length) {
        return []
    }

    s.splice(s.length + limit)
    return s
}

function explode6(delimiter, string, limit) {
        var spl = string.split(delimiter);
        if (spl.length <= limit) {
                return spl;
        }
        var ret = [],i=0;
        for (; i < limit; ++i) {
                ret.push(spl[i]);
        }
        for (; i < spl.length; ++i) {
                ret[limit - 1] += delimiter+spl[i];
        }
        return ret;
}

var s = 'Mark Twain,1879-11-14,"We haven't all had the good fortune to be ladies; we haven't all been generals, or poets, or statesmen; but when the toast works down to the babies, we stand on common ground."'
console.log(s);

console.time('explode1');
var a1 = explode1(',', s, 3);
//console.log(a1);
console.timeEnd('explode1');

console.time('explode2');
var a2 = explode2(',', s, 3);
//console.log(a2);
console.timeEnd('explode2');

console.time('explode3');
var a3 = explode3(',', s, 3);
//console.log(a3);
console.timeEnd('explode3');

console.time('explode4');
var a4 = explode4(',', s, 3);
//console.log(a4);
console.timeEnd('explode4');

console.time('explode5');
var a5 = explode5(',', s, 3);
//console.log(a5);
console.timeEnd('explode5');

console.time('explode6');
var a6 = explode6(',', s, 3);
//console.log(a6);
console.timeEnd('explode6');

The two best-performing algorithms was explode4 principally, with explode3 a close second in multiple iterations of the benchmark:

$ node explode1.js && node explode2.js && node explode3.js && node 
explode4.js && node explode5.js && node explode6.js
explode1: 0.200ms
explode2: 0.194ms
explode3: 0.147ms
explode4: 0.183ms
explode5: 0.341ms
explode6: 0.162ms

You can run your own benchmarks, but with my tests I can confirm that splitting an array by n - 1 and then getting an index from joining the resulting array is the fastest algorithm matching explode in PHP.

EDIT: It turns out that the garbage collector biased how each successive function was measured, so I split them off into their own individual files and re-ran the benchmarking a few times. It seems explode3 is the best performing, not explode4, but I won't make a decision that I'm not completely sure of.

Wednesday, November 2, 2022
1

You don't really access it, you insert it into the javascript code when you serve the page.

However if your other javascript isn't from an external source you can do something like:

<?php
    $color = "Red";
?>
<script type="text/javascript">var color = "<?= $color ?>";</script>
<script type="text/javascript" src="file.js"></script>

and then in the file.js use color like so:

alert("color: " + color);
Wednesday, September 21, 2022
 
1

About question 1: use JSON_HEX_TAG in json_encode()

  • Example 1
    Consider this simple piece of code.

    <script>
        <?php $myVarValue = 'hello world'; ?>
        var myvar = <?php echo json_encode($myVarValue); ?>;
        alert(myvar);
    </script>
    

    Output:

    <script>
        var myvar = "hello world";
        alert(myvar);
    </script>
    

    It alerts hello world. Good.

  • Example 2
    Let's try having </script> as the string.

    <script>
        <?php $myVarValue = '</script>'; ?>
        var myvar = <?php echo json_encode($myVarValue); ?>;
        alert(myvar);
    </script>
    

    Output:

    <script>
        var myvar = "</script>";
        alert(myvar);
    </script>
    

    It alerts </script>. Good.

    As you can see, the slash (/) is correctly escaped as /,

  • Example 3
    Now, consider this very special string: <!--<script>

    <script>
        <?php $myVarValue = '<!--<script>'; ?>
        var myvar = <?php echo json_encode($myVarValue); ?>;
        alert(myvar);
    </script>
    

    Output:

    <script>
        var myvar = "<!--<script>";
        alert(myvar);
    </script>
    

    Surprisingly, it does not alert anything, and there's nothing in the error console. What?!

    If you check JSON's spec, none of the characters in <!--<script> need to be escaped, so what went wrong?

    Image adapted from json.org

For a complete and well explained answer, read this amazing Q & A. In short, it turns out that having <!--<script> in a <script> block confuses the HTML parser. PHP actually did its job correctly in json_encode(); you just can't have a <!--<script> there, even though it is a perfectly valid JavaScript string!

I did a few simple tests myself. The browsers actually ignore everything after <!--<script>, so if it happens in the middle of a page, the entire second half of the page is gone! I'm not sure if someone can actually inject something malicious there to, say, execute arbitrary code, but that's bad enough.

Also,

  • If you have not just a string in $myVarValue, but a complex object like array("key" => array("one", "and<!--<script>two", 3)), which includes <!--<script>, it's still bad.
  • If you have a plain HTML file (i.e. no PHP) and you have <!--<script> anywhere (even in a JavaScript comment) in your <script> block, it's also bad.
  • If you are using other, non-PHP, server-side programming languages, and produced <!--<script>, it's bad too.
  • If your PHP is outputting JavaScript directly (Content-type: application/javascript), it's actually ok [1].

The solution? Use JSON_HEX_TAG to escape < and > (requires PHP 5.3.0).

<script>
    <?php $myVarValue = '<!--<script>'; ?>
    var myvar = <?php echo json_encode($myVarValue, JSON_HEX_TAG); ?>;
    //                                            ^^^^^^^^^^^^^^
    alert(myvar);
</script>

Output:

<script>
    var myvar = "u003C!--u003Cscriptu003E";
    alert(myvar);
</script>

It alerts <!--<script>. Hurray!

It works because there's no more <!--<script> in the output, so no more HTML parsing problems.

Note: you don't need JSON_HEX_TAG if you're not printing into a <script> block.

[1] Here, "ok" merely means it is free from the <!--<script> issue. Dynamically generating external JavaScript files is not recommended as it has tons of disadvantages, such as those stated here, here, here.


About question 2: initial page load time

Actually, it's rather obvious. If the time needed to obtain the value of $myVarValue is long (e.g. you're fetching lots of data from DB), PHP will have to wait, so is the browser, and the user. That means longer initial page load time. If you load the data later with Ajax instead, they won't have to wait to see the initial result, but then, the Ajax call would be an extra HTTP request, so it means more workload to the server, and more load to the network.

Of course, each method has its pros and cons, so you have to decide. I suggest reading this excellent Q & A.

Sunday, December 18, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :