Der Inhalt dieses Artikels besteht darin, Ihnen einige Vorschläge zur Verbesserung der PHP-Effizienz und -Optimierung mitzuteilen. Er hat einen gewissen Referenzwert.
1 String
1.1 Verwenden Sie weniger reguläre Ausdrücke
Wenn Sie die internen String-Manipulationsfunktionen von PHP verwenden können, versuchen Sie, diese anstelle regulärer Ausdrücke zu verwenden, da ihre Effizienz höher ist als regulär.
Es versteht sich von selbst, dass reguläre Ausdrücke die meiste Leistung verbrauchen.
Die Funktion str_replace ist viel schneller als preg_replace und die Funktion strtr ist schneller als str_replace.
Gibt es nützliche Funktionen, die Sie vermisst haben?
Zum Beispiel: strpbrk(), strncasecmp(), strpos(), strrpos(), stripos(), strripos().
1.2 Zeichenersetzung
Wenn nur ein einzelnes Zeichen konvertiert werden muss, verwenden Sie einen String als strtr()-Funktion, um die Ersetzung abzuschließen, anstelle eines Arrays:
$addr = strtr($addr, "abcd", "efgh"); // Empfohlen
$addr = strtr($addr, array('a' => 'e', ));
Effizienzverbesserung: 10-mal.
str_replace-Zeichenersetzung ist schneller als die reguläre Ersetzung preg_replace, aber strtr ist 1/4 schneller als str_replace.
Führen Sie außerdem keine unnötigen Ersetzungen durch, str_replace reserviert Speicher für seine Parameter, auch wenn keine Ersetzung erfolgt. Sehr langsam!
Verwenden Sie strpos, um zuerst (sehr schnell) zu suchen, um zu sehen, ob es ersetzt werden muss, und wenn ja, ersetzen Sie es.
Wenn ein Austausch erforderlich ist, ist der Wirkungsgrad nahezu gleich, mit einem Unterschied von etwa 0,1 %.
Wenn kein Austausch nötig ist: 200 % schneller mit strpos.
1.3 Komprimieren großer Zeichenfolgen
Verwenden Sie gzcompress() und gzuncompress(), um Zeichenfolgen mit großer Kapazität zu komprimieren und zu dekomprimieren und sie dann in der Datenbank zu speichern und abzurufen.
Diese integrierte Funktion verwendet den gzip-Algorithmus und kann Zeichenfolgen um 90 % komprimieren.
1.4 Echo-Ausgabe
Echo-String verwendet Kommas anstelle von Punktverbindungen, um es schneller zu machen.
Obwohl Echo eine Sprachstruktur ist, keine echte Funktion.
Es können jedoch mehrere durch Kommas getrennte Zeichenfolgen als „Funktions“-Parameter übergeben werden, sodass es schneller geht.
echo $str1, $str2; // Schneller
echo $str1 ; // Langsamer
1.5 Versuchen Sie, einfache Anführungszeichen zu verwenden
PHP ermöglicht die Verwendung von einfachen und doppelten Anführungszeichen zum Kapseln von Zeichenfolgenvariablen, ihre Geschwindigkeiten sind jedoch sehr unterschiedlich!
Die Verwendung von doppelten Anführungszeichen in einer Zeichenfolge weist die PHP-Engine an, zuerst den Inhalt der Zeichenfolge zu lesen, die darin enthaltenen Variablen zu finden und sie in die den Variablen entsprechenden Werte zu ändern.
Im Allgemeinen haben Zeichenfolgen keine Variablen und die Verwendung von doppelten Anführungszeichen führt zu einer schlechten Leistung.
Es ist besser, die Zeichenfolgenverkettung anstelle von Zeichenfolgen in doppelten Anführungszeichen zu verwenden.
$output = "This is a plain string"; // 不好的实践 $output = 'This is a plain string'; // 好的实践 $type = "mixed"; // 不好的实践 $output = "This is a $type string"; $type = 'mixed'; // 好的实践 $output = 'This is a ' . $type . ' string';
1.6 Verwenden Sie isset anstelle von strlen
Beim Überprüfen der Länge einer Zeichenfolge ist unser erster Gedanke, die Funktion strlen() zu verwenden.
Diese Funktion wird recht schnell ausgeführt, da sie keine Berechnungen durchführt und lediglich die bekannte Zeichenfolgenlänge zurückgibt, die in der zval-Struktur (der in C integrierten Datenstruktur zum Speichern von PHP-Variablen) gespeichert ist.
Da strlen() jedoch eine Funktion ist, ist sie etwas langsam, da der Funktionsaufruf viele Schritte durchläuft, wie z. B. Kleinbuchstaben und Hash-Suche, und zusammen mit der aufgerufenen Funktion ausgeführt wird.
In einigen Fällen können Sie den isset()-Trick verwenden, um die Ausführung Ihres Codes zu beschleunigen. Zum Beispiel:
if (strlen($foo) < 5) { echo "Foo is too short"; } // 使用isset() if (!isset($foo{5})) { echo "Foo is too short"; }
1.7 Verwenden Sie „split“, um eine Zeichenfolge zu teilen.
Beim Teilen einer Zeichenfolge ist „split()“ schneller als „explosive()“.
split()
0,001813 Sekunden (durchschnittlich 0,002042 Sekunden)
explode()
0,001678 - 0,003626 Sekunden (durchschnittlich 0,002652 Sekunden)
1,8 Echo ist effizienter als print
, da echo keinen Rückgabewert hat und print eine Ganzzahl zurückgibt.
Hinweis: Wenn Echo große Zeichenfolgen ausgibt und keine Anpassung erfolgt, wird die Leistung erheblich beeinträchtigt.
Aktivieren Sie Apaches mod_deflate zur Komprimierung oder aktivieren Sie ob_start, um den Inhalt in den Puffer zu legen, was zu Leistungsproblemen führen kann.
2 Aussagen
2.1 最好不用@
用@掩盖错误会降低脚本运行速度,并且在后台有很多额外操作。
用@比起不用,效率差距 3 倍。特别不要在循环中使用@。
在 5 次循环的测试中,即使是先用error_reporting(0)关掉错误,循环完成后再打开,都比用@快。
2.2 避免使用魔术方法
对于__开头的函数就命名为魔术函数,它们都在特定的条件下触发。
这些魔术函数包括:__construct()、__get()、__call()、__autoload()等等。
以__autoload() 为例,如果不能将类名与实际的磁盘文件对应起来,将不得不做大量的文件存在判断。
而判断文件存在需要磁盘I/O操作,众所周知,磁盘I/O操作的效率很低,因此这才是使得autoload机制效率降低的原因。
因此,在系统设计时,需要定义一套清晰的、将类名与实际磁盘文件映射的机制。
这个规则越简单越明确,__autoload()机制的效率就越高。
autoload机制并不是天然的效率低下,只有滥用autoload、设计不好的自动装载函数,才会导致其效率的降低.
所以说,尽量避免使用__autoload等魔术方法,有待商榷。
2.3 别在循环里用函数
例如:
for($x=0; $x < count($array); $x++) { }
这种写法在每次循环的时候都会调用 count() 函数,效率大大降低,建议这样:
$len = count($array); for($x=0; $x < $len; $x++) { }
让函数在循环外面一次获得循环次数。
2.4 使用三元运算符
在简单的判断语句中,三元运算符?:更简洁高效。
2.5 使用选择分支语句
switch、case好于使用多个if、else if语句,并且代码更加容易阅读和维护。
2.6 屏蔽敏感信息
使用 error_reporting() 函数来预防潜在的敏感信息显示给用户。
理想的错误报告应该被完全禁用在php.ini文件里
如果用的是共享虚拟主机,php.ini不能修改,最好添加 error_reporting() 函数。
放在每个脚本文件的第一行,或者用require_once()来加载,能有效的保护敏感的SQL查询和路径,在出错时不被显示。
2.7 不实用段标签
不要使用开始标志的缩写形式,你正在使用这样的符号吗,应该用完整的当然,如果是输出变量,用= $value ?>这种方式是鼓励的,可以是代码更加简洁。
2.8 纯PHP代码不加结束标记
如果文件内容是纯 PHP 代码,最好在文件末尾删除 PHP 结束标记?>。
这可以避免在 PHP 结束标记之后万一意外加入了空格或者换行符,会导致 PHP 开始输出这些空白,而脚本中此时并无输出的意图。
2.9 永远不要使用register_globals和magic quotes
这是两个很古老的功能,在当时(十年前)也许是一个好方法,但现在看来并非如此。
老版本的PHP在安装时会默认打开这两个功能,这会引起安全漏洞、编程错误及其他的问题。
如只有用户输入了数据时才会创建变量等。
PHP5.4.0开始这两个功能都被舍弃了,所以每个程序员都应该避免使用。
如果你过去的程序有使用这两项功能,那就尽快将其剔除吧。
3 函数
3.1 尽量使用PHP内部函数
内置函数使用C语言实现,并且经过PHP官方优化,效率更高。
3.2 使用绝对路径
在include和require中尽量使用绝对路径。
如果包含相对路径,PHP会在include_path里面遍历查找文件。
用绝对路径就会避免此类问题,解析路径所需的时间会更少。
3.3 包含文件
尽量不要用require_once和include_once包含文件,它们多一个判断文件是否被引用的过程,能不用尽量不用。
而使用require、include方法代替。
鸟哥在其博客中就多次声明,尽量不要用require_once和include_once。
3.4 函数快于类方法
调用只有一个参数、并且函数体为空的函数,花费的时间等于7-8次$localvar++运算。
而同一功能的类方法大约为15次$localvar++运算。
3.5 用子类方法
基类里面只放能重用的方法,其他功能尽量放在子类中实现,子类里方法的性能优于在基类中。
3.6 类的性能和其方法数量没有关系
新添加10个或多个方法到测试的类后,性能没什么差异。
3.7 读取文件内容
在可以用file_get_contents()替代file()、fopen()、feof()、fgets()等系列方法的情况下,尽量用file_get_contents()。
因为他的效率高得多!
3.8 引用传递参数
通过参数地址引用的方式,实现函数多个返回值,这比按值传递效率高。
方法是在参数变量前加个 &。
3.9 方法不要细分得过多
仔细想想你真正打算重用的是哪些代码?
3.10 尽量静态化
如果一个方法能被静态,那就声明它为静态的,速度可提高1/4,甚至我测试的时候,这个提高了近三倍。
当然了,这个测试方法需要在十万级以上次执行,效果才明显。
其实,静态方法和非静态方法的效率主要区别在内存。
静态方法在程序开始时生成内存,实例方法(非静态方法)在程序运行中生成内存。
所以,静态方法可以直接调用,实例方法要先成生实例再调用,静态速度很快,但是多了会占内存。
任何语言都是对内存和磁盘的操作,至于是否面向对象,只是软件层的问题,底层都是一样的,只是实现方法不同。
静态内存是连续的,因为是在程序开始时就生成了,而实例方法申请的是离散的空间,所以当然没有静态方法快。
静态方法始终调用同一块内存,其缺点就是不能自动进行销毁,而实例化可以销毁。
3.11 用C扩展方式实现
Wenn Ihr Code viele zeitaufwändige Funktionen enthält, sollten Sie erwägen, diese als C-Erweiterungen zu implementieren.
4 Variablen
4.1 Variablen rechtzeitig zerstören
Arrays, Objekte und GLOBAL-Variablen belegen in PHP besonders viel Speicher PHP Wird durch die zugrunde liegende Zend-Engine verursacht.
Im Allgemeinen beträgt die Speicherauslastung von PHP-Arrays nur 1/10.
Mit anderen Worten: Ein Array mit 100 MB Speicher in der Sprache C erfordert 1 GB in PHP.
Insbesondere in Systemen, in denen PHP als Backend-Server verwendet wird, tritt häufig das Problem eines übermäßigen Speicherverbrauchs auf.
4.2 Verwenden Sie die Variable $_SERVER
Wenn Sie die Skriptausführungszeit benötigen, ist $_SERVER['REQUSET_TIME'] besser als time().
Einer ist fertig und kann direkt verwendet werden, der andere erfordert das von der Funktion erhaltene Ergebnis.
4.3 Lokale Variablen in Methoden einrichten
Das Erstellen lokaler Variablen in Klassenmethoden ist am schnellsten, fast so schnell wie das Aufrufen lokaler Variablen in Methoden.
4.4 Lokale Variablen sind schneller als globale Variablen
Da lokale Variablen auf dem Stapel gespeichert werden.
Wenn der von einer Funktion belegte Stapelspeicher nicht sehr groß ist, ist es sehr wahrscheinlich, dass der gesamte Speicher auf den Cache gelangt, und die Effizienz des CPU-Zugriffs ist sehr hoch.
Im Gegenteil, wenn eine Funktion gleichzeitig globale Variablen und lokale Variablen verwendet und der Unterschied zwischen den beiden Adressen groß ist, muss der CPU-Cache hin und her wechseln, was die Effizienz verringert.
4.5 Lokale Variablen anstelle von Objekteigenschaften
Das Erstellen einer Objekteigenschaft (einer Variablen in einer Klasse, zum Beispiel: $this->prop++) ist dreimal langsamer als das Erstellen einer lokalen Variablen.
4.6 Lokale Variablen im Voraus deklarieren
Das Erstellen einer nicht deklarierten lokalen Variablen ist 9-10 Mal langsamer als das Erstellen einer bereits definierten lokalen Variablen.
4.7 Globale Variablen mit Vorsicht deklarieren
Das Deklarieren einer globalen Variablen, die von keiner Funktion verwendet wurde, verringert ebenfalls die Leistung.
Dies entspricht der Deklaration der gleichen Anzahl lokaler Variablen. PHP prüft möglicherweise, ob die globale Variable vorhanden ist.
4.8 Inkrementieren mit ++$i
Beim Erhöhen oder Dekrementieren der Variablen $i ist $i++ langsamer als ++$i.
Dieser Unterschied ist spezifisch für PHP und gilt nicht für andere Sprachen. Ändern Sie also bitte nicht Ihren C- oder Java-Code und erwarten Sie, dass er sofort schneller ist, da er sonst nicht funktioniert.
++$i ist schneller, da nur 3 Anweisungen (Opcodes) erforderlich sind, während $i++ 4 Anweisungen erfordert.
Post-Inkrementierung erstellt tatsächlich eine temporäre Variable, die anschließend inkrementiert wird.
Das Präfix-Inkrement erhöht sich direkt auf den ursprünglichen Wert.
Dies ist eine Form der Optimierung, wie sie vom PHP-Optimierer von Zend durchgeführt wird.
Bedenken Sie, dass nicht alle Befehlsoptimierer die gleichen Optimierungen durchführen.
4.9 Variablen nicht beiläufig kopieren
Um den PHP-Code sauberer zu machen, kopieren einige PHP-Neulinge (einschließlich mir) manchmal die vordefinierten Variablen in eine Variable mit einem kürzeren Namen.
Tatsächlich führt dies zu einer Verdoppelung des Speicherverbrauchs, wodurch das Programm nur langsamer wird.
Stellen Sie sich vor, dass im Beispiel unten 1 MB Speicher verbraucht wird, wenn der Benutzer in böswilliger Absicht 512 KB Text einfügt!
// 不好的实践 $description = $_POST['description']; echo $description; // 好的实践 echo $_POST['description'];
4.10 循环内部不要声明变量
尤其是大变量,这好像不只是PHP里面要注意的问题吧?
4.11 一定要对变量进行初始化
这里的“初始化”指的是“声明”。
当需要没有初始化的变量,PHP解释器会自动创建一个变量,但依靠这个特性来编程并不是一个好主意。
这会造成程序的粗糙,或者使代码变得另人迷惑。
因为你需要探寻这个变量是从哪里开始被创建的。
另外,对一个没有初始化的变量进行递增操作要比初始化过的来得慢。
所以对变量进行初始化会是个不错的主意。
5 数组
5.1 用字符串而不是数组作为参数
如果一个函数既能接受数组,又能接受简单字符做为参数,那么尽量用字符作为参数。
例如,字符替换函数,参数列表并不是太长,就可以考虑额外写一段替换代码。
使得每次传递参数都是一个字符,而不是接受数组做为查找和替换参数。
5.2 数组元素加引号
$row['id']比$row[id]速度快7倍。
如果不带引号,例如$a[name],那么PHP会首先检查有没有define定义的name常量
如果有,就用这个常量值作为数组键值。如果没有,再查找键值为字符串'name'的数组元素。
多了一个查找判断的过程,所以建议养成数组键名加引号的习惯。
正如上面字符串部分所述,用'又比用"速度更快。
5.3 多维数组操作
多维数组尽量不要循环嵌套赋值。
5.4 循环用foreach
尽量用foreach代替while和for循环,效率更高。
6 架构
6.1 压缩输出
在php.ini中开启gzip压缩:
zlib.output_compression = On
zlib.output_compression_level = (level)
level可能是1-9之间的数字,你可以设置不同的数字。
几乎所有的浏览器都支持Gzip的压缩方式,gzip可以降低80%的输出.
付出的代价是,大概增加了10%的cpu计算量。
但是还是会赚到了,因为带宽减少了,页面加载会变得很快。
如果你使用apache,也可以激活mod_gzip模块。
6.2 静态化页面
Apache/Nginx解析一个PHP脚本的时间,要比解析一个静态HTML页面慢2至10倍。
所以尽量使页面静态化,或使用静态HTML页面。
6.3 将PHP升级到最新版
提高性能的最简单的方式是不断升级、更新PHP版本。
6.4 利用PHP的扩展
一直以来,大家都在抱怨PHP内容太过繁杂。
最近几年来,开发人员作出了相应的努力,移除了项目中的一些冗余特征。
即便如此,可用库以及其它扩展的数量还是很可观。
甚至一些开发人员开始考虑实施自己的扩展方案。
6.5 PHP缓存
一般情况下,PHP脚本被PHP引擎编译后执行,会被转换成机器语言,也称为操作码。
如果PHP脚本反复编译得到相同的结果,为什么不完全跳过编译过程呢?
PHP加速器缓存了编译后的机器码,允许代码根据要求立即执行,而不经过繁琐的编译过程。
对PHP开发人员而言,目前提供了两种可用的缓存方案。
一种是APC(Alternative PHP Cache,可选PHP缓存),它是一个可以通过PEAR安装的开源加速器。
另一种流行的方案是OPCode,也就是操作码缓存技术。
6.6 使用NoSQL缓存
Memchached或者Redis都可以。
这些是高性能的分布式内存对象缓存系统,能提高动态网络应用程序性能,减轻数据库的负担。
这对运算码 (OPcode)的缓存也很有用,使得脚本不必为每个请求重新编译。
Das obige ist der detaillierte Inhalt vonEinige Vorschläge zur Verbesserung der PHP-Effizienz und -Optimierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!