`
dongbei
  • 浏览: 5732 次
  • 性别: Icon_minigender_1
  • 来自: 大连
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

增加PHP的内存限制方法 还有个人关于静态类的使用的观点

阅读更多
当然,静态类有好的一面,比如说很适合实现一些无状态的工具类,但多数时候,我的主观倾向很明确,多用对象,少用静态类,避免系统过早的固化。顺便说一句,希望别有人告诉我静态类比对象快之类的说教。

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

检查php的内存限制值

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

<?php phpinfo(); ?>

将这个脚本放到你的Web服务器上,然后在浏览器中调用它。这时你可以看到你的PHP环境配置的信息,其中有一部分是关于“memory_limit”的, 如下图:



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

memory_limit应该设为多少?

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

如何设置memory_limit

方法1: php.ini

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

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



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

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

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

保存文件

3.重启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的值修改失败。这个需要联系你的服务商看怎么处理,通常他们限制了可以设置的最大值或者根本就不允许你修改。如果他们的环境真的无法满足你的要求,那么你可能要考虑换一个主机服务商。

黑格尔有句名言:存在即合理。以此为论据的话,静态类的使用必然有其合理性。不过物极必反,一旦代码过于依赖静态类,其劣化二人转的解决则不可避免。这就好比罂粟作为一种草本植物,有其在药理上的价值,但如果肆无忌惮的大量使用,它就变成了。

什么是静态类

所谓静态类指的是无需实例化成对象,直接通过静态方式调用的类。代码如下:

class Math{    public static function ceil($value)    {        return ceil($value);    }    public static function floor($value)    {        return floor($value);    }}?>
此时类所扮演的角色更像是命名空间,这或许是很多人喜欢使用静态类最直接的原因。

静态类的问题

本质上讲,静态类是面向过程的,因为通常它只是机械的把原本面向过程的代码集合到一起,虽然结果是以类的方式存在,但此时的类更像是一件皇帝的新衣,所以可以说静态类实际上是披着面向对象的壳儿,干着面向过程的事儿。

面向对象的设计原则之一:针对接口编程,而不是针对实现编程。这有什么不同?打个比方来说:抛开价格因素,你喜欢独立显卡的电脑还是集成显卡的电脑?我想绝大多数人会选择独立显卡。独立显卡可以看做是针对接口编程,而集成显卡就就可以看做是针对实现编程。如此说来针对实现编程的弊端就跃然纸上了:它丧失了变化的可能性。

下面杜撰一个文章管理系统的例子来具体说明一下:

class Article{    public function save()    {        ArticleDAO::save();    }}?>
Article实现必要的领域逻辑,然后把数据持久化交给ArticleDAO去做,而ArticleDAO是一个静态类,就好像焊在主板上的集成显卡一样难以改变,假设我们为了测试代码可能需要Mock掉ArticleDAO的实现,但因为调用时使用的是静态类的名字,等同于已经绑定了具体的实现方式,Mock几乎不可能,当然,实际上有一些方法可以实现:

class Article{    private static $dao = 'ArticleDAO';    public static funciton setDao($dao)    {        self::$dao = $dao;    }    public static function save()    {        $dao = self::$dao;        $dao::save();    }}?>
有了变量的介入,可以在运行时设定具体使用哪个静态类:

Article::setDao('MockArticleDAO');www.errenzhuan.cc;Article::save();?>
虽然这样的实现方式看似解决了Mock的问题,但是首先它修改的原有的代码,违反了开闭原则,其次它引入了静态变量,而静态变量是共享的状态,有可能会干扰其它代码的执行,所以并不是一个完美的解决方案。

补充说明,利用动态语言的特性,其实可以简单的通过require一个不同的类定义文件来实现Mock,但这样做同样有弊端,设想我们在二人转www.errenzhuan.cc脚本里需要多次变换实现方式,但实际上我们只有一次require的机会,否则就会出现重复定义的错误。

注:某些情况下,利用静态延迟绑定也可以提高静态类的可测试性,参考PHPUnit。

对象的价值

如果放弃静态类,转而使用对象,应该如何实现文章管理系统的例子?代码如下:

class Article{    private $dao;    public function __construct($dao = null)    {        if ($dao === null) {            $dao = new ArticleDAO();        }        $this->setDao($dao);    }    public function setDao($dao)    {        $this->dao = $dao;    }    public function save()    {        $this->dao->save();    }}?>
实际上,这里用到了人们常说的依赖注入技术,通过构造器或者Setter注入依赖的对象:

$article = new Article(new MockArticleDAO());$article->save();?>
对象有自己的状态,不会发生共享状态干扰其它代码的执行的情况。
分享到:
评论

相关推荐

    Handler对象中使用匿名内部类或非静态内部类正确地释放消息避免内存泄漏或增加Native内存

    然而,不当使用Handler,尤其是结合匿名内部类或非静态内部类,可能导致内存泄漏和Native内存增加,这对应用性能和稳定性造成负面影响。 首先,我们要理解内存泄漏的概念。内存泄漏是指程序中已分配的内存没有被...

    Java中的静态变量静态方法静态块与静态类.docx

    Java 中的静态变量、静态方法、静态块和静态类 Java 中的静态变量、静态方法、静态块和静态类是 Java 编程语言的四个重要概念,它们之间存在着紧密的关系。下面将对这四个概念进行详细的介绍。 一、静态变量...

    c#面向对象静态类、构造方法、静态方法介绍.zip

    在C#编程中,面向对象是核心特性之一,它提供了静态类、构造方法以及静态方法等概念,这些是创建高效、可维护代码的关键元素。让我们深入探讨这些知识点。 首先,静态类是C#中不能被实例化的类,它们只包含静态成员...

    PHP中静态方法(static)与非静态方法的使用及区别.docx

    在PHP编程语言中,`static`关键字用于定义类的静态属性和方法,它们与类的实例(对象)无关,而是直接关联到类本身。理解静态方法和非静态方法的使用和区别是掌握PHP面向对象编程的关键。 静态方法是通过类名直接...

    JS定义静态类

    这段代码提供了一种实现限制文本框输入长度的方法,虽然它使用了函数而非ES6中更现代的类语法来定义静态方法和属性,但依然实现了基本的需求。对于希望了解如何在不使用ES6类的情况下模拟静态方法和属性的开发者而言...

    从JVM内存管理的角度谈谈静态方法和静态属性

    1. **内存分配**:静态属性在类加载时分配,占用的是方法区的内存,而非堆。这意味着静态属性的生命周期与类的生命周期相同,直到类卸载才会被释放。 2. **垃圾收集**:由于静态属性不会随着对象的创建和销毁而改变...

    可能是方法最全Redis静态工具类(RedisUtils.java)

    可能是最全的Redis静态工具类,拿来即用,随时随地RedisUtils.方法名()存取数据,每个方法都有对应的注释,快速上手!

    C#静态方法与非静态方法的比较

    - 尽量减少静态方法的使用,因为它们会增加代码之间的耦合度,不利于代码的维护和扩展。 - 如果一个方法不依赖于实例状态,那么考虑将其声明为静态方法,这样可以提高性能并减少内存占用。 - 当方法需要访问实例变量...

    生成静态的方法

    下面我们将深入探讨静态方法、静态变量以及静态类等相关的知识点。 1. 静态方法 静态方法是与类关联,而不是与类的实例关联的方法。这意味着我们不需要创建类的实例就可以调用静态方法。它们在内存中只有一份,且在...

    MSIL 静态类在 IL 定义上和非静态类的差别.rar

    - **非静态类**:非静态成员的访问受到访问修饰符(如`public`, `private`, `protected`等)的限制。 - **静态类**:静态类不能包含实例构造器,所以无法通过`new`关键字访问。静态成员可以直接通过类名访问,无需...

    静态内部类

    2. **访问限制**:静态内部类只能访问外部类的静态成员(包括变量和方法),而不能访问外部类的非静态成员。这是因为静态内部类并不依赖于外部类的实例,因此不能访问非静态成员。 3. **命名空间**:静态内部类和...

    操作系统内存静态分配

    总的来说,操作系统内存的静态分配是优化性能和简化内存管理的一种方法,尤其是在批处理环境中。通过C++模拟这一过程,可以帮助我们更好地理解和控制程序的内存行为,减少不必要的内存开销,提高程序的运行效率。

    java 静态内部类的使用规范

    Java语言中的静态内部类,也称为嵌套类,是内部类的一种特殊形式,它与非静态内部类(也称为成员内部类)相比有着独特的特点和使用场景。在深入探讨其使用规范之前,我们先理解静态内部类的基本概念。 静态内部类不...

    浅析php静态方法与非静态方法的用法区别

    1. 访问限制:静态方法不能直接访问非静态的属性和方法,因为静态成员是属于类级别的,而非静态成员是属于对象实例级别的。由于静态成员的创建和调用不依赖于任何实例,因此在静态方法内部不存在对非静态成员的直接...

    静态(static)方法重写(override)

    - **作用域限制**:静态方法只能访问静态变量和调用其他静态方法。 2. **静态方法的隐藏** - **隐藏而非重写**:当子类中声明了一个与父类中相同的静态方法时,实际上是在子类中定义了一个新的方法,这个新方法会...

    C++ 静态成员变量 嵌套类分配回收内存

    在深入探讨"C++ 静态成员变量与嵌套类的内存分配回收"这一主题之前,我们首先需要理解几个核心概念:静态成员变量、嵌套类以及它们在内存管理中的角色。 ### C++中的静态成员变量 静态成员变量是类的一个特性,它...

    实现易语言类静态数据成员的方法

    易语言的学习者在论坛中讨论这类问题时,可能会遇到如何在类的方法中正确使用静态数据成员的问题。记住,静态数据成员在所有实例方法中都可以直接访问,而无需通过`this`关键字引用。同时,由于静态数据成员不随对象...

Global site tag (gtag.js) - Google Analytics