Maison  >  Article  >  développement back-end  >  Compréhension approfondie de l'optimisation et des précautions PHP

Compréhension approfondie de l'optimisation et des précautions PHP

黄舟
黄舟original
2017-07-27 10:15:181035parcourir

Cet article est une analyse détaillée et une introduction aux méthodes d'écriture efficaces en PHP. Le résumé est très détaillé et complet. Il est très utile pour que chacun améliore son niveau PHP. Les amis qui en ont besoin peuvent s'y référer !

1. Rendez-la aussi statique que possible :

Si une méthode peut être statique, déclarez-la comme statique, et le la vitesse peut être améliorée Améliorée de 1/4, même lorsque j'ai testé, cela s'est amélioré de près de trois fois.

Bien sûr, cette méthode de test doit être exécutée au niveau 100 000 ou plus pour que l'effet soit évident.

En fait, la principale différence d'efficacité entre les méthodes statiques et les méthodes non statiques est la mémoire : les méthodes statiques génèrent de la mémoire au démarrage du programme, et les méthodes d'instance génèrent de la mémoire pendant l'exécution du programme, donc les méthodes statiques peuvent être appelé directement, et les méthodes d'instance doivent être créées en premier. Générer des instances et appeler des méthodes via des instances est très rapide, mais trop occupera de la mémoire.

Tout langage fonctionne sur la mémoire et le disque. Quant à savoir s'il est orienté objet ou non, c'est juste une question de couche logicielle. La couche inférieure est la même, mais la méthode d'implémentation est différente. La mémoire statique est continue car elle est générée au début du programme, tandis que l'instance s'applique à l'espace discret, donc bien sûr elle n'est pas aussi rapide que la méthode statique.

Les méthodes statiques appellent toujours la même mémoire. L'inconvénient est qu'elles ne peuvent pas être détruites automatiquement, mais peuvent être détruites par instanciation.

2. Echo est plus efficace que print car echo n'a pas de valeur de retour et print renvoie un entier

Test :


Echo
0.000929 - 0.001255 s (平均 0.001092 seconds)
Print
0.000980 - 0.001396 seconds (平均 0.001188 seconds)

La différence est d'environ 8%. De manière générale, l'écho est plus rapide.

Notez que lors de l'écho de grandes chaînes, les performances seront sérieusement affectées si aucun ajustement n'est effectué. Utilisez mod_deflate pour ouvrir Apache pour la compression ou ouvrez ob_start pour mettre d'abord le contenu dans le tampon.

3. Définissez le nombre maximum de boucles avant la boucle, pas pendant la boucle

Tous les imbéciles comprennent cela.

4. Détruisez les variables pour libérer de la mémoire, en particulier les grands tableaux

Les tableaux et les objets occupent particulièrement de la mémoire en PHP. Causé par,

De manière générale, l'utilisation de la mémoire des tableaux PHP n'est que de 1/10, c'est-à-dire qu'un tableau avec 100 Mo de mémoire en langage C nécessite 1 Go en PHP.

Surtout dans les systèmes où PHP est utilisé comme serveur backend, le problème d'une consommation excessive de mémoire se produit souvent.

5. Évitez d'utiliser des méthodes magiques comme __get, __set, __autoload, etc.

Pour les fonctions commençant par __, nommez-les fonctions magiques en premier. visite sous conditions particulières. En général, il existe les fonctions magiques suivantes

<code><strong>__construct(),__destruct(),__get(),__set(),__unset(),__call(),__callStatic(),__sleep(),__wakeup(),__toString(),__set_state(),__clone(),__autoload()</strong>__construct(), __destruct(), __get(), __set(), __unset(), __call(), __callStatic(), __sleep (), __wakeup(), __toString(), __set_state(), __clone(), __autoload()

En fait, si __autoload ne peut pas comparer efficacement le nom de la classe avec le correspondant réel au fichier disque (notez que cela fait référence au fichier disque réel, pas seulement au nom du fichier), le système devra faire un grand nombre de jugements pour savoir si le fichier existe (il doit être recherché dans le chemin inclus dans chaque inclure le chemin). Déterminer si un fichier existe nécessite des opérations d'E/S sur disque Comme nous le savons tous, l'efficacité des opérations d'E/S sur disque est très faible, c'est donc la raison pour laquelle l'efficacité du mécanisme de chargement automatique est réduite.

Par conséquent, lors de la conception du système, nous devons définir un mécanisme clair pour mapper les noms de classe aux fichiers de disque réels. Plus cette règle est simple et claire, plus le mécanisme de chargement automatique sera efficace.

Conclusion : le mécanisme de chargement automatique n'est pas intrinsèquement inefficace. Seul un abus des fonctions de chargement automatique et des fonctions de chargement automatique mal conçues entraîneront une réduction de son efficacité.

Essayez donc d'éviter d'utiliser la méthode magique __autoload. est sujette à caution.

6.requiere_once() est relativement gourmand en ressources ;

C'est parce que requirere_once doit déterminer si le fichier a été référencé), alors n'essayez pas pour l'utiliser si possible. Méthodes require/include couramment utilisées à éviter.

7. Utilisez des chemins absolus dans les inclusions et les exigences.


Si un chemin relatif est inclus, PHP parcourra le include_path pour trouver le fichier.

L'utilisation de chemins absolus évitera de tels problèmes, il faudra donc moins de temps pour résoudre le chemin du système d'exploitation.

8. Si vous avez besoin d'obtenir l'heure à laquelle le script est exécuté, $_SERVER['REQUSET_TIME'] est meilleur que time(); Comme vous pouvez l'imaginer. L'un est prêt à l'emploi et peut être utilisé directement, et l'autre nécessite le résultat obtenu par la fonction.
9. 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 leur efficacité est supérieure à celle des expressions régulières

Pas besoin de le dire ; La régularité consomme le plus de performances.
Y a-t-il des fonctions utiles que vous avez manquées ? Par exemple : strpbrk()strncasecmp()strpos()/strrpos()/stripos()/strripos() accélère strtr Si tout ce dont vous avez besoin pour convertir est un seul caractère,
Utilisez une chaîne au lieu d'un tableau pour. do strtr :




Amélioration de l'efficacité : 10 fois.

<?php
$addr = strtr($addr, "abcd", "efgh"); // good
$addr = strtr($addr, array(&#39;a&#39; => &#39;e&#39;, )); // bad
?>

Le remplacement du caractère 10.str_replace est plus rapide que le remplacement régulier preg_replace, mais strtr est 1/4 plus rapide que str_replace ;

另外不要做无谓的替换即使没有替换,str_replace 也会为其参数分配内存。很慢!解决办法:
用 strpos 先查找(非常快),看是否需要替换,如果需要,再替换效率:- 如果需要替换:效率几乎相等,差别在 0.1% 左右。
如果不需要替换:用 strpos 快 200%。

11.参数为字符串

如果一个函数既能接受数组又能接受简单字符做为参数,例如字符替换函数,并且参数列表不是太长,可以考虑额外写一段替换代码,使得每次传递参数都是一 个字符,而不是接受数组做为查找和替换参数。大事化小,1+1>2;

12.最好不用@,用@掩盖错误会降低脚本运行速度;

用@实际上后台有很多操作。用@比起不用@,效率差距:3 倍。特别不要在循环中使用@,在 5 次循环的测试中,即使是先用 error_reporting(0) 关掉错误,在循环完成后再打开,都比用@快。

13.$row['id']比$row[id]速度快7倍

建议养成数组键加引号的习惯;

14.在循环里别用函数

例如For($x=0; $x 48501fad7ec9f8ada671c1a739f00b12prop++)比局部变量要慢3倍;

19.建立一个未声明的局部变量要比一个已经定义过的局部变量慢9-10倍

20.声明一个未被任何一个函数使用过的全局变量也会使性能降低(和声明相同数量的局部变量一样)。
PHP可能去检查这个全局变量是否存在;

21.方法的性能和在一个类里面定义的方法的数目没有关系

因为我添加10个或多个方法到测试的类里面(这些方法在测试方法的前后)后性能没什么差异;

22.在子类里方法的性能优于在基类中;

23.只调用一个参数并且函数体为空的函数运行花费的时间等于7-8次$localvar++运算,而一个类似的方法(类里的函数)运行等于大约15次$localvar++运算;

24 用单引号代替双引号来包含字符串,这样做会更快一些。
因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会。

PHP 引擎允许使用单引号和双引号来封装字符串变量,但是这个是有很大的差别的!使用双引号的字符串告诉 PHP 引擎首先去读取字符串内容,查找其中的变 量,并改为变量对应的值。一般来说字符串是没有变量的,所以使用双引号会导致性能不佳。最好是使用字

符串连接而不是双引号字符串。


BAD:
$output = "This is a plain string";
GOOD:
$output = &#39;This is a plain string&#39;;
BAD:
$type = "mixed";
$output = "This is a $type string";
GOOD:
$type = &#39;mixed&#39;;
$output = &#39;This is a &#39; . $type .&#39; string&#39;;

25.当echo字符串时用逗号代替点连接符更快些。

echo一种可以把多个字符串当作参数的“函数”(译注:PHP手册中说echo是语言结构,不是真正的函数,故把函数加上了双引号)。
例如echo $str1,$str2。

26.Apache解析一个PHP脚本的时间要比解析一个静态HTML页面慢2至10倍。

尽量多用静态HTML页面,少用脚本。

28.尽量使用缓存,建议用memcached。

高性能的分布式内存对象缓存系统,提高动态网络应用程序性能,减轻数据库的负担;
也对运算码 (OP code)的缓存很有用,使得脚本不必为每个请求做重新编译。

29.使用ip2long()和long2ip()函数把IP地址转成整型存放进数据库而非字符型。

这几乎能降低1/4的存储空间。同时可以很容易对地址进行排序和快速查找;

30.使用checkdnsrr()通过域名存在性来确认部分email地址的有效性

这个内置函数能保证每一个的域名对应一个IP地址;

31.使用mysql_*的改良函数mysqli_*;

32.试着喜欢使用三元运算符(?:);

33.是否需要PEAR

在你想在彻底重做你的项目前,看看PEAR有没有你需要的。PEAR是个巨大的资源库,很多php开发者都知道;

35.使用error_reporting(0)函数来预防潜在的敏感信息显示给用户。

理想的错误报告应该被完全禁用在php.ini文件里。可是如果你在用一个共享的虚拟主机,php.ini你不能修改,那么你最好添加error_reporting(0)函数,放在每个脚本文件的第一行(或用
require_once()来加载)这能有效的保护敏感的SQL查询和路径在出错时不被显示;

36.使用 gzcompress() 和gzuncompress()对容量大的字符串进行压缩(解压)在存进(取出)数据库时。

这种内置的函数使用gzip算法能压缩到90%;

37.通过参数变量地址得引用来使一个函数有多个返回值。

你可以在变量前加个“&”来表示按地址传递而非按值传递;

38. 完全理解魔术引用和SQL注入的危险。

Fully understand “magic quotes” and the dangers of SQL injection. I'm hoping that most developers reading this are already familiar with SQL injection. However, I list it here because it's absolutely critical to understand. If you've never heard the term before, spend the entire rest of the day googling and reading.

39.某些地方使用isset代替strlen

当操作字符串并需要检验其长度是否满足某种要求时,你想当然地会使用strlen()函数。此函数执行起来相当快,因为它不做任何计算,只返回在zval 结构(C的内置数据结构,用于存储PHP变量)中存储的已知字符串长度。但是,由于strlen()是函数,多多少少会有些慢,因为函数调用会经过诸多步骤,如字母小写化(译注:指函数名小写化,PHP不区分函数名大小写)、哈希查找,会跟随被调用的函数一起执行。在某些情况下,你可以使用isset() 技巧加速执行你的代码。
(举例如下)

if (strlen($foo) < 5) { echo “Foo is too short”$$ }

(与下面的技巧做比较)

if (!isset($foo{5})) { echo “Foo is too short”$$ }

调用isset()恰巧比strlen()快,因为与后者不同的是,isset()作为一种语言结构,意味着它的执行不需要函数查找和字母小写化。也就是说,实际上在检验字符串长度的顶层代码中你没有花太多开销。

40.使用++$i递增


When incrementing or decrementing the value of the variable $i++ happens to be a tad slower then ++$i. This is something PHP specific and does not apply to other languages, so don't go modifying your C or Java code thinking it'll suddenly become faster, it won't. ++$i happens to be faster in PHP because instead of 4 opcodes used for $i++ you only need 3. Post incrementation actually causes in the creation of a temporary var that is then incremented. While preincrementation increases the original value directly. This is one of the optimization that opcode optimized like Zend's PHP optimizer. It is a still a good idea to keep in mind since not all opcode optimizers perform this optimization and there are plenty of ISPs and servers running without an opcode optimizer.

当执行变量$i的递增或递减时,$i++会比++$i慢一些。这种差异是PHP特有的,并不适用于其他语言,所以请不要修改你的C或Java代码并指望它们能立即变快,没用的。++$i更快是因为它只需要3条指令(opcodes),$i++则需要4条指令。后置递增实际上会产生一个临时变量,这个临时变量随后被递增。而前置递增直接在原值上递增。这是最优化处理的一种,正如Zend的PHP优化器所作的那样。牢记这个优化处理不失为一个好主意,因为并不是所有的指令优化器都会做同样的优化处理,并且存在大量没有装配指令优化器的互联网服务
提供商(ISPs)和服务器。

40. 不要随便就复制变量

有时候为了使 PHP 代码更加整洁,一些 PHP 新手(包括我)会把预定义好的变量复制到一个名字更简短的变量中,其实这样做的结果是增加了一倍的内存消耗,只会使程序更加慢。试想一下,在下面的例子中,如果用户恶意插入 512KB 字节的文字到文本输入框中,这样就会导致 1MB 的内存被消耗!


BAD:
$description = $_POST[&#39;description&#39;];

echo $description;
GOOD:
echo $_POST[&#39;description&#39;];

41 使用选择分支语句

switch case好于使用多个if,else if语句,并且代码更加容易阅读和维护。

42.在可以用file_get_contents替代file、fopen、feof、fgets

在可以用file_get_contents替代file、fopen、feof、fgets等系列方法的情况下,尽量用file_get_contents,因为他的效率高得多!但是要注意file_get_contents在打开一个URL文件时候的PHP版本问题;

43.尽量的少进行文件操作,虽然PHP的文件操作效率也不低的;

44.优化Select SQL语句,在可能的情况下尽量少的进行Insert、Update操作(在update上,我被恶批过);

45.尽可能的使用PHP内部函数

46.循环内部不要声明变量,尤其是大变量:对象

(这好像不只是PHP里面要注意的问题吧?);

47.多维数组尽量不要循环嵌套赋值;

48.foreach效率更高,尽量用foreach代替while和for循环;

49.“用i+=1代替i=i+1。符合c/c++的习惯,效率还高”;

50.对global变量,应该用完就unset()掉;

51 并不是事必面向对象(OOP),面向对象往往开销很大,每个方法和对象调用都会消耗很多内存。

52 不要把方法细分得过多,仔细想想你真正打算重用的是哪些代码?

53 如果在代码中存在大量耗时的函数,你可以考虑用C扩展的方式实现它们。

54、打开apache的mod_deflate模块,可以提高网页的浏览速度。
(提到过echo 大变量的问题)

55、数据库连接当使用完毕时应关掉,不要用长连接。

56、split比exploade快


split()
0.001813 - 0.002271 seconds (avg 0.002042 seconds)
explode()
0.001678 - 0.003626 seconds (avg 0.002652 seconds)
Split can take regular expressions as delimiters, and runs faster too. ~23% on average.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn