将PHP数组传递到Javascript w/o,显示在源代码中。

时间:2023-01-17 21:55:54

I'm working on a historical database with 2,000+ photos that need to be categorized of which about 250 are loaded. I've created a MYSQL database with 26 fields to hold this data.

我正在开发一个历史数据库,其中有2000多张照片需要分类,其中大约有250张照片被载入。我创建了一个包含26个字段的MYSQL数据库来保存这些数据。

I'm using PHP to access the database and retrieve the information.

我使用PHP访问数据库并检索信息。

I'd like to use JavaScript to manage the rest of the form. All of the code is in one php file.

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

The problem I'm running into is when I

我遇到的问题是

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

It works but, I get the entire database structure and data embedded in the source html output. Obviously this won't do especially as the photo count increases.

它可以工作,但是,我将整个数据库结构和数据嵌入到源html输出中。显然,这并不能实现,尤其是随着照片数量的增加。

How can I prevent this?

我该如何预防呢?

If I were to split this one php file into two, one containing php accessing the database and returning an array, and the other page containing all of the input boxes etc., and use AJAX passing the array as a JSON; would that work? I'd hate to go down that path unless it'll be successful. I've read where you can't pass the array if all of the code is on one page.

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

Or, should I just stick with doing everything in php?

或者,我应该继续用php做所有的事情吗?

Thanks, Eric

谢谢你,埃里克

Edit: What I want to do is to pass a php array to js without having all of the data in the array included in the source. By source I mean when someone "views source". I also think that once I get up to 2,000 photos is is going to be unwieldy....(2,000 photos) x (26 fields) = a lot of stuff needlessly included in the web page.

编辑:我要做的是将一个php数组传递给js,而不包含源数组中的所有数据。我指的是当某人“查看源”的时候。我也认为一旦我得到多达2000张照片是笨拙....(2000张照片)x(26个字段)=在网页中不必要地包含了很多东西。

I have no objection to using AJAX. But all of the examples I've seen have the request on one page and the response on another. Do I need to split up my code onto two pages; one to handle the php and MySQL and the other to handle the html and js?

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

What I envision is a screen showing the selected photo at 800x600 with the input fields below that. A person enters the title, caption, description etc and that is saved in the db with the photo's name. Below that I would have 20 thumbnail photos which a person could pick from to enter that photo's information. I would loop through the database 20 or so, photos at a time. Only the file names are stored in the database, the actual photo jpg is stored on a hard disk and retrieved via an statement.

我设想的是一个屏幕,显示在800x600的选中照片,下面是输入字段。一个人输入标题、标题、描述等,然后用照片的名字保存在数据库中。下面是20张缩略图,用户可以从中选择,输入照片的信息。我会在数据库中循环大约20次,每次都是照片。只有文件名称存储在数据库中,实际的照片jpg存储在硬盘上,并通过语句检索。

How can I do this without all of the data in the database array being on the html source page?

如果数据库数组中的所有数据都在html源页面上,我怎么做呢?

Edit 2: I've been asked to include more of my php. Sorry I couldn't make it neater.

编辑2:我被要求包含更多的php。对不起,我不能把它弄得更整洁。

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

Edit 3 @trincot

编辑3 @trincot

Something's not right. I moved all of my MYSQL db setup and retrieve into a new file called fhs_get_photos.php. In my jQuery ready function I added the below. See my comments on what gets displayed

东西是不正确的。我移动了所有的MYSQL db设置,并检索到一个名为fhs_get_photoss.php的新文件。在我的jQuery就绪函数中,我添加了以下内容。查看我对显示内容的评论

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']);   
    });

});

In my main php I put

在主php中

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

but it's not displaying anything. I suspect photo_array is not being passed into the page. In the js file, I then created a global variable 'myarray' and in the .getJason function I added

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

 myarray = photo_array;

thinking it would pass into the main file but it didn't.

认为它会传入主文件,但它没有。

1 个解决方案

#1


3  

There are in principle two ways you can think of to get data in JavaScript:

原则上有两种方法可以让你用JavaScript获取数据:

1. Ajax request

With this solution use your current PHP file for generating the HTML page only, so without generating JSON, and create another PHP file which will generate the JSON only.

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

So let's say your JSON-generating PHP file is called fhs_get_photos.php, then it would have this code (no HTML!):

假设生成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);

?>

See the last section in my answer for treating JSON encoding errors.

关于处理JSON编码错误,请参见我的回答的最后一节。

Make sure there are no line breaks or spaces before the opening <?php, and that you do not echo or print anything else than that one JSON string.

确保在开始前没有换行或空格?php,并且除了一个JSON字符串之外,您不回显或打印任何其他内容。

Your database query would also be in this new file. Note that currently you have a mix, like with this line:

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

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

This line belongs in the non-JSON file, but it also depends on the query. So either you make an include file that does the query, include it in both PHP files, or you move the logic of defining the image tag (or at least the image's source) to the JavaScript part (better!).

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

Then in the original PHP file, remove the JSON output, and add some JavaScript, using jQuery (I understood you were already using it, so you have it included):

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

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

This function will get executed once the HTML DOM has been built, so evidently after the first PHP file has finished execution. It will make the request to the second PHP file. Once that request is answered by PHP, the inner call-back function will receive the data. Note that there is no need to decode JSON here, as jQuery has already done that for you.

该函数将在构建HTML DOM之后执行,因此很明显,在第一个PHP文件完成执行之后。它将请求第二个PHP文件。一旦该请求得到PHP的响应,内部回调函数将接收数据。请注意,这里不需要解码JSON,因为jQuery已经为您做了这一点。

2. Generate JavaScript with data

Here you keep your current PHP file, but move the part where you inject the JSON encoded data to the JavaScript block:

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

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

There is no need to wrap JSON in a JavaScript string to then parse it.

不需要将JSON包装在JavaScript字符串中,然后解析它。

From json.org:

从json.org:

JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.

JSON是JavaScript对象文字表示法的一个子集。由于JSON是JavaScript的一个子集,因此可以在语言中使用它,不会有任何混乱和麻烦。

2.1. Valid JSON that could be invalid JavaScript?

Although not a problem in the context of this question (see below), there is an incompatibility between JSON and JavaScript syntax. It concerns whether or not the non-ASCII characters U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR are allowed to appear unescaped in quoted strings:

尽管在这个问题的上下文中没有问题(见下文),但是JSON和JavaScript语法之间存在不兼容性。它涉及是否允许非ascii字符U+2028行分隔符和U+2029段分隔符出现在引号字符串中:

  • JSON syntax allows this, as stated in the ECMAScript® 2015 Language Specification, section 24.3.1:

    JSON的语法允许,如上所述的ECMAScript®2015语言规范,部分24.3.1:

    JSON allows Unicode code points U+2028 and U+2029 to directly appear in String literals without using an escape sequence.

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

  • JavaScript syntax does not allow this, as indicated in the ECMAScript® 2015 Language Specification, section 11.8.4:

    JavaScript语法不允许这样做,表明ECMAScript®2015语言规范,部分11.8.4:

    All code points may appear literally in a string literal except for the closing quote code points, U+005C (REVERSE SOLIDUS), U+000D (CARRIAGE RETURN), U+2028 (LINE SEPARATOR), U+2029 (PARAGRAPH SEPARATOR), and U+000A (LINE FEED). Any code points may appear in the form of an escape sequence.

    除了结束引号、U+005C(反向SOLIDUS)、U+000D(回车)、U+2028(换行符)、U+2029(段落分隔符)和U+000A(换行符)之外,所有代码点都可能以字符串文字形式出现。任何代码点都可能以转义序列的形式出现。

PHP's json_encode however, follows the possibility offered in that last line, and escapes all non-ASCII characters, including the problematic U+2028 and U+2028, except if you explicitly tell PHP not to do so with the JSON_UNESCAPED_UNICODE flag:

但是,PHP的json_encode遵循最后一行中提供的可能性,并转义所有非ascii字符,包括有问题的U+2028和U+2028,除非您明确告诉PHP不要使用JSON_UNESCAPED_UNICODE标志:

JSON_UNESCAPED_UNICODE (integer)

JSON_UNESCAPED_UNICODE(整数)

  • Encode multibyte Unicode characters literally (default is to escape as \uXXXX). Available since PHP 5.4.0.
  • 按字面意思编码多字节Unicode字符(默认是转义为\uXXXX)。由于PHP 5.4.0可用。

So, a json_encode call without this flag will not produce instances of this problem.

因此,没有此标志的json_encode调用将不会产生此问题的实例。

3. Catch json_encode failures

According to the manual on json_encode the method can return a non-string (false):

根据json_encode手册,该方法可以返回一个非字符串(false):

Returns a JSON encoded string on success or FALSE on failure.

返回一个JSON编码的字符串成功或错误的失败。

When this happens echo json_encode($result) will output the empty string, which is invalid JSON.

当发生这种情况时,echo json_encode($result)将输出空字符串,这是无效的JSON。

This error condition should be captured in PHP, for example like this:

这个错误条件应该在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"}';
    }
}
?>

And then in JavaScript, this condition should be handled as well, for example like this:

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

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

#1


3  

There are in principle two ways you can think of to get data in JavaScript:

原则上有两种方法可以让你用JavaScript获取数据:

1. Ajax request

With this solution use your current PHP file for generating the HTML page only, so without generating JSON, and create another PHP file which will generate the JSON only.

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

So let's say your JSON-generating PHP file is called fhs_get_photos.php, then it would have this code (no HTML!):

假设生成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);

?>

See the last section in my answer for treating JSON encoding errors.

关于处理JSON编码错误,请参见我的回答的最后一节。

Make sure there are no line breaks or spaces before the opening <?php, and that you do not echo or print anything else than that one JSON string.

确保在开始前没有换行或空格?php,并且除了一个JSON字符串之外,您不回显或打印任何其他内容。

Your database query would also be in this new file. Note that currently you have a mix, like with this line:

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

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

This line belongs in the non-JSON file, but it also depends on the query. So either you make an include file that does the query, include it in both PHP files, or you move the logic of defining the image tag (or at least the image's source) to the JavaScript part (better!).

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

Then in the original PHP file, remove the JSON output, and add some JavaScript, using jQuery (I understood you were already using it, so you have it included):

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

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

This function will get executed once the HTML DOM has been built, so evidently after the first PHP file has finished execution. It will make the request to the second PHP file. Once that request is answered by PHP, the inner call-back function will receive the data. Note that there is no need to decode JSON here, as jQuery has already done that for you.

该函数将在构建HTML DOM之后执行,因此很明显,在第一个PHP文件完成执行之后。它将请求第二个PHP文件。一旦该请求得到PHP的响应,内部回调函数将接收数据。请注意,这里不需要解码JSON,因为jQuery已经为您做了这一点。

2. Generate JavaScript with data

Here you keep your current PHP file, but move the part where you inject the JSON encoded data to the JavaScript block:

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

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

There is no need to wrap JSON in a JavaScript string to then parse it.

不需要将JSON包装在JavaScript字符串中,然后解析它。

From json.org:

从json.org:

JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.

JSON是JavaScript对象文字表示法的一个子集。由于JSON是JavaScript的一个子集,因此可以在语言中使用它,不会有任何混乱和麻烦。

2.1. Valid JSON that could be invalid JavaScript?

Although not a problem in the context of this question (see below), there is an incompatibility between JSON and JavaScript syntax. It concerns whether or not the non-ASCII characters U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR are allowed to appear unescaped in quoted strings:

尽管在这个问题的上下文中没有问题(见下文),但是JSON和JavaScript语法之间存在不兼容性。它涉及是否允许非ascii字符U+2028行分隔符和U+2029段分隔符出现在引号字符串中:

  • JSON syntax allows this, as stated in the ECMAScript® 2015 Language Specification, section 24.3.1:

    JSON的语法允许,如上所述的ECMAScript®2015语言规范,部分24.3.1:

    JSON allows Unicode code points U+2028 and U+2029 to directly appear in String literals without using an escape sequence.

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

  • JavaScript syntax does not allow this, as indicated in the ECMAScript® 2015 Language Specification, section 11.8.4:

    JavaScript语法不允许这样做,表明ECMAScript®2015语言规范,部分11.8.4:

    All code points may appear literally in a string literal except for the closing quote code points, U+005C (REVERSE SOLIDUS), U+000D (CARRIAGE RETURN), U+2028 (LINE SEPARATOR), U+2029 (PARAGRAPH SEPARATOR), and U+000A (LINE FEED). Any code points may appear in the form of an escape sequence.

    除了结束引号、U+005C(反向SOLIDUS)、U+000D(回车)、U+2028(换行符)、U+2029(段落分隔符)和U+000A(换行符)之外,所有代码点都可能以字符串文字形式出现。任何代码点都可能以转义序列的形式出现。

PHP's json_encode however, follows the possibility offered in that last line, and escapes all non-ASCII characters, including the problematic U+2028 and U+2028, except if you explicitly tell PHP not to do so with the JSON_UNESCAPED_UNICODE flag:

但是,PHP的json_encode遵循最后一行中提供的可能性,并转义所有非ascii字符,包括有问题的U+2028和U+2028,除非您明确告诉PHP不要使用JSON_UNESCAPED_UNICODE标志:

JSON_UNESCAPED_UNICODE (integer)

JSON_UNESCAPED_UNICODE(整数)

  • Encode multibyte Unicode characters literally (default is to escape as \uXXXX). Available since PHP 5.4.0.
  • 按字面意思编码多字节Unicode字符(默认是转义为\uXXXX)。由于PHP 5.4.0可用。

So, a json_encode call without this flag will not produce instances of this problem.

因此,没有此标志的json_encode调用将不会产生此问题的实例。

3. Catch json_encode failures

According to the manual on json_encode the method can return a non-string (false):

根据json_encode手册,该方法可以返回一个非字符串(false):

Returns a JSON encoded string on success or FALSE on failure.

返回一个JSON编码的字符串成功或错误的失败。

When this happens echo json_encode($result) will output the empty string, which is invalid JSON.

当发生这种情况时,echo json_encode($result)将输出空字符串,这是无效的JSON。

This error condition should be captured in PHP, for example like this:

这个错误条件应该在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"}';
    }
}
?>

And then in JavaScript, this condition should be handled as well, for example like this:

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

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