将 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 编码错误,请参阅我的答案中的最后一部分。
确保在开头的 <?php
之前没有换行符或空格,并且除了那个 JSON 字符串之外,您没有 echo
或 print
任何其他内容。
您的数据库查询也将在这个新文件中。请注意,目前你有一个混合,就像这行:
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+2028
和U+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+2028
和 U+2028
,除非你明确告诉 PHP 不是 使用JSON_UNESCAPED_UNICODE
flag:
按字面编码多字节 Unicode 字符(默认转义为 \uXXXX)。自 PHP 5.4.0 起可用。
JSON_UNESCAPED_UNICODE
(整数)
所以,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,但不显示在源代码中的主要内容,如果未能解决你的问题,请参考以下文章
将 PHP $_POST 数组传递给 javascript/jQuery 以通过 ajax 发送回 PHP
如何使用 PHP 和 Ajax 将数组传递给 Javascript?