分类 "PHP" 下的文章

1. 一般的文件上传,除非文件很小.就像一个5M的文件,很可能要超过一分钟才能上传完.
但在php中,默认的该页最久执行时间为 30 秒.就是说超过30秒,该脚本就停止执行.
这就导致出现 无法打开网页的情况.这时我们可以修改 max_execution_time
在php.ini里查找:
max_execution_time

默认是30秒.改为:
max_execution_time = 0
0表示没有限制

2. 修改 post_max_size 设定 POST 数据所允许的最大大小。此设定也影响到文件上传。
php默认的post_max_size 为2M.如果 POST 数据尺寸大于 post_max_size $_POST 和 $_FILES superglobals 便会为空.
查找:
post_max_size

修改为:
post_max_size = 150M

3. 很多人都会改了第二步.但上传文件时最大仍然为 8M.
为什么呢.我们还要改一个参数upload_max_filesize 表示所上传的文件的最大大小。
查找:
upload_max_filesize

默认为8M,修改为:
upload_max_filesize = 100M

另外要说明的是,post_max_size 大于 upload_max_filesize 为佳.

在用foreach的时候,经常会有这样的Warning: Invalid argument supplied for foreach() in XXXxxx.php on line 172

foreach仅能用于数组,当试图将其用于其它数据类型或者一个未初始化的变量时会产生错误。 所以当foreach 里面的数组变量假为空并且不定义为数组的时候,就会产生以上报错的情况。

有两种办法解决:
第一是在赋值数组的时候先定义array:

$aa =array();
foreach($aa as $key=>$value){}

第二种方法:

foreach((array) $aa as $key=>$value)

首页index.php代码:

<?php ob_start();?>
<?php
if(file_exists("index.html")){ // 看静态index.htm文件是否存在
$time1 = time();
$time2 = filemtime("index.html");
//echo($time1-$time2);
// 文件修改时间和现在时间相差?的话,直接导向html文件,否则重新生成html
if(($time1 - $time2) < 600)
header("Location:index.html");
}
?>

代码二:

<html>
<body>

<h1>It works!</h1>

</body>
</html>

代码三:

<?php
//首页内容,就是你的动态部分了
//在结尾加入ob_end_clean(),并把本页输出到一个变量中
$temp=ob_get_contents();
ob_end_clean();
//写入文件
$fp=fopen("index.html",'w');
fwrite($fp,$temp) or die('写文件错误');
//初始显示
echo($temp);
?>

电影《社交网络》中,facebook创始人马克.扎克失恋后入侵哈佛大学宿舍楼服务器,窃取数据库资料,并在两个小时内完成了一个给校内女生评分的交互网站,该网站一天内点击数过10W,直接导致学校服务器崩溃。。。。。。
其实,构建那样一个网站并不需要很多高深的技术,任何一个有一定网络编程基础的人都可以做到。马克构建网站所用的是Apache服务器和PHP服务器脚本语言,我曾经用三天时间学习PHP,然后用了两个星期为学校写了一个网站,可见PHP是很简单的,而facebook后台也是用php写的,当然,大家现在看到的我的wordpress博客后台也是php~~。

话说回来,很多人可能已经用上ubuntu了,大家可能花了大量时间在ubuntu的美化上,这无可厚非,但是,ubuntu应该给我们的工作和学习带来更多的便利和方便。ubuntu作为linux,为我们提供了强大的网络方面的功能,其中的服务器技术尤其强大,安全。如果不学习linux的网络技术,很难说自己掌握了linux。

今天,我在ubuntu下配置了一个Apache服务器。通过Apache我们可以学习php网络编程,可以用它来部署自己本地的wordpress博客,从而进一步通过网络和朋友交流。从此,你将深刻体会到网络带个我们的神奇力量,至少我是这样觉得的~~

步骤一、安装apache2

sudo apt-get install apache2

安装完成。

运行如下命令重启下:

sudo /etc/init.d/apache2 restart

在浏览器里输入http://localhost或者是http://127.0.0.1,如果看到了It works!,那就说明Apache就成功的安装了,Apache的默认安装,会在/var下建立一个名为www的目录,这个就是Web目录了,所有要能过浏览器访问的Web文件都要放到这个目录里。

步骤二、安装php

sudo apt-get install libapache2-mod-php5 php5 php5-curl php5-dev php5-gd php5-gmp php5-imap php5-ldap php5-mcrypt

此外,建议安装扩展php5-gd php5-mysql,安装方式同上.

安装完后,我们要重新启动Apache,让它加载PHP模块:

sudo /etc/init.d/apache2 restart

接下来,我们就在Web目录下面新建一个test.php文件来测试PHP是否能正常的运行,命令:

sudo gedit /var/www/test.php

然后输入:

<?php
echo phpinfo();
?>

接着保存文件,在浏览器里输入http://127.0.0.1/test.php,如果在网页中显示hello,world!!,那就说明PHP已经正常运行了。

步骤三、安装mysql数据库:

sudo apt-get install mysql-server mysql-client

apt-get程序会自动下载安装最新的mysql版本。在安装的最后,它会要求里输入root的密码,注意,这里的root密码可不是Ubuntu的root密码啊,是你要给MySQL设定的root密码。

步骤四、安装phpmyadmin-Mysql数据库管理

sudo apt-get install phpmyadmin

phpmyadmin设置:

在安装过程中会要求选择Web server:apache2或lighttpd,使用空格键选定apache2,按tab键然后确定。然后会要求输入设置的Mysql数据库密码连接密码Password of the database’s administrative user。

然后将phpmyadmin与apache2建立连接,以我的为例:www目录在/var/www,phpmyadmin在/usr/share /phpmyadmin目录,所以就用命令:

sudo ln -s /usr/share/phpmyadmin /var/www

建立链接。

phpmyadmin测试:在浏览器地址栏中打开http://localhost/phpmyadmin。

以上ALMP的基本组件就安装完毕了,下面我们再来看一些其他的设置:

步骤五、设置Ubuntu文件执行读写权限

LAMP组建安装好之后,PHP网络服务器根目录默认设置是在:/var/www。由于Linux系统的安全性原则,改目录下的文件读写权限是只允许root用户操作的,所以我们不能在www文件夹中新建php文件,也不能修改和删除,必须要先修改/var/www目录的读写权限。在界面管理器中通过右键属性不能修改文件权限,得执行root终端命令:

sudo chmod 777 /var/www

然后就可以写入html或php文件了。777是linux中的最高权限,表示可读,可写,可执行。

sudo apt-get install apache2 libapache2-mod-php5 php5 php5-curl php5-dev php5-gd php5-gmp php5-imap php5-ldap php5-mcrypt mysql-server mysql-client phpmyadmin

你有没有查看过全部PHP的方法,我大概统计了一下,在PHP参考中一共有5025个。如果你初学这种web编程语言,那么我将介绍几个非常实用的PHP方法,希望能够对你有帮助!
20131031151725_01

方法一:array_rand

首先我们介绍这个简单的方法array_rand。
是不是想从一个数组中随机取出一个来?你可以使用rand或者mt_rand来得到一个随机的数,传递0和最后一个index值作为数组的最小和最大参数,这将会给你一个随机的key你可以用来得到数组的值。
当然这里有更方便的方法来实现上述功能:array_rand,只需要传递一个数组,会自动给你返回一个随机key。如下:

$sites = ["gbin1.com", "gbtags.com", "baidu.com", "google.com"];
$k = array_rand($sites);
$sites[$k];

如果你需要的不仅仅是一个一个随机数值的话,你还可以传递第二个参数来设置返回的数值数量,这样你就可以得到一个随机的数组。

方法二:strip_tags

我们常常会从客户端得到大段的文字内容:可能是留言或者是一个个人介绍。当然你可能不希望其中夹杂任何的HTML标签。如果你希望去除html,那么可以使用strip_tags:

$message = "<div> This is www.piaoyun.org </div>";
echo strip_tags($message); //返回 "This is www.piaoyun.cc"

当然,可能你希望允许出现某些标签,例如<b>,<strong>等,可以传递 第二个参数如下:

$message = "<div> This is <strong>www.piaoyun.cc</strong></div>";
echo strip_tags($message, "<strong><em><code>"); // "This is <strong>www.piaoyun.cc</strong>"

方法三:strftime

日期是web程序中我们需要常常处理的对象,你如何将日期输出为你需要的格式呢?得到timestamp很简单,但是如何得到格式呢?使用strftime方法可以快速的帮助你得到你需要的格式,只需要传递格式字符串和timestamp,如下:

strftime("%B %d, %Y", time()); // July 28, 2012

当然,如果你记不住所有的日期格式 ,可以使用这个方便的 strfti.me 地址来查询。

方法四:basename

当我们需要处理文件,你可以需要知道它的绝对路径。但是,如果你需要给用户显示文件信息,你可能需要显示文件名,不是整个路径。使用basename这个方法可以帮助你找出路径对应文件名,或者文件后缀,如下:

$path = "/some/long/path/to/the/piaoyun.html";
$filename1 = basename($path); // piaoyun.html
$filename2 = basename($path, ".html"); // piaoyun

方法五:list

这个方法超棒,打比方说你有一个数组,你想将数组内容赋予到变量中,使用这个方法将会超简单:

$array = ["piaoyun", "gbtags"];
list($first_website, $last_website) = $array;

echo $first_website; // piaoyun
echo $last_website; // gbtags

你可以看到,我们只传递了一个变量名参数到list方法,然后设置为数组。和一般的语法有些区别,因为方法在左边被调用,但是,的确可以工作。这里PHP文档有个非常好的例子:

$data = "foo:*:1023:1000::/home/foo:/bin/sh";
list($user, $pass, $uid, $gid, $gecos, $home, $shell) = explode(":", $data);

方法六:range

如果你需要列举一个数组,那你需要看看range方法。只需要传入一个开始和结束值,它会返回一个数字数组:

range(0, 10); // array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
range('a', 'f'); // array('a', 'b', 'c', 'd', 'e'. 'f');

可以看到包含了边界数字,即你提供的开始和结束值。你也可以指定只返回他们中间的数字:

range(2, 10, 2); // array(2, 4, 6, 8, 10);

方法七:isset

这个实用的方法可以用检测一个变量是否已经被设置。你传递一个变量名,如果变量存或者已经被设置为非null的数值则在将会返回true。

$name = "www.piaoyun.cc";
isset($name); // true
isset($age); // false

因为这个方法同时也可以处理数组,所以可以用来检查全局数组$_GET和$_POST中指定的key是否存在。如下:

if(isset($_GET['query'])) {
// get results and display them
} else {
// show some default content
}

这里大家学习了7个非常实用的PHP方法,如果你是PHP初学者,你可以阅读相关的PHP书籍,如果你也有自己喜欢的实用PHP方法,请你给我们留言!谢谢阅读!

很多PHP程序员调试使用echo、print_r()、var_dump()、printf()等,虽然对于有较丰富开发经验的程序员来说这些也已经足 够了,他们往往可以在程序执行的过程中,通过输出特定变量的值可以判断程序执行是否正确,甚至效率高低也可以看出来(当然可能还需要使用一些时间函数)。 那么我们为什么还需要一个专门的调试程序来监控我们的程序运行呢?

在我们平时的php开发中,一个大的项目经过长时间的积累以后你会发现性能越来越慢,而性能到底消耗在了什么地方,常常是一个令人头疼的问 题,function a()调用了多少次,function b()又消耗了多少时间,我们到底怎么查找是哪个蛀虫拉慢了我们的程序运行速度呢?在这里给大家介绍一款工具xdebug,相信很多人已经听说过了,希望 借助这个工具我们可以起到简单分析php程序性能瓶颈的问题。

XDebug是什么

XDebug是一个开放源代码的PHP程序调试器(即一个Debug工具),可以用来跟踪,调试和分析PHP程序的运行状况。

安装XDebug

访问http://www.xdebug.org,下载php_xdebug.dll,根据版本号与自己的操作系统、PHP版本下载合适的。

将下载的php_xdebug.dll放到PHP的安装目录php\ext下。
编辑php.ini,有些集合环境已自带xdebug的配置,如果没有则自己手动加入下面几行:

[xdebug]
zend_extension = "/home/ad/php/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so"
xdebug.auto_trace = on
xdebug.auto_profile = on
xdebug.collect_params = on
xdebug.collect_return = on
xdebug.profiler_enable = on
xdebug.trace_output_dir = "/home/ad/xdebug_log"
xdebug.profiler_output_dir = "/home/ad/xdebug_log"
XDebug参数简介:
zend_extension 加载xdebug扩展
xdebug.auto_trace 自动打开打开函数调用监测
xdebug.auto_profile 自动打开性能监测
xdebug.trace_output_dir 设定函数调用监测信息的输出文件的路径。
xdebug.profiler_output_dir 设定效能监测信息输出文件的路径。
xdebug.collect_params 打开收集“函数参数”的功能。将函数调用的参数值列入函数过程调用的监测信息中。
xdebug.collect_return 打开收集“函数返回值”的功能。将函数的返回值列入函数过程调用的监测信息中。

重启Apache。

写一个test.php,内容为<?php phpinfo(); ?>,如果输出的内容中有看到xdebug,说明安装配置成功。或者去/home/ad/xdebug_log下看看是不是日志已经出来了。

设置选项
CategorySettingDescription

日志
xdebug.trace_output_dir
日志追踪输出目录xdebug.trace_output_name日志文件名,xdebug提供了一系列的标识符,生成相应格式的文件名,具体请参考官网xdebug.trace_options记录添加到文件中方式:1 = 追加(如果存在该文件). 0 (default) = 覆盖(如果存在该文件)显示数据 xdebug.collect_params非零值 = 控制function的参数显示选项

0 = 不显示.
1 = 参数类型,值 (例如:array(9)).
2 = 同上1,只是在CLI模式下略微有区别
3 = 所有变量内容
4 = 所有变量内容和变量名(例如:array(0 => 9)).

xdebug.collect_return1 = 显示function返回值. Default 0 不显示xdebug.collect_vars1 = 显示当前作用域使用了哪些变量,显示变量名,该选项不会记录变量的值,如果需要,使用xdebug.collect_params xdebug.collect_assignments1 = 添加一行显示变量赋值(若为1,形如$a = 1;这类Assignment Expression会在trace文件里显示)格式 xdebug.trace_format

0 = 人可读. 从左至右每列分别表示:时间点, 内存, 内存差 (需要设置xdebug.show_mem_delta=1), 等级, 函数名,函数参数 (需要设置,xdebug.collect_params=1,只要是非零), 当前代码行所在文件名 , 行号.
1 = 机器可读[1]. 需要借助第三方app,例如:xdebug trace file parser 或者 xdebug trace viewer
2 = html格式 即table,用browser打开,显示table

xdebug.show_mem_delta1 = 显示每次函数调用内存消耗(内存差)行为 xdebug.auto_trace1 = 打开自动追踪. (追踪方式有2种,一种是自动追踪,所有php脚本运行时,都会产生trace文件;另一种是触发方式追踪,如 下)xdebug.trace_enable_trigger[2]

1 = 使用 XDEBUG_TRACE GET/POST 触发追踪, 或者通过设置cookie XDEBUG_TRACE. 为了避免每次请求时,都会生成相应trace追踪文件,你需要把auto_trace设置为0

注:该特性只在2.2+版本才能设置

[xdebug-general] Re: Is trace_enable_trigger defunct?
限制xdebug.var_display_max_depth数组和对象元素显示深度:主要用在数组嵌套,对象属性嵌套时,显示几级的元素内容. Default 3.xdebug.var_display_max_data变量值为字符串时显示多长. Default 512.xdebug.var_display_max_children数组和对象元素显示的个数. Default 128

一些自定义函数
FunctionDescriptionvoid xdebug_enable()手动打开,相当于xdebug.default_enable=onvoid var_dump()覆写php提供的var_dump,出错时,显示函数堆栈信息,(前提:php.ini里html_errors为1),使用 xdebug.overload_var_dump 设置是否覆写void xdebug_start_trace(

string trace_file_path
[, integer options] )手动控制需要追踪的代码段
trace_file_path :文件路径(相对或绝对,若为空).如果为空,或者不传参, 使用xdebug.trace_output_dir设置的目录

options :
XDEBUG_TRACE_APPEND: 1 = 追加文件内容末尾, 0 = 覆写该文件
XDEBUG_TRACE_COMPUTERIZED:
2 =同 xdebug.trace_format=1 .

XDEBUG_TRACE_HTML: 4 = 输出HTML表格,浏览器打开为一table
void xdebug_stop_trace()停止追踪,代码追踪在该行停止string xdebug_get_tracefile_name()获得输出文件名,与 xdebug.auto_trace配合使用.void xdebug_var_dump([mixed var[,...]]) 输出变量详细信息,相当于php里的var_dump,具体显示请看 这里 xdebug.show_local_vars 默认为0,不显示;非零时,在php执行出错时,显示出错代码所在作用域所有本地变量(注:这会产生大量信息,因此默认是closed),具体显示差别如 下图[3]array xdebug_get_declared_vars()显示当前作用域中已声明的变量array xdebug_get_code_coverage()显示某一段代码内,代码执行到哪些行[4]

关于xdebug.trace_format=1,如果你使用触发方式启用代码追踪:(xdebug.auto_trace = 0;xdebug.trace_enable_trigger = 1),那么,你可以在URL里添加XDEBUG_TRACE,例如:localhost/test.php?XDEBUG_TRACE,或者 localhost//test.php?XDEBUG_TRACE=1(任意值)。

是不是觉得很麻烦,那么装个插件,让它来帮你。Chrome XDEBUG Helper,使用它,你可以切换3种状态,disabled ,debugging enabled,profiling enabled(下篇详细介绍),然后切换到debugging enabled。运行该脚本,(去掉URL里的?XDEBUG_TRACE),就可以代码跟踪了。

使用xdebug_start_trace()和xdebug_stop_trace()可以手动追踪你的代码执行情况。

xdebug_start_trace();
//your code required to trace
xdebug_stop_trace();

设定 xdebug.auto_trace = 1 将在执行所有 PHP 脚本之前先启用自动跟踪。另外,您可以通过代码设定 xdebug.auto_trace = 0,并分别使用 xdebug_start_trace() 和 xdebug_stop_trace() 函数启用和禁用跟踪。但是,如果 xdebug.auto_trace 为 1,则可以在包括配置好的 auto_prepend_file 之前先启动跟踪。

选项 xdebug.trace_ouput_dir 和 xdebug.trace_output_name 用于控制保存跟踪输出的位置。在这里,所有文件都被保存到 /tmp/traces 中,并且每个跟踪文件都以 trace 为开头,后接 PHP 脚本的名称(%s)以及进程 ID(%p)。所有 Xdebug 跟踪文件都以 .xt 后缀结尾。

默认情况下,XDebug 将显示时间、内存使用量、函数名和函数调用深度字段。如果将 xdebug.trace_format 设为 0,则输出将符合人类阅读习惯(将参数设为 1 则为机器可读格式)。此外,如果指定 xdebug.show_mem_delta = 1,则可以查看内存使用量是在增加还是在减少,而如果指定 xdebug.collect_params = 4,则可以查看传入参数的类型和值。要监视每个函数返回的值,请设定 xdebug.collect_return = 1。

今天改过服务器的php.ini文件后,发现所有的页面都不能访问,显示为:“No input file specified.”
由于要同时支持.NET,服务器采用的是IIS。我改用Apache就没有这个问题。
这个问题很让人头疼。google了一阵之后没有找到好的方法。大都是说因为CGI的安全认证问题,而使用ISAPI模块方式安装PHP则没有这个问题。可是我恰恰就是用ISAPI模块方式安装的,为什么还有这个问题?

于是把ISAPI删除,改成CGI模式安装PHP,然后修改PHP.ini文件中的cgi.force_redirect值为0,重启IIS。错误依旧。
到现在,我大致已经知道出现这个错误可能是因为没有找到PHP ISAPI模块的DLL文件,但是我配置的所有路径都正确呀!
接着试验。禁用IIS6中的php扩展,此时访问网站出现404错误。为什么会出现404错误?这是没有找到网页文件的错误呀!看来可能是配置问题了。

想起来刚才改过PHP.ini中的doc_root行,打开ini文件注释掉此行,然后重启IIS,一切正常了。

; doc_root =

其实,在虚拟主机中配置php.ini中的doc_root,实际上没有什么意义,因为提供虚拟主机的IIS,一般都不会有实际的doc_root,而是每个虚拟主机一个root。我煞费苦心的跑去设置doc_root,实在是多此一举,浪费表情。

'ez' => 'application/andrew-inset',
'hqx' => 'application/mac-binhex40',
'cpt' => 'application/mac-compactpro',
'doc' => 'application/msword',
'bin' => 'application/octet-stream',
'dms' => 'application/octet-stream',
'lha' => 'application/octet-stream',
'lzh' => 'application/octet-stream',
'exe' => 'application/octet-stream',
'class' => 'application/octet-stream',
'so' => 'application/octet-stream',
'dll' => 'application/octet-stream',
'oda' => 'application/oda',
'pdf' => 'application/pdf',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
'smi' => 'application/smil',
'smil' => 'application/smil',
'mif' => 'application/vnd.mif',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
'wbxml' => 'application/vnd.wap.wbxml',
'wmlc' => 'application/vnd.wap.wmlc',
'wmlsc' => 'application/vnd.wap.wmlscriptc',
'bcpio' => 'application/x-bcpio',
'vcd' => 'application/x-cdlink',
'pgn' => 'application/x-chess-pgn',
'cpio' => 'application/x-cpio',
'csh' => 'application/x-csh',
'dcr' => 'application/x-director',
'dir' => 'application/x-director',
'dxr' => 'application/x-director',
'dvi' => 'application/x-dvi',
'spl' => 'application/x-futuresplash',
'gtar' => 'application/x-gtar',
'hdf' => 'application/x-hdf',
'js' => 'application/x-javascript',
'skp' => 'application/x-koan',
'skd' => 'application/x-koan',
'skt' => 'application/x-koan',
'skm' => 'application/x-koan',
'latex' => 'application/x-latex',
'nc' => 'application/x-netcdf',
'cdf' => 'application/x-netcdf',
'sh' => 'application/x-sh',
'shar' => 'application/x-shar',
'swf' => 'application/x-shockwave-flash',
'sit' => 'application/x-stuffit',
'sv4cpio' => 'application/x-sv4cpio',
'sv4crc' => 'application/x-sv4crc',
'tar' => 'application/x-tar',
'tcl' => 'application/x-tcl',
'tex' => 'application/x-tex',
'texinfo' => 'application/x-texinfo',
'texi' => 'application/x-texinfo',
't' => 'application/x-troff',
'tr' => 'application/x-troff',
'roff' => 'application/x-troff',
'man' => 'application/x-troff-man',
'me' => 'application/x-troff-me',
'ms' => 'application/x-troff-ms',
'ustar' => 'application/x-ustar',
'src' => 'application/x-wais-source',
'xhtml' => 'application/xhtml+xml',
'xht' => 'application/xhtml+xml',
'zip' => 'application/zip',
'au' => 'audio/basic',
'snd' => 'audio/basic',
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'kar' => 'audio/midi',
'mpga' => 'audio/mpeg',
'mp2' => 'audio/mpeg',
'mp3' => 'audio/mpeg',
'aif' => 'audio/x-aiff',
'aiff' => 'audio/x-aiff',
'aifc' => 'audio/x-aiff',
'm3u' => 'audio/x-mpegurl',
'ram' => 'audio/x-pn-realaudio',
'rm' => 'audio/x-pn-realaudio',
'rpm' => 'audio/x-pn-realaudio-plugin',
'ra' => 'audio/x-realaudio',
'wav' => 'audio/x-wav',
'pdb' => 'chemical/x-pdb',
'xyz' => 'chemical/x-xyz',
'bmp' => 'image/bmp',
'gif' => 'image/gif',
'ief' => 'image/ief',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'jpe' => 'image/jpeg',
'png' => 'image/png',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'djvu' => 'image/vnd.djvu',
'djv' => 'image/vnd.djvu',
'wbmp' => 'image/vnd.wap.wbmp',
'ras' => 'image/x-cmu-raster',
'pnm' => 'image/x-portable-anymap',
'pbm' => 'image/x-portable-bitmap',
'pgm' => 'image/x-portable-graymap',
'ppm' => 'image/x-portable-pixmap',
'rgb' => 'image/x-rgb',
'xbm' => 'image/x-xbitmap',
'xpm' => 'image/x-xpixmap',
'xwd' => 'image/x-xwindowdump',
'igs' => 'model/iges',
'iges' => 'model/iges',
'msh' => 'model/mesh',
'mesh' => 'model/mesh',
'silo' => 'model/mesh',
'wrl' => 'model/vrml',
'vrml' => 'model/vrml',
'css' => 'text/css',
'html' => 'text/html',
'htm' => 'text/html',
'asc' => 'text/plain',
'txt' => 'text/plain',
'rtx' => 'text/richtext',
'rtf' => 'text/rtf',
'sgml' => 'text/sgml',
'sgm' => 'text/sgml',
'tsv' => 'text/tab-separated-values',
'wml' => 'text/vnd.wap.wml',
'wmls' => 'text/vnd.wap.wmlscript',
'etx' => 'text/x-setext',
'xsl' => 'text/xml',
'xml' => 'text/xml',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpe' => 'video/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
'mxu' => 'video/vnd.mpegurl',
'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie',
'ice' => 'x-conference/x-cooltalk',

 

1.使用MyISAM而不是InnoDB

MySQL有很多的数据库引擎,单一般也就用MyISAM和InnoDB。
MyISAM 是默认使用的。但是除非你是建立一个非常简单的数据库或者只是实验性的,那么到大多数时候这个选择是错误的。MyISAM不支持外键的约束,这是保证数据 完整性的精华所在啊。另外,MyISAM会在添加或者更新数据的时候将整个表锁住,这在以后的扩展性能上会有很大的问题。
解决办法很简单:使用InnoDB。
完全错误,反驳理由:
首先原文说MyISAM是默认使用的,而实际上到了MySQL 5.5.x,InnoDB已经成为了默认的表引擎。
另外,简单的使用InnoDB不是解决所有问题的方法,盲目的使用甚至会使应用性能下降10%乃至40%。
最佳方法还是针对具体业务具体处理,例如论坛中版块表,新闻分类表,各种码表等长时间不操作的表,还是要用性能优异的MyISAM引擎。
而需要用到事务处理的例如用户、账目、流水等严格要求数据完整性和时序性的,则需要用InnoDB引擎,并且应用也要用好事务处理机制。当然,事务处理必然要带来大量的性能损耗,但是这在简单高并发应用上是必须的。
最后,外键约束在公共web互联网应用上一般是不用的,因为他会严重影响性能。数据完整性还是靠程序员或者应用架构本身的健壮来维护。而正规的第三范式只是在企业内部MIS系统和12306这种网站上使用。

2.使用PHP的mysql方法

PHP从一开始就提供了MySQL的函数库。很多程序都依赖于mysql_connect、mysql_query、mysql_fetch_assoc等等,但是PHP手册中建议:
如果你使用的MySQL版本在4.1.3之后,那么强烈建议使用mysqli扩展。
mysqli,或者说MySQL的高级扩展,有一些优点:
有面向对象的接口
prepared statements(预处理语句,可以有效防止SQL-注入攻击,还能提高性能)
支持多种语句和事务
另外,如果你想支持多数据库那么应该考虑一下PDO。
不完全错,但要酌情选用:
mysqli固然好,但是不是所有的服务器都为PHP编译了mysqli的支持。
当你的应用如果是能确定只用自己部署的服务器,而应用也是完全自己开发,则mysqli是最好的选择。
但是一旦你的应用有可能部署在虚拟主机或者由其他人部署(例如分布式项目),还是老老实实使用mysql函数集吧,好好封装一下或者使用成熟框架杜绝sql注入。

3.不过滤用户输入

应该是:永远别相信用户的输入。用后端的PHP来校验过滤每一条输入的信息,不要相信Javascript。像下面这样的SQL语句很容易就会被攻击:
$username = $_POST["name"];
$password = $_POST["password"];
$sql = "SELECT userid FROM usertable WHERE username=?$username?AND password=?$password?;"; // run query...
这样的代码,如果用户输入”admin’;”那么,就相当于下面这条了:
SELECT userid FROM usertable WHERE username=?admin?;
这样入侵者就能不输入密码,就通过admin身份登录了。

这一点不用说了,要么MagicQuote,要么选用成熟框架。sql注入老话题了。

4.不使用UTF-8

那些英美国家的用户,很少考虑语言的问题,这样就造成很多产品就不能在其他地方通用。还有一些GBK编码的,也会有很多的麻烦。
UTF-8解决了很多国际化的问题。虽然PHP6才能比较完美的解决这个问题,但是也不妨碍你将MySQL的字符集设置为UTF-8。

大部分情况下对,但也要认真考虑:
要知道,一个UTF-8字符占3个字节,所以比GBK等其他编码的文件大33%。换句话说,相同的网页用UTF-8编码如果是100KB,那么换成GBK 编码则只有66KB。所以即便你的PHP确定要用UTF-8,那么前端页面也要根据情况选择需要的编码。但是,如果PHP用UTF-8,前端模版是 GBK,再加上模版引擎不强大,那么转码工作够你受的。所以尽可能的选用自己需要的编码,而不是简单的选择UTF-8了事。
最后啰嗦一句:UTF-8下:strlen("我")=3,而GBK下:strlen("我")=2

5.该用SQL的地方使用PHP

如果你刚接触MySQL,有时候解决问题的时候可能会先考虑使用你熟悉的语言来解决。这样就可能造成一些浪费和性能比较差的情况。比如:计算平均值的时候不适用MySQL原生的AVG()方法,而是用PHP将所有值循环一遍然后累加计算平均值。
另外还要注意SQL查询中的PHP循环。通常,在取得所有结果之后再用PHP来循环的效率更高。
一般在处理大量数据的时候使用强有力的数据库方法,更能提高效率。

同样酌情考虑:
例如,有些人习惯在建表时,默认值填写CURRENT_TIMESTAMP,用来达到注册时间、发帖时间的效果。 或者在时间判断的SQL语句中,写类似SELECT x FROM tab1 WHERE regdate < UNIX_TIMESTAMP()。那么我只能说,你为系统埋下了很隐蔽的BUG。因为数据库和应用往往不在同一台机器上,时间很容易出现偏差。当你一套 应用的时间参照不准确时,就会出现很大的问题。
正确做法是:不要使用MySQL的任何时间函数,而是在应用里计算时间。如果是分布式应用,一定要有时间服务器来统一管理时间。
而文中说的一些MySQL数学函数 ,也是要慎用。因为在大型应用中,数据库的负担往往是最大的,而复杂的WHERE语句又是造成慢查询的元凶。所以,要把计算尽可能的放在廉价的、不影响全局稳定的应用服务器上,而不是核心数据库上。

6.不优化查询

99%的PHP性能问题都是数据库造成的,一条糟糕的SQL语句可能让你的整个程序都非常慢。MySQL的EXPLAIN statement,Query Profiler,many other tools的这些工具可以帮你找出那些调皮的SELECT。

这点也不用说了,大型应用上甚至不允许使用各种JOIN,哪怕生写两条查询,查回来在用PHP合并数据。

7.使用错误的数据类型

MySQL提供一系列数字、字符串、时间等的数据类型。如果你想存储日期,那么就是用DATE或者DATETIME类型,使用整形或者字符串会让事情更加复杂。
有时候你想用自己定义的数据类型,例如,使用字符串存储序列化的PHP对象。数据库的添加可能很容易,但是这样的话,MySQL就会变得很笨重,而且以后可能导致一些问题。

INT,TinyINT,VARCHAR,CHAR,TEXT这些字段类型的合理选用无可厚非。
而Date、DateTime、TIMESTAMP这三种类型,在大型应用中是绝对不可以使用的,而是要用INT(10) UNSIGNED代替。
一个是性能,另外就是应用中尤其是PHP对UNIX_TIMESTAMP时间戳的转化实在太方便了。用Date要输出各种时间格式反而麻烦。

8.在SELECT查询中使用*

不要使用*在表中返回所有的字段,这会非常的慢。你只需要取出你需要的数据字段。如果你需要取出所有的字段,那么可能你的表需要更改了。

9.索引不足或者过度索引

一般来说,应该索引出现在SELECT语句中WHERE后面所有的字段。
例如,假如我们的用户表有一个数字的ID(主键)和email地址。登录之后,MySQL应该通过email找到相应的ID。通过索引,MySQL可以通过搜索算法很快的定位email。如果没有索引,MySQL就需要检查每一项记录直到找到。
这样的话,你可能想给每一个字段都添加索引,但是这样做的后果就是在你更新或者添加的时候,索引就会重新做一遍,当数据量大的时候,就会有性能问题。所以,只在需要的字段做索引。
索引是必须的,但是如果索引都解决不了的查询,考虑memcache或者nosql解决方案吧。

10.不备份

也许不常发生,但是数据库损毁,硬盘坏了、服务停止等等,这些都会对数据造成灾难性的破坏。所以你一定要确保自动备份数据或者保存副本。
这条是作者凑数么?

11.另外:不考虑其他数据库

MySQL 可能是PHP用的最多的数据库了,但是也不是唯一的选择。 PostgreSQL和Firebird也是竞争者,他们都开源,而且不被某些公司所控制。微软提供SQL Server Express,Oracle有10g Express,这些企业级的也有免费版。SQLite对于一些小型的或者嵌入式应用来说也是不错的选择。

这条相当正确。应用中不仅要针对应用选择其他数据库,甚至还要针对具体的业务类型,在同一套应用中并行使用多种数据库。哪怕不是数据库,而是其他各种缓存、内存存储等解决方案。