Maison >développement back-end >tutoriel php >Quelques suggestions pour améliorer l'efficacité et l'optimisation de PHP
Le contenu de cet article est de partager avec vous quelques suggestions pour améliorer l'efficacité et l'optimisation de PHP. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer
. 1 String
1.1 Utilisez moins d'expressions régulières
Si vous pouvez utiliser les fonctions internes de manipulation de chaînes de PHP, essayez de les utiliser à la place des expressions régulières car son efficacité est supérieure à. régularité.
Il va sans dire que les expressions régulières sont celles qui consomment le plus de performances.
La fonction str_replace est beaucoup plus rapide que preg_replace, et la fonction strtr est plus rapide que str_replace.
Y a-t-il des fonctions utiles que vous avez manquées ?
Par exemple : strpbrk(), strncasecmp(), strpos(), strrpos(), stripos(), strripos().
1.2 Remplacement de caractères
Si tout ce qui doit être converti est un seul caractère, utilisez une chaîne comme fonction strtr() pour terminer le remplacement au lieu d'un tableau :
$addr = strtr($addr, "abcd", "efgh"); // Recommandé
$addr = strtr($addr, array('a' => 'e', ));
Amélioration de l'efficacité : 10 fois .
Le remplacement du caractère Str_replace est plus rapide que le remplacement régulier preg_replace, mais strtr est 1/4 plus rapide que str_replace.
De plus, ne faites pas de substitutions inutiles, str_replace allouera de la mémoire pour ses paramètres même s'il n'y a pas de substitution. Très lent !
Utilisez strpos pour rechercher d'abord (très rapidement) s'il doit être remplacé, et si c'est le cas, remplacez-le.
Si un remplacement est nécessaire, l'efficacité est presque égale, avec une différence d'environ 0,1 %.
Si aucun remplacement n'est nécessaire : 200 % plus rapide avec le strpos.
1.3 Compresser des chaînes de grande capacité
Utilisez gzcompress() et gzuncompress() pour compresser et décompresser des chaînes de grande capacité, puis stockez-les et récupérez-les dans la base de données.
Cette fonction intégrée utilise l'algorithme gzip et peut compresser les chaînes de 90 %.
Sortie d'écho 1.4
la chaîne d'écho utilise des virgules au lieu de connecteurs de points pour la rendre plus rapide.
Bien que echo soit une structure de langage, pas une vraie fonction.
Cependant, il peut transmettre plusieurs chaînes séparées par des virgules comme paramètres de « fonction », ce sera donc plus rapide.
echo $str1, $str2; // Plus rapide
echo $str1 . // Plus lent
1.5 Essayez d'utiliser des guillemets simples
PHP Le moteur permet l'utilisation de guillemets simples et doubles pour encapsuler des variables chaîne, mais leurs vitesses sont très différentes !
L'utilisation de guillemets doubles dans une chaîne indiquera au moteur PHP de lire d'abord le contenu de la chaîne, d'y trouver les variables et de les remplacer par les valeurs correspondant aux variables.
De manière générale, les chaînes n'ont pas de variables et l'utilisation de guillemets doubles entraînera de mauvaises performances.
Il est préférable d'utiliser la concaténation de chaînes au lieu des chaînes entre guillemets doubles.
$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 Utiliser isset au lieu de strlen
Lorsque nous vérifions la longueur d'une chaîne, notre première pensée est d'utiliser la fonction strlen().
Cette fonction s'exécute assez rapidement car elle n'effectue aucun calcul et renvoie simplement la longueur de chaîne connue stockée dans la structure zval (la structure de données intégrée du C utilisée pour stocker les variables PHP).
Cependant, puisque strlen() est une fonction, elle sera quelque peu lente, car l'appel de fonction passera par de nombreuses étapes, telles que les lettres minuscules et la recherche de hachage, et sera exécuté avec la fonction appelée.
Dans certains cas, vous pouvez utiliser l'astuce isset() pour accélérer l'exécution de votre code. Par exemple :
if (strlen($foo) < 5) { echo "Foo is too short"; } // 使用isset() if (!isset($foo{5})) { echo "Foo is too short"; }
1.7 Utilisez split pour diviser une chaîne
Lors du fractionnement d'une chaîne, split() est plus rapide que explosive().
split()
0,001813 secondes (moyenne 0,002042 secondes)
explode()
0,001678 - 0,003626 secondes (moyenne 0,002652 secondes)
1,8 Echo est plus efficace que print
car echo n'a pas de valeur de retour et print renvoie un entier.
Remarque : lorsque l'écho produit de grandes chaînes, s'il n'y a pas de réglage, les performances seront sérieusement affectées.
Activez mod_deflate d'Apache pour la compression, ou activez ob_start pour mettre le contenu dans le tampon, ce qui peut améliorer les problèmes de performances.
2 déclarations
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 不实用段标签34be907719e18072f62a198f7caa6408这种方式是鼓励的,可以是代码更加简洁。
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扩展方式实现
Si votre code contient un grand nombre de fonctions chronophages, envisagez de les implémenter en tant qu'extensions C.
4 Variables
4.1 Détruire les variables dans le temps
Les tableaux, les objets et les variables GLOBAL occupent particulièrement de la mémoire en PHP Cela est dû à. PHP Causé par le moteur Zend sous-jacent.
D'une manière générale, l'utilisation de la mémoire des tableaux PHP n'est que de 1/10.
En d'autres termes, un tableau avec 100M de mémoire en langage C nécessite 1G en PHP.
En particulier, dans les systèmes où PHP est utilisé comme serveur backend, le problème d'une consommation excessive de mémoire se produit souvent.
4.2 Utilisez la variable $_SERVER
Si vous avez besoin d'obtenir le temps d'exécution du script, $_SERVER['REQUSET_TIME'] est meilleur que time().
L'un est prêt à l'emploi et peut être utilisé directement, et l'autre nécessite le résultat obtenu par la fonction.
4.3 Établir des variables locales dans les méthodes
La création de variables locales dans les méthodes de classe est la plus rapide, presque aussi rapide que l'appel de variables locales dans les méthodes.
4.4 Les variables locales sont plus rapides que les variables globales
Parce que les variables locales sont stockées sur la pile.
Lorsque l'espace de pile occupé par une fonction n'est pas très grand, il est très probable que toute cette mémoire atteigne le cache, et l'efficacité de l'accès au CPU est très élevée.
Au contraire, si une fonction utilise simultanément des variables globales et des variables locales, lorsque la différence entre les deux adresses est grande, le cache du processeur doit basculer d'avant en arrière et l'efficacité diminuera.
4.5 Variables locales au lieu des propriétés d'un objet
Créer une propriété d'objet (une variable dans une classe, par exemple : $this->prop++) est 3 fois plus lente qu'une variable locale.
4.6 Déclarer les variables locales à l'avance
La création d'une variable locale non déclarée est 9 à 10 fois plus lente que la création d'une variable locale déjà définie.
4.7 Déclarez les variables globales avec prudence
Déclarer une variable globale qui n'a été utilisée par aucune fonction réduira également les performances.
Cela revient à déclarer le même nombre de variables locales. PHP peut vérifier si la variable globale existe.
4.8 Incrémenter en utilisant ++$i
Lors de l'incrémentation ou de la décrémentation de la variable $i, $i++ sera plus lent que ++$i.
Cette différence est spécifique à PHP et ne s'applique pas aux autres langages, alors ne modifiez pas votre code C ou Java et attendez-vous à ce qu'il soit instantanément plus rapide, cela ne fonctionnera pas.
++$i est plus rapide car il ne nécessite que 3 instructions (opcodes), tandis que $i++ nécessite 4 instructions.
La post-incrémentation crée en fait une variable temporaire qui est ensuite incrémentée.
L'incrément du préfixe augmente directement sur la valeur d'origine.
Il s'agit d'une forme d'optimisation, comme le fait l'optimiseur PHP de Zend.
C'est une bonne idée de garder à l'esprit que tous les optimiseurs d'instructions n'effectuent pas les mêmes optimisations.
4.9 Ne copiez pas les variables avec désinvolture
Parfois, afin de rendre le code PHP plus propre, certains débutants PHP (dont moi) copient les variables prédéfinies dans une variable avec un nom plus court.
En fait, cela a pour résultat de doubler la consommation de mémoire, ce qui ne fera que ralentir le programme.
Imaginez, dans l'exemple ci-dessous, si l'utilisateur insère malicieusement 512 Ko de texte, 1 Mo de mémoire sera consommé !
// 不好的实践 $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)的缓存也很有用,使得脚本不必为每个请求重新编译。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!