Questions d'entretien PHP compilées et partagées

小云云
Libérer: 2023-03-22 11:56:01
original
4377 Les gens l'ont consulté

Cet article partage principalement avec vous la collecte et le partage des questions d'entretien PHP, dans l'espoir de vous aider à passer un entretien plus fluide.

Aspect du serveur

1. Redémarrage en douceur de nginx

nginx exécute un nouveau processus de travail et ferme calmement l'ancien processus de travail, informe le processus de travail de fermer le socket d'écoute, mais continue de se connecter à l'actuel fournir des services aux clients. Une fois tous les services client terminés, l'ancien processus de travail est
fermé. Si l'application du nouveau fichier de configuration échoue, nginx continuera à fonctionner en utilisant l'ancien fichier de configuration.
Pour faire simple, nginx continuera à traiter la requête précédente et démarrera un nouveau processus pour gérer la nouvelle requête. L'ancien processus sera tué une fois le traitement terminé.

2. Récupérez les 10 dernières lignes du fichier.
tail -10 a.log

3. Vérifiez les processus qui occupent plus de ressources système
top
ps : Après avoir entré la commande top, appuyez sur 1 pour voir l'utilisation de la mémoire et du processeur

3. Afficher la fonction d'occurrence des mots-clés
grep -n 'Je suis le mot-clé que vous souhaitez trouver' a.txt | cut -d ":" - f1

Mots-clés dans les fichiers statistiques Which apparaît :
grep -n "Keyword" "File path" | cut -d ":" -f1
Le dernier numéro de ligne où le mot-clé apparaît dans le fichier de statistiques :
grep -n "Keyword" "Chemin du fichier" | tail -n 1 | cut -d ":" -f1


4. Recherchez les fichiers avec le mot-clé "www" dans le répertoire /root/. terminal :
find /root/ –type f | Répertoire, le nombre de fichiers js :
find demo/ -name "*.js" |wc -l
Comptez le nombre de lignes de code de tous les js fichiers dans le répertoire de démonstration :
find demo/ -name "*.js" " |xargs cat|wc -l
wc -l `find ./ -name "*.js"`|tail -n1
Comptez le nombre de lignes de code dans tous les fichiers js du répertoire de démonstration et filtrez les lignes vides :
find /demo -name "*.js" |xargs cat|grep -v ^$|wc -l

6. Surveiller un fichier en temps réel
tail -f a.log

7 Les 100 IP les plus visitées et le nombre de visites dans le log nginx
Les 100. adresses IP les plus visitées et nombre de visites dans le journal nginx
awk '{print $1}' /opt/software/nginx/logs/ access.log sort | head -n 100

8. Dans le php compilé, ajoutez une nouvelle extension
------ -------------------- ---------
Installation du code source
1. Recherchez le répertoire du code source de php
2. Accédez au répertoire EXT
3. Exécutez phpize pour générer le fichier de configuration
4. ./configure --with-php-config=/usr/local/php/bin/php-config
5. Compiler make
6. Compiler et installer make install
7. Modifier php.ini extension=/usr/local/***.so
8. Redémarrez php-fpm

Installation YUM :
1. Allez sur le site officiel de PHP pour télécharger le code source (htpp ://pecl.php.net)
2. Décompressez le fichier
3. Exécutez phpize pour générer le fichier de configuration
4. ./ configure --with-php-config=/usr/local/ php/bin/php-config
5. Compilez make
6. Compilez et installez make install
7. Modifiez php.ini extension=/usr /local/***.so
8. Redémarrez php-fpm
—————————————————————————————————————— ----- ------
optimisation php optimisation nginx optimisation mysql

optimisation php :
1. Définissez la méthode de classe comme statique.
2. Essayez d'utiliser des guillemets simples.
3. Modifiez le nombre de processus php-fpm.
4. Modifier la mémoire maximale utilisable d'un seul script.
5. Les grands tableaux doivent être libérés rapidement après utilisation.
6. Lors d'une boucle, définissez le nombre maximum de boucles
7. N'utilisez pas @ pour protéger les erreurs
8 Essayez d'utiliser un grand nombre de fonctions intégrées PHP
Utilisez require. au lieu de require_once

optimisation nginx :
1. Modifier le nombre de processus enfants nginx. [Maximum 65535]
2. Activer le cache statique
3. Modifier le nombre de processus principaux. Il est recommandé de spécifier en fonction du nombre de processeurs, généralement des multiples (par exemple, 2 processeurs quad-core comptent pour 8)
4 Activer la sortie gzip [Lorsque gzip est activé, la fonction ob ne peut pas. être utilisé]
5. keepalive_timeout Définir le délai d'expiration de la connexion

Optimisation MySQL :
Éviter les sous-requêtes
2. Lecture séquentielle
3. Définissez l'identifiant d'incrémentation automatique
5. Évitez d'utiliser select *
6. Définissez les types de champs de manière appropriée
7. Séparez la lecture et l'écriture
8.
10. Évitez d'utiliser des opérations consommatrices de ressources null
11. Ne pas utiliser rand()
12 Essayez de ne pas utiliser ou d'interroger
13. Ajoutez LIMIT 1 lors de l'interrogation d'une donnée <.>14. Activez le cache de requêtes
15. Effectuez une évaluation raisonnable des données à un stade précoce, et partitionnez et divisez les tables
16 Évitez d'utiliser des requêtes floues avec le préfixe %
17. Fonctions intégrées de MySQL
18. Utiliser plusieurs esclaves pour résoudre les requêtes lentes Question

Comment réaliser une vente flash ?

Le volume simultané de ventes flash que nous réalisons est de centaines de milliers, et la version ci-dessous est de centaines de milliers :

1 Spécialisé pour les serveurs de vente flash [ps : si le volume est important, dites-le, si c'est petit Pas besoin de faire ça]
2. Générez une page statique. [ ps : S'il est encore volumineux, vous pouvez mettre ce fichier sur cdn ]
3. Le compte à rebours et l'inventaire sont obtenus à partir du serveur [Obtenus uniquement une fois par période de temps. Une fois le compte à rebours terminé, il sera demandé au serveur de voir s'il a démarré]
4. Stockez la base de données à tuer. dans redis [valeur clé] stock= 10
5. Configurer une file d'attente redis [utiliser la liste comme file d'attente] lpop rpush
6 Lorsque l'utilisateur fait une demande, il est jugé s'il a participé au flash. vente, et sinon, les données utilisateur sont écrites dans la file d'attente, et l'inventaire est réduit 1. Si vous avez participé, vous serez invité à avoir participé
ps : Cette section utilise l'opération atomique de redid, comme. ainsi que transaction multi et watch
redis optimiste lock cas ==== c'est juger si la valeur a changé avant de la paramétrer
7 Les ventes flash ne peuvent pas être réalisées lorsque l'inventaire est réduit de 0
8. . Le script asynchrone traite les données de la file d'attente [crontab + fichier php]

Si vous dites que c'est 10 000-30 000, il n'est pas nécessaire de louer un serveur séparément

Si on vous pose des questions sur les affaires. questions, adaptez-vous en conséquence ! ! ! !

Par exemple : Que dois-je faire si 10 utilisateurs l'achètent mais ne paient pas ?
La première déclaration :
On dit que la demande pour le produit à cette époque était qu'il n'y avait aucun problème sans payer et que les autres utilisateurs ne pouvaient pas l'acheter. Ce que nous faisions à ce moment-là a été discuté avec le. produit, et si le produit disait que c'était normal, les utilisateurs paieraient, car Moins cher
La deuxième déclaration :
lancera la prochaine série de ventes flash. Par exemple, chez Xiaomi, vous pouvez continuer à l'acheter après 2 heures ! !
Le troisième arrêt :
Oui. . . .

Comment s'assurer qu'il n'y a pas de surachat ?
Lors de la réduction des stocks, il s'agit d'une opération atomique et utilise le verrouillage optimiste. Lors du test, il n'y a pas eu de situation de surachat

De plus, il n'y a pas besoin de panier pendant la vente flash. Lorsque vous cliquez dessus, vous ferez la queue


T1. : Comment éviter le brossage ? En général, il existe des réductions intéressantes lors des ventes urgentes. Si quelqu’un triche de manière malveillante, les utilisateurs normaux perdront la possibilité d’acheter. Par exemple, si le nombre de produits récupérés est de 1 000 et que quelqu’un en glisse 900 de manière malveillante, seuls 100 seront récupérés par les utilisateurs normaux.
Une fois les 900 saisis de manière malveillante vérifiés lors du processus de paiement ultérieur, le délai de récupération peut être passé. Même si les 900 personnes saisies de manière malveillante étaient payées avec succès, cela serait toujours injuste pour les utilisateurs normaux.
Dans ce scénario commercial, ce que nous faisons est d'afficher les produits et de délivrer le droit d'acheter les produits. La consommation réelle est générée par un tiers. Ensuite, le problème de la fraude des utilisateurs doit être contrôlé par nous et par la page de paiement tierce. Une fois que l'utilisateur a obtenu le quota d'achat via le mécanisme de file d'attente
, lors du passage à un tiers, nous transférerons les informations cryptées selon la méthode de cryptage convenue avec le tiers, et le tiers permettra uniquement à l'utilisateur de payer après l'avoir déchiffré avec succès selon la méthode de décryptage convenue, le processus de cryptage et de décryptage peut
contenir du contenu avec un cycle de vie. De cette manière, lorsqu'un utilisateur obtient un produit sur une page de paiement de demande à haute fréquence, il ne peut effectivement l'obtenir que via : 1) la paire cryptée 2) la première fois ; Cependant, le tiers consiste uniquement à vendre des marchandises, le succès de ce type de coopération
est donc peu probable. Un brossage malveillant montrera en effet que le produit est en rupture de stock au niveau de notre entreprise. En conséquence, les utilisateurs qui souhaitent acheter perdent l’opportunité, mais cela peut garantir que les tiers ne soient pas lésés. Si nous voulons éviter cette situation de brossage au niveau de notre couche métier, je pense qu'il s'agit d'un problème général
anti-SPAM. Je ne sais vraiment pas grand-chose à ce sujet.

Q2 : Si vous souhaitez placer les pinceaux avec précision, il existe de nombreuses dimensions de jugement et la logique est compliquée ; contrairement à cela, l'achat précipité nécessite une réponse rapide.
Oui, en raison de la forte pression des demandes et de la forte concurrence des achats de tickets chauds dans le secteur des achats précipités, il est important de ne pas ajouter trop de logique ou de trop s'appuyer sur le backend. Plus c'est simple, meilleur est l'effet. Lorsque nous concevons le système, il y a beaucoup de choses que notre système ne peut pas couvrir
Nous avons besoin de certains modules et capacités pré-requis pour être prêts avant que notre système puisse fonctionner correctement. Il est recommandé de créer un système de compte et des enregistrements de consommation des utilisateurs.
Q3 : Le rapprochement vise-t-il uniquement à comparer l'inventaire des marchandises avec celui d'un tiers ? Le montant est-il comparé ?
La réconciliation est en fait une comparaison des données de consommation. Pour éviter la situation où nos statistiques montrent aujourd'hui la consommation de X articles d'une valeur totale de Y, le tiers donne la consommation de N articles d'une valeur totale de M. Évitez les incohérences dans les montants, qui pourraient causer des problèmes tels que le règlement et le partage.
Je pense que le problème des différences d'inventaire dans votre question nécessite qu'un tiers mette régulièrement à jour les produits qu'il fournit via l'interface de notre couche de données. En fait, dans notre bibliothèque de produits, les produits ne sont pas nécessairement uniquement autorisés à être fournis par des tiers. Nous pouvons également permettre à des tiers de réduire les produits via l'interface. Par exemple, si nous coopérons avec un tiers qui vend des fruits, le tiers. La fête a annoncé la semaine dernière qu'il y avait 100 produits, mais ils se vendent bien hors ligne cette semaine, et il ne reste que 20 pièces. Nous devrions également permettre aux tiers de mettre à jour vers une valeur inférieure. Mais de cette façon, notre système
sera assez compliqué.

Q4 : Anti-swipe pour éviter les problèmes avec les promotions tierces qui ne sont pas efficaces.
Oui, la dimension ID utilisateur et la dimension IP sont toutes deux des méthodes efficaces. Regardez le scénario spécifique. Pour les entreprises disposant d'un système de compte, le meilleur effet est d'utiliser la dimension ID utilisateur. Utilisez simplement le stockage pour enregistrer les enregistrements d'achat de chaque utilisateur à des fins de contrôle. Les sites de commerce électronique
sur le marché nécessitent essentiellement une connexion pour les achats urgents et limitent le nombre d'achats par une seule personne pour chaque article. En fait, ils stockent et enregistrent la consommation de l'utilisateur et génèrent des requêtes de pré-consommation. encore une fois et ajoutez une logique de code pour le contrôler.

Q5 : Ai-je besoin d’un nouveau code de vérification pour chaque événement de vente urgente ?
Le code de vérification est un test de Turing. Tant que la méthode de test est bonne et que les informations de vérification générées à chaque fois sont garanties de ne jamais apparaître et sont irrégulières, alors c'est un bon code de vérification.

Comment trouver celui avec le plus de répétitions dans les données massives

L'adresse IP de l'utilisateur est enregistrée dans le journal du site Web, trouvez l'adresse IP avec le plus de visites

Supposons qu'il y en ait Numéros d'identification 1kw et leurs données correspondantes. Le numéro d'identification peut être répété, vous devez donc trouver le numéro d'identification qui apparaît le plus.

Il existe un fichier de 1 Go, chaque ligne qu'il contient est un mot, la taille du mot ne dépasse pas 16 octets et la limite de mémoire est de 1 Mo. Renvoie les 100 mots les plus fréquents.

Il y a 10 fichiers, chaque fichier fait 1G. Chaque ligne de chaque fichier stocke la requête de l'utilisateur. La requête de chaque fichier peut être répétée. Il vous est demandé de trier par fréquence de requête.

Tri à bulles :
Principe :
Comparez le premier nombre avec tous les nombres, puis rencontrez une grande position d'échange, de sorte que le plus grand soit placé à la fin pour la première fois, puis continuez à comparer. Dans la deuxième comparaison, le dernier nombre ne sera pas comparé car il a été déterminé comme étant le plus grand, et ainsi de suite.

1. Méthode de tri à bulles

 *     思路分析:法如其名,就是像冒泡一样,每次从数组当中 冒一个最大的数出来。 
 *     比如:2,4,1    // 第一次 冒出的泡是4 
 *                2,1,4   // 第二次 冒出的泡是 2 
 *                1,2,4   // 最后就变成这样
Copier après la connexion

Complexité temporelle :
Le tri à bulles est une méthode de tri qui échange du temps contre de l'espace. Le pire La situation est la suivante. changer la disposition séquentielle en ordre inverse, ou pour changer la séquence inverse en ordre séquentiel.


$arr=array(1,43,54,62,21,66,32,78,36,76,39);  
function getpao($arr)
{  
  $len=count($arr);
  //设置一个空数组 用来接收冒出来的泡
  //该层循环控制 需要冒泡的轮数
  for($i=1;$i<$len;$i++)
  { //该层循环用来控制每轮 冒出一个数 需要比较的次数
    for($k=0;$k<$len-$i;$k++)
    {
       if($arr[$k]>$arr[$k+1])
        {
            $tmp=$arr[$k+1];
            $arr[$k+1]=$arr[$k];
            $arr[$k]=$tmp;
        }
    }
  }
  return $arr;
}
Copier après la connexion
2. Tri par sélection :


http://jingyan.baidu.com/article/f3ad7d0f07516d09c3345b19.html
http://mmm2010.blog.163.com/blog/static/174230348201292273310140/
function select_sort($arr) {
//实现思路 双重循环完成,外层控制轮数,当前的最小值。内层 控制的比较次数
    //$i 当前最小值的位置, 需要参与比较的元素
    for($i=0, $len=count($arr); $i<$len-1; $i++) {
        //先假设最小的值的位置
        $p = $i;
        //$j 当前都需要和哪些元素比较,$i 后边的。
        for($j=$i+1; $j<$len; $j++) {
            //$arr[$p] 是 当前已知的最小值
            if($arr[$p] > $arr[$j]) {
     //比较,发现更小的,记录下最小值的位置;并且在下次比较时,
 // 应该采用已知的最小值进行比较。
                $p = $j;
            }
        }
        //已经确定了当前的最小值的位置,保存到$p中。
 //如果发现 最小值的位置与当前假设的位置$i不同,则位置互换即可
        if($p != $i) {
            $tmp = $arr[$p];
            $arr[$p] = $arr[$i];
            $arr[$i] = $tmp;
        }
    }
    //返回最终结果
    return $arr;
}
3.快速排序法  
function quick_sort($arr) {
    //先判断是否需要继续进行
    $length = count($arr);
    if($length <= 1) {
        return $arr;
    }
    //如果没有返回,说明数组内的元素个数 多余1个,需要排序
    //选择一个标尺
    //选择第一个元素
    $base_num = $arr[0];
    //遍历 除了标尺外的所有元素,按照大小关系放入两个数组内
    //初始化两个数组
    $left_array = array();//小于标尺的
    $right_array = array();//大于标尺的
    for($i=1; $i<$length; $i++) {
        if($base_num > $arr[$i]) {
            //放入左边数组
            $left_array[] = $arr[$i];
        } else {
            //放入右边
            $right_array[] = $arr[$i];
        }
    }
    //再分别对 左边 和 右边的数组进行相同的排序处理方式
    //递归调用这个函数,并记录结果
    $left_array = quick_sort($left_array);
    $right_array = quick_sort($right_array);
    //合并左边 标尺 右边
    return array_merge($left_array, array($base_num), $right_array);
}
Copier après la connexion
4. Méthode de tri par insertion

Description du scénario :
suivi d'un tri bouillonnant. , chaque fois que les élèves essayaient et essayaient, mais il y avait de plus en plus d'élèves. Le professeur a constaté qu'à chaque fois qu'il finissait de faire la queue, la majeure partie de la classe était en retard. Il a dit : « Nous n'avons pas besoin de bouillonner. . Insérons le tri aujourd'hui ".
A cette époque, le professeur d'éducation physique a assumé la responsabilité d'un professeur de mathématiques et a enseigné aux élèves une méthode de mise en file d'attente - le tri par insertion.
1. Commencez avec le premier camarade de classe comme référence, et commencez par le deuxième camarade de classe qui avance pour comparer avec le premier camarade de classe, restez immobile, s'il est plus bas, changez de position
2. le troisième camarade doit commencer en premier Comparez avec le deuxième camarade devant vous, s'il est plus bas, changez avec le deuxième, puis avancez et comparez avec le premier, s'il est plus bas, changez à nouveau, sinon bloquez et ne comparez plus
3. Ordonner d'avant en arrière Exécutez l'étape 2, un élève sort l'un après l'autre, comparez à chaque fois avec le camarade devant lui, trouvez une position adaptée pour insérer, les autres élèves reculent
vers le position appropriée : l'élève précédent est égal ou inférieur à sa propre taille, et l'élève suivant Chaque élève est plus grand que lui
Selon cette méthode, les élèves peuvent trouver la bonne position un par un, plus besoin de comparer les positions adjacentes un à chaque fois, et après avoir trouvé la position, il n'est pas nécessaire de comparer avec l'avant...

Idée de méthode de tri par insertion : Insérez les éléments à trier dans la position spécifiée du tableau où le numéro de tri a été supposé.

function insert_sort($arr) {
    //区分 哪部分是已经排序好的
    //哪部分是没有排序的
    //找到其中一个需要排序的元素
    //这个元素 就是从第二个元素开始,到最后一个元素都是这个需要排序的元素
    //利用循环就可以标志出来
    //i循环控制 每次需要插入的元素,一旦需要插入的元素控制好了,
    //间接已经将数组分成了2部分,下标小于当前的(左边的),是排序好的序列
    for($i=1, $len=count($arr); $i<$len; $i++) {
        //获得当前需要比较的元素值。
        $tmp = $arr[$i];
        //内层循环控制 比较 并 插入
        for($j=$i-1;$j>=0;$j--) {
   //$arr[$i];//需要插入的元素; $arr[$j];//需要比较的元素
            if($tmp < $arr[$j]) {
                //发现插入的元素要小,交换位置
                //将后边的元素与前面的元素互换
                $arr[$j+1] = $arr[$j];
                //将前面的数设置为 当前需要交换的数
                $arr[$j] = $tmp;
            } else {
                //如果碰到不需要移动的元素
           //由于是已经排序好是数组,则前面的就不需要再次比较了。
                break;
            }
        }
    }
    //将这个元素 插入到已经排序好的序列内。
    //返回
    return $arr;
}
/**
     * 插入排序,默认第一位已经排好序,从第二位开始依次向前比较,确定自己的位置后插入,即前一位小余或等于当前,且后一位大于当前。
     * 插入后,自己新位置后面的元素依次向后移位, 完成一轮插入排序
     * @param arr
     * @return
     */
    public static int[] insertSort(int[] arr) {
        int len = arr.length;
        for (int i = 1; i < len; i++) {
            if (arr[i - 1] > arr[i]) {
                int k = arr[i];
                int j = i;
                while (j > 0 && arr[j - 1] > k) {
                    arr[j] = arr[j - 1];
                    j--;
                }
                arr[j] = k;
            }
        }
        return arr;
    }
Copier après la connexion

1,2,3,4,5,6,7
Je veux trouver le 7 maintenant
Je vais d'abord retirer le numéro du milieu 4
pour juger Est-ce le numéro que vous recherchez ? Si vous trouvez qu'il est petit
, allez à droite et recherchez
puis retirez tous les chiffres à droite
Retirez le numéro du milieu 6 d'entre eux
Si vous trouvez qu'il est encore petit
continuez à chercher Le tableau de droite
en a trouvé 7, ok ! ! !

Le pire des cas est que ce numéro n'existe pas =====

 1 <?php
 2     #二分查找
 3     function binarySearch(Array $arr, $target) {
 4         $low = 0;
 5         $high = count($arr) - 1;
 6         
 7         while($low <= $high) {
 8             $mid = floor(($low + $high) / 2);
 9             #找到元素
10             if($arr[$mid] == $target) return $mid;
11             #中元素比目标大,查找左部
12             if($arr[$mid] > $target) $high = $mid - 1;
13             #重元素比目标小,查找右部
14             if($arr[$mid] < $target) $low = $mid + 1;
15         }
16         
17         #查找失败
18         return false;
19     }
20     
21     $arr = array(1, 3, 5, 7, 9, 11);
22     $inx = binarySearch($arr, 1);
23     var_dump($inx);
24 ?>
Copier après la connexion

安全方面:
xss :跨站脚本攻击
csrf : 跨站请求伪造
Ddos:用很多机器对网址进行请求,把服务器某方面搞挂。
sql注入: 通过关键字或者非法字符的注入,实现一些对数据库一些非正常的操作

最简单的demo :
在用户登陆的时候,用户名和密码的判断,密码后加上 or 1=1

如何防止sql注入:
关键字的过滤
pdo预处理
php 配置文件 php.ini 中的 magic_quotes_gpc选项没有打开,被置为 off
addslashes stripslashes
mysql_real_escape_string
对一些数据类型做强制的校验

如何防止xss攻击?
xss攻击最简单的方式就是通过地址栏输入<script></script>,最简单的列子我们在php在使用一个get的a参数的时候,如何客户端传过来是<script>alert(1)</script>,
这样的话就会在我们的浏览器弹出来1,如果是页面的跳转,或者是一些其它脚本、病毒的话,可能对我们网站的安全造成很大的隐患。

最简单的解决办法
不要相信客户端的任何输入,在程序做严格的判断以及处理
htmlspecialchars进行过滤

csrf :
这个我们在学curl的时候做的模拟登陆就是跨站请求伪造!!!!
最简单的大白话就是:
a网站往b网站请求数据。
加个token防止下就行了,简单,粗暴,有效

Dos和Ddos防止:
阿里云 高防ip
idc机房
放弃一部分请求不处理。


正则方面的问题:

贪婪模式和非贪婪模式的区别:
贪婪模式匹配到内容之后会继续向后匹配
非贪婪模式则不回继续匹配


匹配中文字符的正则表达式: [\u4e00-\u9fa5]
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了
匹配双字节字符(包括汉字在内):[^\x00-\xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
匹配空白行的正则表达式:\n\s*\r
评注:可以用来删除空白行
匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?|<.*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力
匹配首尾空白字符的正则表达式:^\s*|\s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注:表单验证时很实用
匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
评注:表单验证时很实用
匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
评注:匹配形式如 0511-4405222 或 021-87888822
匹配腾讯QQ号:[1-9][0-9]{4,}
评注:腾讯QQ号从10000开始
匹配中国邮政编码:[1-9]\d{5}(?!\d)
评注:中国邮政编码为6位数字
匹配身份证:\d{15}|\d{18}
评注:中国的身份证为15位或18位
匹配ip地址:\d+\.\d+\.\d+\.\d+
评注:提取ip地址时有用
匹配特定数字:
^[1-9]\d*$    //匹配正整数
^-[1-9]\d*$   //匹配负整数
^-?[1-9]\d*$   //匹配整数
^[1-9]\d*|0$  //匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$   //匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$   //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$  //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$  //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$   //匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$  //匹配非正浮点数(负浮点数 + 0)
评注:处理大量数据时有用,具体应用时注意修正
匹配特定字符串:
^[A-Za-z]+$  //匹配由26个英文字母组成的字符串
^[A-Z]+$  //匹配由26个英文字母的大写组成的字符串
^[a-z]+$  //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$  //匹配由数字和26个英文字母组成的字符串
^\w+$  //匹配由数字、26个英文字母或者下划线组成的字符串

下面是一些特殊字符:
正则表达式中的特殊字符: (学习参考书-<<精通正则表达式>>)
字符
Signification : Pour les caractères, cela signifie généralement une signification littérale, indiquant que les caractères suivants sont des caractères spéciaux sans explication.
Par exemple : /b/ correspond au caractère 'b'. En ajoutant une barre oblique inverse devant b, c'est-à-dire /b/, le caractère devient un caractère spécial, indiquant que
correspond à la ligne de séparation de a. mot.
Ou :
Pour plusieurs caractères, il est généralement indiqué qu'ils sont spéciaux, indiquant que les caractères suivants ne sont pas spéciaux et doivent être interprétés littéralement.
Par exemple : * est un caractère spécial, correspondant à n'importe quel nombre de caractères (y compris 0 caractères), par exemple : /a*/ signifie correspondre à 0 ou plusieurs a.
Pour faire correspondre un littéral *, ajoutez une barre oblique inverse avant a ; par exemple : /a*/ correspond à 'a*'.

Caractère^
Signification : Indique que le caractère correspondant doit être au début.
Par exemple : /^A/ ne correspond pas au « A » dans « an A », mais correspond au premier « A » dans « An A ».

Caractère$
Signification : Semblable à ^, correspond au dernier caractère.
Par exemple : /t$/ ne correspond pas au « t » dans « eater », mais correspond au « t » dans « eat ».

Caractère*
Signification : Faites correspondre le caractère avant * 0 ou n fois.
Par exemple : /bo*/ correspond au 'boooo' dans "Un fantôme hué" ou au 'b' dans "Un oiseau gazouilli", mais ne correspond à aucun caractère dans "Une chèvre g
avortée".

Caractère +
Signification : Faites correspondre le caractère avant le signe + 1 ou n fois. Équivalent à {1,}.
Par exemple : /a+/ correspond au « a » dans « candy » et à tous les « a » dans « caaaaaaandy ».

caractères ?
Signification : Faire correspondre le caractère avant ?
Par exemple : /e?le?/ correspond au 'el' dans "angel" et au 'le' dans "angle".

caractères
signification : (point décimal) correspond à tous les caractères simples, à l'exception des sauts de ligne.
Par exemple : /.n/ correspond à "an" et "on" dans "non, une pomme est sur l'arbre", mais ne correspond pas à "non".


Caractère (x)
Signification : faites correspondre « x » et enregistrez la valeur correspondante.
Par exemple : /(foo)/ correspond et enregistre 'foo' dans "foo bar.". La sous-chaîne correspondante peut être renvoyée par les éléments [1], ..., [n] dans le tableau résultat, ou par les propriétés $1, ..., $9 de l'objet RegExp.

Caractère x|y
Signification : correspond à "x" ou "y".
Par exemple : /green|red/ correspond au « vert » dans « pomme verte » et au « rouge » dans « pomme rouge ».

Caractère {n}
Signification : n voici un entier positif. Correspond aux n premiers caractères.
Par exemple : /a{2}/ ne correspond pas au « a » dans « candy », mais correspond à tous les « a » dans « caandy » et aux deux premiers
« a » dans « caaandy ». .

Caractère {n,}
Signification : n voici un entier positif. Correspond à au moins n caractères précédents.
Par exemple : /a{2,} ne correspond pas au 'a' dans "candy", mais correspond à tous les 'a' dans "caandy" et à tous les 'a' dans "caaaaaaandy". Caractère {n,m}
Signification : n et m sont ici tous deux des entiers positifs. Correspond à au moins n et au plus m caractères précédents.
Par exemple : /a{1,3}/ ne correspond à aucun caractère de "cndy", mais correspond au "a" de "candy" et aux deux premiers
"a" de "caandy", Et les trois premiers 'a dans "caaaaaaandy", remarque : même s'il y a beaucoup de 'a dans "caaaaaaandy", cela ne correspond qu'aux trois premiers
'a, c'est-à-dire "aaa".

Caractère [xyz]
Signification : Une liste de caractères, correspondant à n'importe quel caractère de la liste. Vous pouvez spécifier une plage de caractères à l'aide du trait d'union -.
Par exemple : [abcd] est identique à [a-c]. Ils correspondent au « b » dans « poitrine » et au « c » dans « douleur ».

Caractère[^xyz]
Signification : Complément à un caractère, c'est-à-dire qu'il correspond à tout sauf aux caractères répertoriés. Vous pouvez utiliser des traits d'union - pour indiquer une plage de caractères
.
Par exemple : [^abc] et [^a-c] sont équivalents, ils correspondent d'abord au 'r' dans "brisket" et au 'h' dans "chop.".

Caractère
Signification : Correspond à un espace (à ne pas confondre avec b)

Caractère b
Signification : Correspond à une ligne de séparation d'un mot, comme un espace (pas à confondre avec)
Par exemple : /bnw/ correspond au « non » dans « midi », /wyb/ correspond au « ly » dans « peut-être hier ».

Caractère B
Signification : Correspond à la ligne insécable d'un mot
Par exemple : /wBn/ correspond au 'on' dans "midi", /yBw/ correspond au 'in "éventuellement hier." ouais.

Caractère cX
Signification : Le X ici est un caractère de contrôle. Correspond à une chaîne de caractères de contrôle.
Par exemple : /cM/ correspond à control-M dans une chaîne.

Caractère d
Signification : Correspond à un nombre, équivalent à [0-9].
Par exemple : /d/ ou /[0-9]/ correspond au « 2 » dans « B2 est le numéro de suite. ».

Caractère D
Signification : correspond à tout non-chiffre, équivalent à [^0-9].
Par exemple : /D/ ou /[^0-9]/ correspond au « B » dans « B2 est le numéro de suite. ».

Caractère f
Signification : Correspond à un caractère de formulaire

Caractère n
Signification : Correspond à un caractère de nouvelle ligne

caractère r
Signification : Correspond à un caractère de retour chariot

caractère s
Signification : Correspond à un seul caractère d'espace blanc, y compris l'espace, la tabulation, le formulaire feed, caractère de nouvelle ligne, équivalent à [fnrtv].
Par exemple : /sw*/ correspond à 'bar' dans "foo bar.".

Caractère S
Signification : correspond à un seul caractère à l'exception des espaces blancs, équivalent à [^ fnrtv].
Par exemple : /S/w* correspond à 'foo' dans "foo bar.".

caractère t
signification : correspond à un caractère de tabulation

caractère v
signification : correspond à un caractère de tabulation d'en-tête

caractère w
signification : correspond à tous des chiffres et des lettres ainsi que des traits de soulignement, équivalents à [A-Za-z0-9_].
Par exemple : /w/ correspond au "a" dans "apple", au "5" dans "$5.28" et au "3" dans "3D".

Caractère W
Signification : correspond à d'autres caractères à l'exception des chiffres, des lettres et des traits de soulignement, équivalent à [^A-Za-z0-9_].
Par exemple : /W/ ou /[^$A-Za-z0-9_]/ correspond au '%' dans "50%.".

Caractère n
Signification : n voici un entier positif. La valeur de n qui correspond à la dernière sous-chaîne d'une expression régulière (en comptant les parenthèses gauches).


Problèmes avec les fonctions PHP :

1. La fonction Array

array_key_exists détermine si la clé existe
is_array détermine s'il s'agit d'un tableau
in_array détermine si la valeur donnée apparaît dans les données
array_count_values ​​​​​​détermine le nombre de fois que la valeur apparaît
array_search array search
array_merge array merge
array_map utilise une fonction définie par l'utilisateur pour chaque élément du array
array_change_case change le tableau Key case
sort array sorting
array_push Insère un ou plusieurs éléments à la fin du tableau
array_pop Pop le dernier élément du tableau
array_unshift Insère plusieurs éléments à le début du tableau
array_shift Pop le premier élément des éléments du tableau
implose le tableau en chaîne
shuffle perturbe le tri du tableau
array_rand supprime aléatoirement plusieurs unités du tableau
array_chunk split le tableau dans un nouveau tableau
array_diff difference set
array_inestsert Intersection
array_flip Exchange key values
array_keys Renvoie toutes les clés du tableau
count Calculer la longueur du tableau

2. Fonction de chaîne
addcslashes - ajoute des barres obliques inverses à certains caractères de la chaîne Caractères d'échappement
addslashes — Caractères d'échappement dans une chaîne d'une manière spécifiée
bin2hex — Convertit les données binaires en représentation hexadécimale
chop — Alias ​​fonction de rtrim()
chr — Renvoie le code ASCII d'un caractère
chunk_split — Divise une chaîne en petits morceaux selon une certaine longueur de caractère
convert_cyr_string — Convertit les caractères cyrilliques en d'autres caractères
convert_uudecode — Décrypte une chaîne
convert_uuencode — Chiffre une chaîne
count_chars — Renvoie les informations d'utilisation des caractères dans une chaîne
crc32 — Calcule le polynôme crc32 d'une chaîne
crypt — Fonction de cryptage de hachage unidirectionnel
echo — Utiliser pour afficher du contenu
explode — Convertir une chaîne en tableau à l'aide de délimiteurs
fprintf — Renvoie les données requises et les écrit directement dans le flux du document
get_html_translation_table — Renvoie les entités HTML qui peuvent être convert
hebrev — Convertit une chaîne codée en hébreu en texte visuel
hebrevc — Convertit une chaîne codée en hébreu en texte visuel
html_entity_decode — La fonction inverse de la fonction htmlentities (), convertit les entités HTML Convertir en caractères
htmlentities — Convertit certains caractères de la chaîne en entités HTML
htmlspecialchars_decode — La fonction inverse de la fonction htmlspecialchars(), convertit les entités HTML en caractères
htmlspecialchars — Convertit certains caractères de la chaîne en entité HTML
implode — Convertir un tableau en chaîne à l'aide d'un délimiteur spécifique
join — Convertir un tableau en chaîne, alias de la fonction implode()
levenshtein — Calculer la différence entre deux mots
localeconv — Obtenir un nombre -définitions de format liées
ltrim — Supprime les espaces ou les caractères spécifiés sur le côté gauche de la chaîne
md5_file — Chiffre un fichier avec l'algorithme MD5
md5 — Chiffre une chaîne avec l'algorithme MD5
métaphone — déterminer les règles de prononciation d'une chaîne
money_format — formater la sortie des nombres en fonction de paramètres
nl_langinfo — langage de requête et informations locales
nl2br — convertir le caractère de nouvelle ligne « n » dans la chaîne » est remplacé par "
"
number_format — sortie formatée des nombres en fonction de paramètres
ord — convertit un code ASCII en caractère
parse_str — convertit une chaîne dans un certain format Pour les variables et les valeurs
print — utilisé pour générer une valeur unique
printf — affiche les données selon les besoins
quoted_printable_decode — crypte une chaîne en une chaîne binaire de 8 bits
quotemeta — Échappe plusieurs caractères spécifiques
rtrim — supprimez les espaces ou les caractères spécifiés sur le côté droit de la chaîne
setlocale — définissez le format local pour les nombres, les dates, etc.
sha1_file — exécutez l'algorithme SHA1 sur un fichier Chiffrement
sha1 — Chiffrez une chaîne avec l'algorithme SHA1
similar_text — Comparez deux chaînes et renvoie le nombre de caractères similaires pris en compte par le système
soundex — Détermine les règles de prononciation d'une chaîne
sprintf — Renvoie les données selon les besoins, mais ne les affiche pas
sscanf — Vous pouvez formater la chaîne
str_ireplace — Correspond et remplace comme la fonction str_replace() Chaînes , mais insensible à la casse
str_pad — remplissage des deux côtés d'une chaîne
str_repeat — combinaison répétée de chaînes
str_replace — correspondance et remplacement de chaînes
str_rot13 — chaînes de chaînes Effectuer le traitement de cryptage ROT13
str_shuffle — Trier aléatoirement les caractères d'une chaîne
str_split — Diviser une chaîne en un tableau en fonction de l'espacement des caractères
str_word_count — Obtenir les informations sur le mot anglais dans la chaîne
strcasecmp — Compare les chaînes par taille, sans tenir compte de la casse
strchr — Renvoie une partie d'une chaîne par comparaison Un alias pour la fonction strstr()
strcmp — Compare les chaînes par taille
strcoll — Basé sur les paramètres locaux, compare la taille des chaînes
strcspn — Renvoie la valeur de la longueur continue des caractères qui ne correspondent pas
strip_tags — Supprime le code HTML et PHP dans une chaîne
stripcslashes — Anti-échappement de la fonction addcslashes() escape Chaîne traitée
stripos — Recherche et renvoie la position du première correspondance, la correspondance n'est pas sensible à la casse
stripslashes — Annulation de la fonction addlashes() pour échapper à la chaîne traitée
stristr — La comparaison de passage renvoie une partie d'une chaîne, la comparaison n'est pas sensible à la casse
strlen — Obtient le longueur codée d'une chaîne
strnatcasecmp — Compare les chaînes en utilisant le tri naturel, sans tenir compte de la casse
strnatcmp — Compare les chaînes en utilisant le tri naturel
strncasecmp — Compare les N premiers caractères d'une chaîne, sans tenir compte de la casse
strncmp — Comparez les N premiers caractères d'une chaîne
strpbrk — Renvoie une partie d'une chaîne en la comparant
strpos — Trouve et renvoie la position de la première correspondance
strrchr — Renvoie une partie d'une chaîne en la comparant à l'envers
strrev — Convertit une chaîne en Toutes les lettres à l'intérieur sont disposées dans l'ordre inverse
strripos - Recherche de l'arrière vers l'avant et renvoie la position de la première correspondance, la correspondance n'est pas sensible à la casse
strrpos - Recherche de l'arrière vers l'avant et renvoie la position de la première correspondance
strspn — Correspond et renvoie la valeur de la longueur des occurrences consécutives de caractères
strstr — Renvoie une partie d'une chaîne par comparaison
strtok — Divise un chaîne avec un nombre spécifié de caractères
strtolower — Convertir une chaîne en minuscules
strtoupper – Convertir la chaîne en majuscules
strtr — Comparer et remplacer la chaîne
substr_compare — Comparer la chaîne tronquée
substr_count — Compter l'occurrence d'un certain segment de caractère dans la chaîne Times
substr_replace — Remplacer certains caractères dans la chaîne
substr — Tronquer la chaîne
trim — Supprimer les espaces ou les caractères spécifiés des deux côtés de la chaîne
ucfirst — Remplacez la chaîne donnée Convertissez la première lettre de chaque mot anglais en majuscule
ucwords — Convertissez la première lettre de chaque mot anglais de la chaîne donnée en majuscule
vfprintf — Renvoyez les données si nécessaire et écrivez-les directement au flux de documents
vprintf — Affiche les données selon les besoins
vsprintf — Renvoie les données selon les besoins, mais ne les affiche pas
wordwrap — Divise la chaîne en fonction d'une certaine longueur de caractères



Que dites-vous des normes de codage ?

Lorsque nous avons écrit l'interface, nous avons écrit une vérification et un retour unifiés

Exigé que chaque fichier doit avoir sa propre annotation, chaque classe doit avoir sa propre annotation et chaque méthode doit Avec des commentaires, pour des besoins incertains ou des problèmes qui pourraient être rencontrés ultérieurement, il faut ajouter todo

La logique des touches doit être commentée

Lors de l'appel d'interfaces externes, elle ne peut pas être codée en dur dans le programme et doit être écrit séparément. Il est recommandé de créer un fichier de configuration pour faciliter les modifications ultérieures

Les opérations de base de données doivent être écrites dans le modèle et les opérations de base de données ne peuvent pas être écrites dans la couche C.

Les noms de variables doivent pouvoir exprimer clairement leur signification.

Le document d'interface doit être complété avant de rédiger l'interface.

Des méthodes privées doivent être ajoutées_ [Important, il semble que je sois également un pilote expérimenté]



Les fichiers de classe sont tous suffixés par .class.php (fait ici référence à Le fichier de bibliothèque de classes utilisé en interne par ThinkPHP ne représente pas le fichier de bibliothèque de classes chargé en externe), utilisez la dénomination en casse chameau et la première lettre est en majuscule, comme DbMysql.class.php ; 🎜> class L'adresse est cohérente.Par exemple, le chemin où se trouve la classe HomeControllerUserController doit être Application/Home/Controller/UserController.class.php
Assurez-vous que le nom du fichier et le cas d'appel sont cohérents car ils sont similaires à ceux d'Unix; les systèmes sont sensibles à la casse (ThinkPHP vérifiera strictement la casse même sur la plate-forme Windows en mode débogage)
Le nom de la classe et le nom du fichier sont cohérents (y compris la casse mentionnée ci-dessus). est UserController.class.php , le nom de fichier de la classe InfoModel est InfoModel.class.php,
et la dénomination de classe des différentes bibliothèques de classes a certaines normes

fonctions, fichiers de configuration et autres bibliothèques de classes ; les fichiers autres que les autres fichiers de la bibliothèque de classes sont généralement nommés .php est le suffixe (non requis s'il est introduit par un tiers

) ;函数的命名使用小写字母和下划线的方式,例如 get_client_ip;

方法的命名使用驼峰法,并且首字母小写或者使用下划线“_”,例如 getUserName,_parseType,通常下划线开头的方法属于私有方法;
属性的命名使用驼峰法,并且首字母小写或者使用下划线“_”,例如 tableName、_instance,通常下划线开头的属性属于私有属性;
以双下划线“__”打头的函数或方法作为魔法方法,例如 __call 和 __autoload;

常量以大写字母和下划线命名,例如 HAS_ONE和 MANY_TO_MANY;

配置参数以大写字母和下划线命名,例如HTML_CACHE_ON;

语言变量以大写字母和下划线命名,例如MY_LANG,以下划线打头的语言变量
通常用于系统语言变量,例如 _CLASS_NOT_EXIST_;

对变量的命名没有强制的规范,可以根据团队规范来进行;

ThinkPHP的模板文件默认是以.html 为后缀(可以通过配置修改);

数据表和字段采用小写加下划线方式命名,并注意字段名不要以下划线开头,例
如 think_user 表和 user_name字段是正确写法,类似 _username 这样的数据表字段可能会被过滤。


tp底层看过没有?


1、看过框架的底层没有?
看过tp的数据库驱动相关。 关于配置数据库方面的,在配置文件配置就直接可以使用各种数据库类型,自己简单看了下,主要就是通过一个driver(驱动类)来判断当前连接类
型,然后调用对于的数据库操作类。
ps:如果是要我们自己实现的话,可以借助接口,每个数据库的操作类都需要集成一个接口,然后根据具体的配置去调用每个操作类。 就算后期我修改了数据库的类型,也不
会导致程序需要改动。

2、看过tp的cache类,和数据库类似,修改过redis的cache类,因为tp的redis操作类不支持认证。
主要就是在redis操作类添加了个认证

$this->handler  = new \Redis;
        $options[&#39;timeout&#39;] === false ?
            $this->handler->$func($options[&#39;host&#39;], $options[&#39;port&#39;]) :
            $this->handler->$func($options[&#39;host&#39;], $options[&#39;port&#39;], $options[&#39;timeout&#39;]);
            $this -> handler->auth( C(‘REDIS_AUTH_KEY’) );
Copier après la connexion

3、看过tp的处理异常类
路径 ThinkPHP/library/Think/Think.class.php

主要使用的是php自带的错误处理相关函数

register_shutdown_function 定义PHP程序执行完成后执行的函数
set_error_handler 设置用户自定义的错误处理程序
set_exception_handler 设置自己的异常处理机制

借助 get_last_error获取最后一次报错的信息
根据报错级别可以自定义写日志
这个地方我们在做接口的时候纪录了一些错误日志,帮助我们排查一些问题。
如果要看文件加载以及调用关系可以借助 print_debug_backtrace获取文件加载的顺序

     // 注册AUTOLOAD方法
      spl_autoload_register(&#39;Think\Think::autoload&#39;);      
      // 设定错误和异常处理
      register_shutdown_function(&#39;Think\Think::fatalError&#39;);
      set_error_handler(&#39;Think\Think::appError&#39;);
      set_exception_handler(&#39;Think\Think::appException&#39;);
Copier après la connexion

4、简单看了下tp的命名空间自动记载
框架下的核心类都包含进来了,其他的事借助 spl_register_autoload实现。

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal