PHP 和 HTML

PHP 和 HTML 有很多相互作用:PHP 能生成 HTML,HTML 可以向 PHP 传递信息。在阅读这些常见问题之前,先学会怎样 从 PHP 之外取得变量很重要。此主题的手册页也包括很多例子。还要仔细留意 register_globals对你意味着什么。

当我通过表单/URL 传值时需要用什么编码/解码方法?

在几个环节上编码方式很重要。假定有 string $data,其中包含了想通过非编码方式传递的字符串,那这是相关步骤:

  • HTML 解析。要指定一个任意的字符串, 必须将其放在双引号中,并用 htmlspecialchars()处理整个值。

  • URL:URL 由几部分组成。如果希望自己的数据被当作其中一项来解释, 必须urlencode()对其编码。

Example #1 隐藏的 HTML 表单单元

<?php
    
echo "<input type='hidden' value='" htmlspecialchars($data) . "' />\n";
?>

Note: urlencode()来处理 $data是错误的,因为是浏览器的责任来 urlencode()数据。所有流行的浏览器都能正确处理。注意不论何种方法(例如 GET 或 POST)都会这样。不过只会在用 GET 请求时注意到这一点,因为 POST 请求通常是隐藏的。

Example #2 等待用户编辑的数据

<?php
    
echo "<textarea name='mydata'>\n";
    echo 
htmlspecialchars($data)."\n";
    echo 
"</textarea>";
?>

Note: 数据会按照预期的显示在浏览器中,因为浏览器会解释 HTML 转义符号。 当提交时,不论是 GET 或者 POST 方法,数据都会被浏览器进行 urlencode 来传输,并直接被 PHP urldecode。所以最终不需要自己处理任何 urlencoding/urldecoding,全都是自动处理的。

Example #3 URL 中的例子

<?php
    
echo "<a href='" htmlspecialchars("/nextpage.php?stage=23&data=" .
        
urlencode($data)) . "'>\n";
?>

Note: 事实上这在编造一个 HTML 的 GET 请求,因此需要手工对数据进行 urlencode()

Note: 需要对整个 URL 进行 htmlspecialchars(),因为 URL 是作为 HTML 属性的一个值出现的。在本例中,浏览器会首先对值进行 un- htmlspecialchars(),然后再传递此 URL。PHP 将能正确理解 URL,因为对数据进行了 urlencoded() 要注意到 URL 中的 &被替换成了 &amp;。如果忘了这一步,尽管大多数浏览器都能恢复,但也不总是这样。因此即使 URL 不是动态的,也 需要对 URL 进行 htmlspecialchars()

我在试用 <input type="image"> 标记,但是没有 $foo.x$foo.y变量,它们哪去了?

当提交表单时,可以用图片代替标准的提交按钮,用类似这样的标记:

<input type="image" src="image.gif" name="foo" />
当用户点击了图片的任何部分,该表单会被发送到服务器并加上两个额外的变量: foo.xfoo.y

因为 foo.xfoo.y在 PHP 中会成为非法的变量名,它们被自动转换成了 foo_xfoo_y。也就是用下划线代替了点。因此,可以按照在 来自 PHP 之外的变量这一节中说明的那样访问这些变量。例如, $_GET['foo_x']

Note:

请求变量名中的空格被转换为下划线。

怎样在 HTML 的 <form> 中建立数组?

要使你的 <form> 结果被当成 array发送到 PHP 脚本,要对 <input>,<select> 或者 <textarea> 单元这样命名:

<input name="MyArray[]" />
<input name="MyArray[]" />
<input name="MyArray[]" />
<input name="MyArray[]" />
注意变量名后的方括号,这使其成为一个数组。可以通过给不同的单元分配相同的名字来把单元分组到不同的数组里:
<input name="MyArray[]" />
<input name="MyArray[]" />
<input name="MyOtherArray[]" />
<input name="MyOtherArray[]" />
这将产生两个数组,MyArray 和 MyOtherArray,并发送给 PHP 脚本。还可以给数组分配指定的键名:
<input name="AnotherArray[]" />
<input name="AnotherArray[]" />
<input name="AnotherArray[email]" />
<input name="AnotherArray[phone]" />
AnotherArray 数组将包含键名 0,1,email 和 phone。

Note:

指定数组的键名是 HTML 的可选项。如果不指定键名,则数组被按照单元在表单中出现的顺序填充。第一个例子将包含键名 0,1,2 和 3。

参见 数组函数来自 PHP 之外的变量

怎样从可多选的 HTML 的 select multiple 标记中得到所有结果?

可多选的 select multiple 标记是 HTML 的一个构造,允许用户从一个列表中选择多个项目。这些项目接着被传递给该表单 action 中指定的处理程序。问题是它们都会被用同样的名字传递。例如:

<select name="var" multiple="yes">
每个被选项将这样被传递到表单处理程序:
var=option1 var=option2 var=option3
每个选项将覆盖前面一个 $var变量的内容。解决方案是用 PHP 的"表单单元数组"特性。使用方法如下:
<select name="var[]" multiple="yes">
这将告诉 PHP 将 $var当成数组对待,每个对 var[] 的赋值都会给数组增加一项。第一项将成为 $var[0],下一个是 $var[1],等等。可以用 count()函数来测定选择了多少个项目,必要时可以用 sort()函数来对选项的数组进行排序。

注意如果在 JavaScript 中通过名字来引用单元,单元名字中的 []可能会造成问题。用表单单元中的数字序号来替代,或者将变量名用单引号括起来并用其作为单元数组的索引,例如:

variable = documents.forms[0].elements['var[]'];

怎样从 Javascript 传递一个变量到 PHP?

由于 Javascript (通常情况下)是客户端技术,而 PHP (通常情况下)是服务器端技术,而且 HTTP 是一种"无状态"协议,因此两种语言之间不能直接共享变量。

但是,有可能在二者之间传递变量。一种实现的方法是用 PHP 生成 Javascript 代码,并让浏览器自动刷新,将特定的变量传递回 PHP 脚本。以下例子显示了如何这样做——让 PHP 代码取得显示屏幕的高度和宽度,通常只能在客户端这么做。

<?php
if (isset($_GET['width']) AND isset($_GET['height'])) {
  
// output the geometry variables
  
echo "Screen width is: "$_GET['width'] ."<br />\n";
  echo 
"Screen height is: "$_GET['height'] ."<br />\n";
} else {
  
// pass the geometry variables
  // (preserve the original query string
  //   -- post variables will need to handled differently)

  
echo "<script language='javascript'>\n";
  echo 
"  location.href=\"${_SERVER['SCRIPT_NAME']}?${_SERVER['QUERY_STRING']}"
            
"&width=\" + screen.width + \"&height=\" + screen.height;\n";
  echo 
"</script>\n";
  exit();
}
?>

User Contributed Notes

Jay 01-Apr-2014 06:25
If you have a really large form, be sure to check your max_input_vars setting.  Your array[] will get truncated if it exceeds this.  http://www.php.net/manual/en/info.configuration.php#ini.max-input-vars
jetboy 30-Dec-2005 04:06
While previous notes stating that square brackets in the name attribute are valid in HTML 4 are correct, according to this:

http://www.w3.org/TR/xhtml1/#C_8

the type of the name attribute has been changed in XHTML 1.0, meaning that square brackets in XHTML's name attribute are not valid.

Regardless, at the time of writing, the W3C's validator doesn't pick this up on a XHTML document.
davis at risingtiger dot net 09-Jan-2004 09:14
I thought this might be useful to fellow PHP heads like myself out there.

I recently came across a need to transfer full fledged mutli-dimensional arrays from PHP to JAVASCRIPT.

So here it is and hopefuly good things come from it.

<?php
function phparray_jscript($array, $jsarray)
{
    function
loop_through($array,$dimen,$localarray)
    {
        foreach(
$array as $key => $value)
        {
            if(
is_array($value))
            {
                echo (
$localarray.$dimen."[\"$key\"] = new Array();\n");
               
loop_through($value,($dimen."[\"".$key."\"]"),$localarray);
            }
            else
            {
                echo (
$localarray.$dimen."[\"$key\"] = \"$value\";\n");
            }
        }
    }

    echo
"<script language=\"Javascript1.1\">\n";
    echo
"var $jsarray = new Array();\n";
   
loop_through($array,"",$jsarray);
    echo
"</script>";
}
?>
martellare at hotmail dot com 15-Mar-2003 09:28
I do not think you are right about not being able to specify something for the value attribute, but I can see where you would have thought it would fail:

A fair warning about testing to see if a variable exists...
when it comes to strings, the values '' and '0' are interpreted as false when tested this way...

<?php
if ($string) { ... }  //false for $string == '' || $string == '0'
?>

The best practice for testing to see if you received a variable from the form (which in the case of a checkbox, only happens when it is checked) is to test using this...

<?php
if ( isSet($string) ) { ... } //true if and only if the variable is set
?>

The function tests to see if the variable has been set, regardless of its contents.

By the way, if anyone's curious, when you do make a checkbox without specifying the value attribute, the value sent from the form for that checkbox becomes 'on'.  (That's for HTML in general, not PHP-specific).
martellare at hotmail dot com 26-Nov-2002 08:25
A JavaScript Note: Using element indexes to reference form elements can cause problems when you want to add new elements to your form; it can shift the indexes of the elements that are already there.

For example, You've got an array of checkboxes that exist at the beginning of a form:
===================

<FORM>
    <INPUT type="checkbox" name="fruits[]" value="apple">apple
    <INPUT type="checkbox" name="fruits[]" value="orange">orange
    <INPUT type="checkbox" name="fruits[]" value="banana">banana
</FORM>

===================
... These elements could be referenced in JavaScript like so:
===================

<SCRIPT language="JavaScript" type="text/javascript">
<!--
    var index = 0; //could be 1 or 2 as well
    alert(document.forms[0].elements[index]);
//-->
</SCRIPT>

===================
However, if you added a new textbox before these elements, the checkboxes indexes become 1 - 3 instead of 0 - 2;  That can mess up what ever code you create depending on those indexes.

Instead, try referencing your html arrays in JavaScript this way.  I know it works in Netscape 4 & IE 6, I hope it to some extent is universal...
===================

<SCRIPT language="JavaScript" type="text/javascript">
<!--
    var message = "";
    for (var i = 0; i < document.forms[0].elements['fruits[]'].length; i++)
    {
        message += "events[" + i + "]: " + document.forms[0].elements['fruits[]'][i].value + "\n";
    }
    alert(message);
//-->
</SCRIPT>

===================