在运行PHP程序,通常会遇到“Fatal Error: Allowed memory size of xxxxxx bytes exhausted”的错误, 这个意味着PHP脚本使用了过多的内存,并超出了系统对其设置的允许最大内存。解决这个问题,首先需要查看你的程序是否分配了过多的内存,在程序没有问题的情况下,你可以通过一下方法来增加PHP的内存限制(memory_limit)。

检查php的内存限制值

为了查看这个值,你需要建立一个空的php文件,比如view-php-info.php。然后将一下代码贴到里面。

<?php phpinfo(); ?>
将这个脚本放到你的PHP主机上,然后在浏览器中调用它。这时你可以看到你的PHP环境配置的信息,其中有一部分是关于”memory_limit”的, 如下图:

view-php-memory-limit

注:你可以用这种方法来查看php的其他参数设置,不仅仅是memory_limit

memory_limit应该设为多少?

这个完全依赖于你的应用的要求。比如Wordpress,运行起核心代码需要32MB。Drupal 6则要求这个值最小为16MB,并推荐设置为32MB。如果你又安装不少的插件(plugins),尤其是那些要进行图像处理的模块,那么你可能需要128MB或更高的内存。

如何设置memory_limit

方法1: php.ini

最简单或常用的方法是修改php.ini

首先找到对你的网站生效的php.ini文件
由于有多个地方都可以设置php的参数,找到正确的配置文件,并进行更改是首先要做的一步。如果你上面的方法建立了php文件来查看其配置参数,则你可以找到”Loaded Configuration File”这一项,以下是个例子:

php-ini-location

对于Linux用户,你可以通过执行”php -i | grep Loaded Configuration File”来找到对应的配置文件。而Windows用户,你可以尝试修改你的php安装目录下的php.ini。

编辑php.ini
在php.ini中,找到”memory_limit”这一项,如果没有,你可以在文件的尾部自己增加这个参数。以下是一些设置范例

memory_limit = 128M ; 可以将128M改为任何你想设置的值
保存文件

重启web 服务器
如果是web服务器使用Apache, 则执行:

httpd restart
有些情况下,你可能不被允许私修改php.ini。比如如果你购买了虚拟主机服务,但是你的服务商确禁止你修改这个文件。那么,你可以需要考虑用其他方法来增加memory_limit的值。

方法2: .htaccess

说明: 这种方法只有在php以Apache模块来执行时才生效.

在你的网站的根目录下找到”.htaccess”文件,如果没有,可以自己创建一个。然后把以下配置放入其中

php_value memory_limit 128M ; 可以将128M改为任何你想设置的值
方法3: 运行时修改php的内存设置

在你的php代码中增加以下命令行即可。

ini_set(‘memory_limit’, ‘128M’);
memory_limit修改失败

如果你使用虚拟主机,有可能会出现memory_limit的值修改失败。这个需要联系你的服务商看怎么处理,通常他们限制了可以设置的最大值或者根本就不允许你修改。如果他们的环境真的无法满足你的要求,那么你可能要考虑换一个主机服务商。

创建软链接即用 ln -s 原始文件或文件夹 目标文件或文件夹

说明:因为空间有限,不改变原来程序文件,再继续读取/data/ftp目录内容,只需要在/data2/上面建立软连接.

#建立软链接
mv /data/ftp /data2/
ln -s /data2/ftp /data/ftp
#删除软连接
#当删除链接文件时,如果不小心会把原始文件删掉
rm /data/ftp
#只是少了一个“ / ” 删除的 就是链接文件, 也就是在文件的最后不要加上”/”
结论:
在删除文件时要小心
在删除软链接文件时,小心使用 Tab 建,一定不要在目录后面加斜扛”/”

Read More →

表的范式、是首先符合1NF 才能符合2NF 进一步满足 3NF
第一范式:1NF是对属性的原子性约束,要求属性(列)具有原子性,不可再分解 (只要是关系型数据库 自动满足第一范式)
第二范式:2NF是对记录的唯一性约束,要求每条记录既有唯一性 即实体的唯一性 (通常使用主键来完成,主键ID一般不包含业务逻辑,正因为不包含业务逻辑所以数据稳定)
第三范式:3NF是对字段的冗余性约束,要求字段完全没有冗余。(一个字段的内容重复出现多次或者可以在另一张表中可以推算出来的数据 即为冗余数据)

反范式化

反范式化指的是通过增加冗余或重复的数据来提高数据库的读性能。

备注:但是有些情况下 完全符合3NF的数据库也未必是好的数据库,有时候为了提高效率,可以适当的冗余数据,降低3NF标准,具体做法是:
在表的 1对N 情况下 可能会在1的那边设置一个 在为了提高效率 会在1那边设置一个反三范式的字段提速

单例模式(职责模式):
简单的说,一个对象(在学习设计模式之前,需要比较了解面向对象思想)只负责一个特定的任务;
单例类:
1、构造函数需要标记为private(访问控制:防止外部代码使用new操作符创建对象),单例类不能在其他类中实例化,只能被其自身实例化;
2、拥有一个保存类的实例的静态成员变量
3、拥有一个访问这个实例的公共的静态方法(常用getInstance()方法进行实例化单例类,通过instanceof操作符可以检测到类是否已经被实例化)
另外,需要创建__clone()方法防止对象被复制(克隆)
为什么要使用PHP单例模式?
1、php的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 使用单例模式, 则可以避免大量的new 操作消耗的资源。
2、如果系统中需要有一个类来全局控制某些配置信息, 那么使用单例模式可以很方便的实现. 这个可以参看ZF的FrontController部分。
3、在一次页面请求中, 便于进行调试, 因为所有的代码(例如数据库操作类db)都集中在一个类中, 我们可以在类中设置钩子, 输出日志,从而避免到处var_dump, echo。
代码实现:
<?php
/**
* 设计模式之单例模式
* $_instance必须声明为静态的私有变量
* 构造函数和析构函数必须声明为私有,防止外部程序new
* 类从而失去单例模式的意义
* getInstance()方法必须设置为公有的,必须调用此方法
* 以返回实例的一个引用
* ::操作符只能访问静态变量和静态函数
* new对象都会消耗内存
* 使用场景:最常用的地方是数据库连接。
* 使用单例模式生成一个对象后,
* 该对象可以被其它众多对象所使用。
*/
class Danli {

//保存类实例的静态成员变量
private static $_instance;

//private标记的构造方法
private function __construct(){
echo ‘This is a Constructed method;’;
}

//创建__clone方法防止对象被复制克隆
public function __clone(){
trigger_error(‘Clone is not allow!’,E_USER_ERROR);
}

//单例方法,用于访问实例的公共的静态方法
public static function getInstance(){
if(!(self::$_instance instanceof self)){
self::$_instance = new self;
}
return self::$_instance;
}

public function test(){
echo ‘调用方法成功’;
}

}

//用new实例化private标记构造函数的类会报错
//$danli = new Danli();

//正确方法,用双冒号::操作符访问静态方法获取实例
$danli = Danli::getInstance();
$danli->test();

//复制(克隆)对象将导致一个E_USER_ERROR
$danli_clone = clone $danli;

//来源http://blog.sina.com.cn/s/blog_6dbbafe001018w7r.html

REDIS数据库其实与mysql数据库在很多的用法上是一样的,今天 我们要介绍的是REDIS存取PHP多维数组的示例,如果有需要可以和小编一起来学学。

PHP数组实际上是哈希表,Redis似乎不支持二维数组,但是可以使用hmset把PHP数组保存为hash类型的数据,使用hmget读取一维的键没问题,读取二维的多维的键就返回false。
$hset = array(
‘WUST’=>’WUHAN SI’,
‘birth’=>1031,
‘marray’=>array(
‘apple’=>’苹果’,
‘orange’=>’org’,
),
);
dump($redis->hmset(‘tuntun’,$hset));//将数组保存为hash类型
dump($redis->hmget(‘tuntun’,array(‘birth’)));//取出一位数组birth的值,ok

dump($redis->hmget(‘tuntun’,array(‘marry’,’apple’)));//取出二维数组marray的apple的值,返回false

就算使用hgetall方法:
dump($redis->hgetall(‘hset_tuntun’));
结果如下:

array(3) {
[“WUST”] => string(8) “WUHAN SI”
[“birth”] => string(4) “1031”
[“marray”] => string(5) “Array”
}
二维数组无法显示。所以redis不支持PHP的多维数组的存取。
解决办法是:如有要用redis存多维数组,可以把数组json_encode转换成json各式数据,以string类型的方式存储。读取的时候再json_decode回来。