将 PHP 数组传递给 Javascript,但不显示在源代码中

Posted

技术标签:

【中文标题】将 PHP 数组传递给 Javascript,但不显示在源代码中【英文标题】:Passing PHP array to Javascript w/o showing up in source 【发布时间】:2016-05-21 13:14:03 【问题描述】:

我正在处理一个历史数据库,其中包含 2,000 多张需要分类的照片,其中加载了大约 250 张。我创建了一个包含 26 个字段的 mysql 数据库来保存这些数据。

我正在使用 php 访问数据库并检索信息。

我想使用 javascript 来管理表单的其余部分。所有代码都在一个 php 文件中。

我遇到的问题是当我

//$result is the php associative array holding the photo information

<div id="dom-target" style="display: none;">
     <?php echo json_encode($result); ?>
</div>
<script>
    var div =document.getElementById("dom-target");
    var photo_array = JSON.parse(div.textContent);  

它可以工作,但是我将整个数据库结构和数据嵌入到源 html 输出中。显然,随着照片数量的增加,这不会特别有效。

如何防止这种情况发生?

如果我将这个 php 文件一分为二,一个包含 php 访问数据库并返回一个数组,另一个页面包含所有输入框等,并使用 AJAX 将数组作为 JSON 传递;那行得通吗?我不想走这条路,除非它会成功。如果所有代码都在一页上,我已经读过你不能传递数组的地方。

或者,我应该坚持用 php 做所有事情吗?

谢谢,埃里克

编辑: 我想要做的是将 php 数组传递给 js 将数组中的所有数据都包含在来源。来源我的意思是当有人“查看来源”时。我还认为,一旦我获得多达 2,000 张照片,就会变得笨拙......(2,000 张照片)x(26 个字段)= 网页中不必要地包含很多东西。

我不反对使用 AJAX。但是我见过的所有示例都在一页上显示请求,而在另一页上显示响应。我需要把我的代码分成两页吗?一个处理php和mysql,一个处理html和js?

我设想的是一个屏幕,显示 800x600 的所选照片,其下方有输入字段。一个人输入标题、说明、描述等,并与照片的名称一起保存在数据库中。在此之下,我将有 20 张缩略图,人们可以从中挑选以输入该照片的信息。我会一次循环浏览数据库 20 张左右的照片。只有文件名存储在数据库中,实际照片 jpg 存储在硬盘上并通过语句检索。

如果数据库数组中的所有数据都不在 html 源页面上,我该如何做到这一点?

编辑 2:我被要求包含更多我的 php.ini 文件。对不起,我不能让它更整洁。

<?php
$stmt_select->bind_result(
     $select_array['fhs_pkey'], 
     $select_array['file_name'],
     $select_array['caption'],  
     $select_array'post'],
     $select_array['photo_type'], 
     $select_array['last_name'], 
     $select_array['first_name'], 
     $select_array['middle_name'], 
     $select_array['honorific'], 
     etc., etc., etc
);

// put all of the database info into an array. Filename field is for full size photos
$j=$stmt_select->num_rows;
for ($i=0;$i<$j;$i++)

    $stmt_select->data_seek($i);
    $row = $stmt_select->fetch();
    //put all of the column data into the array
    foreach ($select_array as $key=>$value)                   
        $result[$i][$key]=$value;

    //in a separate php file resize the photos and save them
    //put full path with appended filename to retrieve later                  
    $result[$i]['resized'] = 
        "../images/fhs_images/800x600_photos/800x600--" .
        $result[$i]['file_name'] ;
    $result[$i]['thumb'] = "../images/fhs_images/200x150_photos/200x150--" .
        $result[$i]['file_name'] ;

 
$stmt_select->close();
$stmt_update->close();
$stmt = null;
$conn = null;

echo '<figure id="photo_figure">';
$filename = $result[2]['resized'];
echo "<img src = "."'".$filename."'" ."/>";

?>

<script>
//below is where I get the entire array printed out when I view source          
var photo_array = <?php echo json_encode($result); ?>      
var testing = photo_array[40]['thumb'];
//take care of spaces in filenames
testing = encodeURI(testing)

document.write('<img src=' + testing + '>')
</script>                 

编辑 3 @trincot

有些不对劲。我移动了我所有的 MYSQL 数据库设置并检索到一个名为 fhs_get_photos.php 的新文件中。在我的 jQuery 就绪函数中,我添加了以下内容。查看我的 cmets 显示的内容

var myarray;
$(document).ready(function()

$('.tooltips').powerTip();

$(".radio1").on('click',(function()
    
        var photo_type = $("input[name='photo_type']:radio:checked").val();
        if(photo_type == 2)
            $(".person").hide();
        else
            $(".person").show();

    ));


 $.getJSON("fhs_get_photos.php", function(photo_array)
 
    if (photo_array.jsonError !== undefined) 
    
      alert('An error occurred: ' + photo_array.error);
      return;
    

    // photo_array now contains your array. 
    // No need to decode, jQuery has already done it for you.
    // Process it (just an example)
    //$.each(photo_array, function(i, obj)
    //    $("#dom-target").append(obj.fhs_pkey + " " + obj.file_name + ", ");

//this displays correctly on a screen but not with anything else.
//Seems as if it's rewriting the page and only this is displaying which 
//may be how it's supposed to go
document.write("In js. photo_array 2,caption is: " + photo_array[2]     ['caption']);   
    );

);

在我的主要 php 中放置

       document.write("photo_array 2,caption is: " + photo_array[2]['caption']);    

但它没有显示任何内容。我怀疑 photo_array 没有被传递到页面中。然后在 js 文件中创建了一个全局变量“myarray”,并在 .getJason 函数中添加了

 myarray = photo_array;

认为它会传递到主文件中,但它没有。

【问题讨论】:

如果你想传递数据——你需要传递数据。切换到 AJAX 不会减少数据量。 抱歉,您能否准确解释一下目标是什么,以及您如何尝试实现它。 ajax 方式会起作用,我之前实际上使用过它,但你需要善于处理 ajax 响应才能成功 你不想使用AJAX的原因是什么?它实际上很简单,至少使用 jQuery。 您需要澄清(或者向我们描述)用户界面如何工作。如果您在 HTML 页面中加载 250 个图像,那么在 HTML 中包含 JSON 元数据的开销可以忽略不计,@trincot 的答案绝对是要走的路。另一方面,如果您想实现类似于分页的功能,甚至可能使用更小的页面(比如每个 20 张图像),AJAX 服务将是一种简单且平易近人的替代方法,可以在数据库中使用不同的图像偏移量重新加载页面(这也是可行的)。 【参考方案1】:

原则上您可以想到两种在 JavaScript 中获取数据的方法:

1。 Ajax 请求

使用此解决方案,您当前的 PHP 文件仅用于生成 HTML 页面,因此不生成 JSON,并创建另一个仅生成 JSON 的 PHP 文件。

假设您的 JSON 生成 PHP 文件名为 fhs_get_photos.php,那么它将包含以下代码(没有 HTML!):

<?php
header("Content-Type: application/json");

// Collect what you need in the $result variable.
// ...
// and then:

echo json_encode($result);

?>

关于处理 JSON 编码错误,请参阅我的答案中的最后一部分。

确保在开头的 &lt;?php 之前没有换行符或空格,并且除了那个 JSON 字符串之外,您没有 echoprint 任何其他内容。

您的数据库查询也将在这个新文件中。请注意,目前你有一个混合,就像这行:

echo "<img src = "."'".$filename."'" ."/>";

此行属于非 JSON 文件,但也取决于查询。因此,要么创建一个包含文件来执行查询,将其包含在两个 PHP 文件中,要么将定义图像标记(或至少图像源)的逻辑移至 JavaScript 部分(更好!)。

然后在原始 PHP 文件中,删除 JSON 输出,并添加一些 JavaScript,使用 jQuery(我知道你已经在使用它,所以你已经包含它):

$(function()
    $.getJSON("fhs_get_photos.php", function(photo_array)
        // photo_array now contains your array. 
        // No need to decode, jQuery has already done it for you.
        // Process it (just an example)
        $.each(photo_array, function(i, obj)
            $("#dom-target").append(obj['fhs_pkey'] + " " + obj['file_name'] + ", ");
        );
        // or things like:
        $("#caption_input").val(photo_array[2]['caption']);
    );
); 

一旦构建了 HTML DOM,这个函数就会被执行,所以很明显是在第一个 PHP 文件完成执行之后。它将向第二个 PHP 文件发出请求。一旦 PHP 响应了该请求,内部回调函数将接收数据。请注意,这里不需要解码 JSON,因为 jQuery 已经为您完成了。

2。使用数据生成 JavaScript

在这里您保留当前的 ​​PHP 文件,但将您注入 JSON 编码数据的部分移动到 JavaScript 块:

    <script>
        var photo_array = <?php echo json_encode($result); ?>;
        // ... process it
    </script>

无需将 JSON 包装在 JavaScript 字符串中然后对其进行解析。

来自json.org:

JSON 是 JavaScript 的对象文字符号的子集。由于 JSON 是 JavaScript 的子集,因此可以在语言中轻松使用它。

2.1。有效的 JSON 可能是无效的 JavaScript?

虽然在这个问题的上下文中没有问题(见下文),但 JSON 和 JavaScript 语法之间存在不兼容。它涉及非 ASCII 字符 U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR 是否允许在引用的字符串中以非转义形式出现:

JSON 语法允许这样做,如ECMAScript® 2015 Language Specification, section 24.3.1 中所述:

JSON 允许 Unicode 代码点 U+2028U+2029 直接出现在 String 文字中,而无需使用转义序列。

JavaScript 语法不允许 允许这样做,如ECMAScript® 2015 Language Specification, section 11.8.4 中所示:

除结束引号代码点U+005C (REVERSE SOLIDUS)U+000D (CARRIAGE RETURN)U+2028 (LINE SEPARATOR)U+2029 (PARAGRAPH SEPARATOR)U+000A (LINE FEED) 外,所有代码点都可以按字面意思出现在字符串文字中。任何代码点都可能以转义序列的形式出现。

然而,PHP 的 json_encode 遵循最后一行提供的可能性,并转义所有非 ASCII 字符,包括有问题的 U+2028U+2028,除非你明确告诉 PHP 不是 使用JSON_UNESCAPED_UNICODE flag:

JSON_UNESCAPED_UNICODE(整数)

按字面编码多字节 Unicode 字符(默认转义为 \uXXXX)。自 PHP 5.4.0 起可用。

所以,json_encode 调用没有这个标志不会产生这个问题的实例。

3。捕获json_encode 失败

根据manual on json_encode方法可以返回一个非字符串(false):

成功返回 JSON 编码字符串,失败返回 FALSE

发生这种情况时,echo json_encode($result) 将输出空字符串,即invalid JSON。

这种错误情况应该在 PHP 中被捕获,例如:

<?php
header("Content-Type: application/json");

// Collect what you need in the $result variable.
// ...
// and then:

$json = json_encode($result);
if ($json === false) 
    $json = json_encode(array("jsonError", json_last_error_msg()));
    if ($json === false) 
        // This should not happen, but we go all the way now:
        $json = '"jsonError": "unknown"';
    

?>

然后在 JavaScript 中,这个条件也应该被处理,例如这样:

if (photo_array.jsonError !== undefined) 
    alert('An error occurred: ' + photo_array.jsonError);
    return;

【讨论】:

"JSON 是 Javascript 的一个子集" --- 好吧,它不是。并非每个有效的 JSON 都是有效的 JS。 当然,在 js 中,a = "[1, 2, 3]"a = [1, 2, 3] 是不同的东西。需要解析。 谢谢,@zerkms,我从 json.org 引用了更​​准确的引用。 @BoltKey,双引号不存在。正确的 JSON 以 [ 开头,但不是双引号。 @trincot 好吧,这句话并不意味着您可以安全地在 JS 中按原样使用任何 JSON。查看***.com/q/23752156/251311了解更多详情。

以上是关于将 PHP 数组传递给 Javascript,但不显示在源代码中的主要内容,如果未能解决你的问题,请参考以下文章

将JavaScript数组传递给PHP数组[重复]

将Javascript数组传递给PHP文件[重复]

将 PHP $_POST 数组传递给 javascript/jQuery 以通过 ajax 发送回 PHP

如何使用 PHP 和 Ajax 将数组传递给 Javascript?

将 Javascript 数组转换为 PHP 数组或将其传递给 PHP 文件

将字符串数组作为 POST 传递给 PHP