2008年2月11日星期一

PHP 注意事项


  • 页面之间无法传递变量 get,post,session
    php5后自动全局变量是关闭的,所以要从上一页面取得提交过来得变量要使用$_GET['test'], $_POST['test'], $_SESSION['test'] 来得到
    当然也可以修改自动全局变量,将register_globals = On 考虑到安全性和兼容性,最好不要这样操作。


  • Win32下apache2 用get方法传递中文参数会出错
    test.php?a=你好&b=你也好 传递参数是会导致一个内部错误
    解决办法: "test.php?a=" . urlencode('你好') . "&b=" . urlencode('你也好');

  • win32下的session不能正常工作
    php.ini 默认的 session.save_path = /tmp, 这是*nix下的配置,win32下php无法读写session文件导致session无法使用

  • 显示错误信息
    当php.ini的display_errors = On并且error_reporting = E_ALL 时,将显示所有的错误和提示

  • Win32下 mail()不能发送电子邮件
    在*nix下配置好的 sendmail 可以发送,在win32下需要有smtp服务器才可以发送电子邮件
    修改php.ini的
    [bash]
    SMTP = ip //ip是不带验证功能的smtp服务器
    [/bash]
    php发送邮件的最好解决方法是用socket直接发送到对方email服务器而不用转发服务器


  • 初装的mysql如果没有设置密码, 应该使用
    [sql]
    UPDATE mysql.user SET PASSWORD ="yourpassword" WHERE user="root";
    [/sql]

  • header already sent
    这个错误通常会在使用header()的时候出现,可能是几种原因:
    A. 在使用header()前有print 或者echo
    B. 当前文件前面有空行
    C. 可能include了一个文件,该文件尾部有空行或者有输出


  • 更改php.ini后没有变化
    重新启动web server,比如IIS,Apache等等,然后才会应用最新的设置


  • php在2003上面安装
    PHP4的php4isapi.dll好像和2003有些冲突,只能用CGI模式安装

  • isset()和empty()的区别
    两者都是测试变量,但是isset()是测试变量是否被赋值,而empty()是测试一个已经被赋值的变量是否为空
    如果一个变量没被赋值就引用在php里是被允许的,但会有notice提示
    如果一个变量被赋空值,$foo=""或者$foo=0或者 $foo=false,那么empty($foo)返回真,isset($foo)也返回真,就是说赋空值不会注销一个变量。
    要注销一个变量,可以用 unset($foo)或者$foo=NULL

  • mysql查询语句包含有关键字
    php查询mysql的时候,有时候mysql表名或者列名会有关键字
    这时候查询会有错误。例如表名是order,查询时候会出错
    简单的办法是sql语句里表名或者列名加上`[tab键上面]来加以区别, 例如 SELECT * FROM `order`

  • 通过HTTP协议一次上传文件
    form 需要 enctype="multipart/form-data" 这个属性



include,require,include_once,require_once的区别
A. include()函数会将指定的档案读入并且执行里面的程序。
被导入的档案中的程序代码都会被执行,而且这些程序在执行的时候会拥有和源文件中呼叫到include()函数的位置相同的变量范围 (variable scope) 。你可以导入同一个服务器中的静态档案,甚至可以通过合并使用include()与fopen()函数来导入其它服务器上面的档案。

B. include_once()函数的作用和include()是几乎相同的
唯一的差别在于include_once()函数会先检查要导入的档案是不是已经在该程序中的其它地方被导入过了,如果有的话就不会再次重复导入该档案 (这项功能有时候是很重要的,比方说要导入的档案里面宣告了一些你自行定义好的函数,那么如果在同一个程序重复导入这个档案,在第二次导入的时候便会发生错误讯息,因为PHP不允许相同名称的函数被重复定义) 。

C. require()函数会将目标档案的内容读入,并且把自己本身代换成这些读入的内容。
这个读入并且代换的动作是在PHP引擎编译你的程序代码的时候发生的,而不是发生在PHP引擎开始执行编译好的程序代码的时候 (PHP 3.0引擎的工作方式是编译一行执行一行,但是到了PHP 4.0就有所改变了,PHP 4.0是先把整个程序代码全部编译完成后,再将这些编译好的程序代码一次执行完毕,在编译的过程中不会执行任何程序代码) 。require()通常来导入静态的内容,而include()则适合用来导入动态的程序代码。

D. 如同include_once()函数,require_once()函数会先检查目标档案的内容是不是在之前就已经导入过了,如果是的话,便不会再次重复导入同样的内容。
如果要包含的文件不存在,include提示notice,然后继续执行下面的语句,require提示致命错误并且退出

E. 对include()来说,在include()执行时文件每次都要进行读取和评估;而对于require()来说,文件只处理一次 (实际上,文件内容替换了require()语句) 。

F. include(), The include() 语句包括并运行指定文件。
以下文档也适用于 require()。这两种结构除了在如何处理失败之外完全一样。include() 产生一个警告而 require() 则导致一个致命错误。换句话说,如果你想在遇到丢失文件时停止处理页面就用 require()。include() 就不是这样,脚本会继续运行。同时也要确认设置了合适的 include_path。

当一个文件被包括时,其中所包含的代码继承了 include 所在行的变量范围。从该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。
[php title="基本的 include() 例子 vars.php"]

$color = 'green';
$fruit = 'apple';

[/php]

[php title="test.php"]
echo "A $color $fruit"; // A
include 'vars.php';
echo "A $color $fruit"; // A green apple
[/php]

如果 include 出现于调用文件中的一个函数里,则被调用的文件中所包含的所有代码将表现得如同它们是在该函数内部定义的一样。所以它将遵循该函数的变量范围。
[php title="函数中的包括"]
function foo() {
global $color;
include 'vars.php';
echo "A $color $fruit";
}

/* vars.php 是在foo()函数中被include, 所以$fruit 在foo()函数外它是不可用的,
* 而$color已被定义为全局变量,所以它是可用的
*/

foo(); // A green apple
echo "A $color $fruit"; // A green
[/php]
当一个文件被包括时,语法解析器在目标文件的开头脱离 PHP 模式并进入 HTML 模式,到文件结尾处恢复。由于此原因,目标文件中应被当作 PHP 代码执行的任何代码都必须被包括在有效的 PHP 起始和结束标记之中。

如果 "URL fopen wrappers" 在 PHP 中被激活 (默认配置) ,可以用 URL (通过 HTTP) 而不是本地文件来指定要被包括的文件。如果目标服务器将目标文件作为 PHP 代码解释,则可以用适用于 HTTP GET 的 URL 请求字符串来向被包括的文件传递变量。严格的说这和包括一个文件并继承父文件的变量空间并不是一回事;该脚本文件实际上已经在远程服务器上运行了,而本地脚本则包括了其结果。

Notice:Windows 版本的 PHP 目前还不支持该函数的远程文件访问,即使 allow_url_fopen 选项已被激活。
[php title="通过 HTTP 进行的 include()"]
/* This example assumes that www.example.com is configured to parse .php *
* files and not .txt files. Also, 'Works' here means that the variables *
* $foo and $bar are available within the included file. */

/*Won't work; file.txt wasn't handled by www.example.com as PHP include
'http://www.example.com/file.txt?foo=1&bar=2';
*/

// Won't work; looks for a file named 'file.php?foo=1&bar=2' on the
// local filesystem.
include 'file.php?foo=1&bar=2';

// Works.
include 'http://www.example.com/file.php?foo=1&bar=2';

$foo = 1;
$bar = 2;
include 'file.txt'; // Works.
include 'file.php'; // Works.
[/php]

相关信息参见使用远程文件,fopen() 和 file()。
因为 include() 和 require() 是特殊的语言结构,在条件语句中使用必须将其放在语句组中 (花括号中) 。
[php language="title="与条件语句组"]
// This is WRONG and will not work as desired.
if ($condition)
include $file;
else
include $other;


// This is CORRECT.
if ($condition) {
include $file;
} else {
include $other;
}
[/php]

处理返回值:可以在被包括的文件中使用 return() 语句来终止该文件中程序的执行并返回调用它的脚本。同样也可以从被包括的文件中返回值。可以像普通函数一样获得 include 呼叫的返回值。

注: 在 PHP 3 中,除非是在函数中调用否则被包括的文件中不能出现 return。在此情况下 return() 作用于该函数而不是整个文件。
[php title="include() 和 return() 语句 return.php"]
$var = 'PHP';
return $var;
[/php]
[php title="noreturn.php"]
$var = 'PHP';
[/php]
[php title="testreturns.php"]
$foo = include 'return.php';
echo $foo; // prints 'PHP'
$bar = include 'noreturn.php';
echo $bar; // prints 1
[/php]

$bar 的值为 1 是因为 include 成功运行了。注意以上例子中的区别。第一个在被包括的文件中用了 return() 而另一个没有。其它几种把文件 包括 到变量的方法是用 fopen(),file() 或者 include() 连同输出控制函数一起使用。

如果一个文件不想被包含多次可以使用include_once或require_once读取,写入文档数据
[php]
function r($file_name) {
$filenum = @fopen($file_name, "r");
@flock($filenum, LOCK_SH);
$file_data = @fread($filenum, filesize($file_name));
@fclose($filenum);
return $file_data;
}
function w($file_name, $data, $method = "w"){
$filenum = @fopen($file_name, $method);
flock($filenum, LOCK_EX);
$file_data = fwrite($filenum, $data);
fclose($filenum);
return $file_data;
[/php]

没有评论 :

发表评论