Die PHP+Socket-Serie implementiert einen WebSocket-Chatroom
Dieser Artikel vermittelt Ihnen relevantes Wissen über PHP+Socket. Er stellt hauptsächlich vor, wie man mit PHP Native Socket einen einfachen Web-Chatroom implementiert. Freunde, die interessiert sind, können einen Blick darauf werfen. Ich hoffe, es wird für alle hilfreich sein. Der native OPhp-Socket implementiert WebSocket-Chatrooms
VorwortIn diesem Artikel wird die Verwendung des nativen PHP-Sockets zum Erreichen eines einfachen Web-Chatrooms erläutert. Der endgültige Code befindet sich am Ende des Artikels.
Wenn nichts anderes, sollte dies der letzte Artikel in dieser Artikelserie sein. Als ich diese Artikelserie schrieb, dachte ich, es wäre eine sehr einfache Sache, aber nachdem ich diese wenigen Artikel geschrieben hatte, habe ich den Code von fast durchgelesen Arbeiter, seien Sie also nie zu eingebildet, Sie müssen es trotzdem selbst ausprobieren, am besten aufschreiben, um zu beweisen, dass Sie etwas wirklich verstehen 2008 und wurde 2011 zu einem internationalen Protokoll. Der Standard
RFC6455definiert seinen Kommunikationsstandard und wird jetzt von allen Browsern unterstützt. webSocket ist ein Protokoll für die Vollduplex-Kommunikation über eine einzelne TCP-Verbindung, mit deren Bereitstellung HTML5 begonnen hat. Der Server kann Nachrichten aktiv an den Client senden, und der Client kann auch aktiv Nachrichten an den Server senden.
webSocket legt die Spezifikation eines Kommunikationsprotokolls fest. Durch den Handshake-Mechanismus kann eine TCP-ähnliche Verbindung zwischen dem Client (Browser) und dem Server (Webserver) hergestellt werden, wodurch die CS-Kommunikation erleichtert wird.Warum brauchen wir einen WebSocket? Das HTTP-Protokoll ist ein zustandsloses, verbindungsloses, einseitiges Anwendungsschichtprotokoll. Es verwendet das Modell Request=>Response
. Kommunikationsanfragen können nur vom Client initiiert werden, und der Server antwortet auf die Anfrage. Dieses Kommunikationsmodell hat einen Nachteil: Es ist für den Server unmöglich, proaktiv zu senden Nachrichten an den Client Der Client initiiert eine Nachricht. Die Parallelitätsfähigkeiten herkömmlicher HTTP-Anfragen werden durch die gleichzeitige Initiierung mehrerer TCP-Verbindungen für den Zugriff auf den Server erreicht. Websocket ermöglicht es uns, mehrere Anfragen gleichzeitig auf einer WS-Verbindung auszugeben. Das heißt, nachdem die A-Anfrage gesendet wurde, erfolgt die A-Antwort noch nicht eingetroffen. Sie können weiterhin B-Anfragen stellen. Aufgrund der langsamen Startfunktion von TCP und des Handshake-Verlusts der Verbindung selbst hat diese Funktion des Websocket-Protokolls die Effizienz erheblich verbessert.
Funktionen
basiert auf dem TCP-Protokoll und die Implementierung des Servers ist relativ einfach.
hat eine gute Kompatibilität mit HTTP Protokoll, standardmäßig Die Ports sind ebenfalls 80 und 443, und das HTTP-Protokoll wird in der Handshake-Phase verwendet, sodass es während des Handshakes nicht leicht blockiert wird und verschiedene HTTP-Proxyserver passieren kann.
请求 => 响应
模型,通信请求仅能由客户端发起,服务端对请求做出应答处理,这种通信模型有一个弊端:无法实现服务端主动向客户端发起消息。传统的 HTTP 请求,其并发能力都是依赖同时发起多个 TCP 连接访问服务器实现的而 websocket 则允许我们在一条 ws 连接上同时并发多个请求,即在 A 请求发出后 A 响应还未到达,就可以继续发出 B 请求。由于 TCP 的慢启动特性,以及连接本身的握手损耗,都使得 websocket 协议的这一特性有很大的效率提升。
特点
建立在 TCP 协议之上,服务端的实现相对比较容易
与 HTTP 协议有良好的兼容性,默认端口也是 80 和 443,并且握手阶段采用 HTTP 协议,因此握手时不容易被屏蔽,能通过各种 HTTP 代理服务器。
数据格式比较轻量,性能开销小,通信高效。
可以发送文本,也可以发送二进制数据。
没有同源限制,客户端可以与任意服务器进行通信。
协议标识符是 ws(如果加密则为 wss),服务地址就是 URL。
PHP实现websocket
客户端与服务端握手
websocket 协议在连接前需要握手[^2],通常握手方式有以下几种方式
基于 flash 的握手协议(不建议)
-
基于 md5 加密方式的握手协议
较早的握手方法,有两个 key,使用 md5 加密
-
基于 sha1 加密方式的握手协议
当前主要的握手协议,本文将以此协议为主
获取客户端上报的
Sec-WebSocket-key
拼接
key
+258EAFA5-E914-47DA-95CA-C5AB0DC85B11
对字符串做
SHA1
计算,再把得到的结果通过base64
- Sie können Text- oder Binärdaten senden.
- Es gibt keine Same-Origin-Beschränkung, der Client kann mit jedem Server kommunizieren.
- basierend auf dem Flash-Handshake-Protokoll (nicht empfohlen)
Handshake-Protokoll basierend auf der MD5-VerschlüsselungsmethodeFrühere Handshake-Methode, mit zwei Schlüsseln, mit MD5-Verschlüsselung
🎜 - 🎜Handshake-Protokoll basierend auf der SHA1-Verschlüsselungsmethode🎜🎜 Das aktuelle Haupt-Handshake-Protokoll Dieser Artikel konzentriert sich auf dieses Protokoll >🎜Spleißen Sie
key
+258EAFA5-E914-47DA-95CA-C5AB0DC85B11
🎜🎜 - 🎜Machen Sie
SHA1
mit der Zeichenfolge. Berechnen Sie sie und verschlüsseln Sie sie dann das Ergebnis durchbase64
und schließlich an den Client zurückgeben 🎜🎜🎜🎜🎜🎜Die Clientanforderungsinformationen lauten wie folgt: 🎜🎜Der Client muss die folgenden Daten zurückgeben: 🎜GET /chat HTTP/1.1Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==Origin: http://example.com Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13
Nach dem Login kopieren🎜us Implementiert über PHP gemäß diesem Protokoll: 🎜HTTP/1.1 101 Switching Protocols Upgrade: websocket Sec-WebSocket-Version: 13Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Nach dem Login kopieren🎜Verwandte Syntaxerklärungen finden Sie in 🎜vorherigen Artikeln🎜, in diesem Artikel wird es nicht im Detail vorgestellt. 🎜🎜Verwenden Sie Front-End-Tests, öffnen Sie eine unserer Browserkonsolen (Konsole) und geben Sie den folgenden Inhalt ein. Der readyState des zurückgegebenen Websocket-Objekts ist 1, was bedeutet, dass der Handshake erfolgreich ist Ich werde es nicht im Detail vorstellen. Weitere Informationen finden Sie im 🎜Rookie-Tutorial🎜: 🎜<?php $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, true); socket_bind($socket, 0, 8888); socket_listen($socket); while (true) { $conn_sock = socket_accept($socket); $request = socket_read($conn_sock, 102400); $new_key = getShaKey($request); $response = "HTTP/1.1 101 Switching Protocols\r\n"; $response .= "Upgrade: websocket\r\n"; $response .= "Sec-WebSocket-Version: 13\r\n"; $response .= "Connection: Upgrade\r\n"; $response .= "Sec-WebSocket-Accept: {$new_key}\r\n\r\n"; socket_write($conn_sock, $response); } function getShaKey($request) { // 获取 Sec-WebSocket-key preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $request, $match); // 拼接 key + 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 $new_key = trim($match[1]) . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; // 对字符串做 `SHA1` 计算,再把得到的结果通过 `base64` 加密 return base64_encode(sha1($new_key, true)); }
Nach dem Login kopieren🎜🎜🎜🎜Senden und Empfangen von Daten🎜🎜console.log(new WebSocket('ws://192.162.2.166:8888')); // 运行后返回: WebSocket { binaryType: "blob" bufferedAmount: 0 extensions: "" onclose: null onerror: null onmessage: null onopen: null protocol: "" readyState: 1 url: "ws://192.162.2.166:8888/"}
Nach dem Login kopieren使用 websocket 协议传输协议需要遵循特定的格式规范,详情请参考 datatracker.ietf.org/doc/html/rfc6...
为了方便,这里直接贴出加解密代码,以下代码借鉴与 workerman 的
src/Protocols/Websocket.php
文件:// 解码客户端发送的消息 function decode($buffer) { $len = \ord($buffer[1]) & 127; if ($len === 126) { $masks = \substr($buffer, 4, 4); $data = \substr($buffer, 8); } else { if ($len === 127) { $masks = \substr($buffer, 10, 4); $data = \substr($buffer, 14); } else { $masks = \substr($buffer, 2, 4); $data = \substr($buffer, 6); } } $dataLength = \strlen($data); $masks = \str_repeat($masks, \floor($dataLength / 4)) . \substr($masks, 0, $dataLength % 4); return $data ^ $masks; } // 编码发送给客户端的消息 function encode($buffer) { if (!is_scalar($buffer)) { throw new \Exception("You can't send(" . \gettype($buffer) . ") to client, you need to convert it to a string. "); } $len = \strlen($buffer); $first_byte = "\x81"; if ($len <= 125) { $encode_buffer = $first_byte . \chr($len) . $buffer; } else { if ($len <= 65535) { $encode_buffer = $first_byte . \chr(126) . \pack("n", $len) . $buffer; } else { $encode_buffer = $first_byte . \chr(127) . \pack("xxxxN", $len) . $buffer; } } return $encode_buffer; }
Nach dem Login kopieren我们修改刚才 客户端与服务端握手 阶段的代码,修改后全代码全文如下,该段代码实现了将客户端发送的消息转为大写后返回给客户端(当然只是为了演示):
<?php $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, true); socket_bind($socket, 0, 8888); socket_listen($socket); while (true) { $conn_sock = socket_accept($socket); $request = socket_read($conn_sock, 102400); $new_key = getShaKey($request); $response = "HTTP/1.1 101 Switching Protocols\r\n"; $response .= "Upgrade: websocket\r\n"; $response .= "Sec-WebSocket-Version: 13\r\n"; $response .= "Connection: Upgrade\r\n"; $response .= "Sec-WebSocket-Accept: {$new_key}\r\n\r\n"; // 发送握手数据 socket_write($conn_sock, $response); // 新增内容,获取客户端发送的消息并转为大写还给客户端 $msg = socket_read($conn_sock, 102400); socket_write($conn_sock, encode(strtoupper(decode($msg)))); } function getShaKey($request) { // 获取 Sec-WebSocket-key preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $request, $match); // 拼接 key + 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 $new_key = trim($match[1]) . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; // 对字符串做 `SHA1` 计算,再把得到的结果通过 `base64` 加密 return base64_encode(sha1($new_key, true)); } function decode($buffer) { $len = \ord($buffer[1]) & 127; if ($len === 126) { $masks = \substr($buffer, 4, 4); $data = \substr($buffer, 8); } else { if ($len === 127) { $masks = \substr($buffer, 10, 4); $data = \substr($buffer, 14); } else { $masks = \substr($buffer, 2, 4); $data = \substr($buffer, 6); } } $dataLength = \strlen($data); $masks = \str_repeat($masks, \floor($dataLength / 4)) . \substr($masks, 0, $dataLength % 4); return $data ^ $masks; } function encode($buffer) { if (!is_scalar($buffer)) { throw new \Exception("You can't send(" . \gettype($buffer) . ") to client, you need to convert it to a string. "); } $len = \strlen($buffer); $first_byte = "\x81"; if ($len <= 125) { $encode_buffer = $first_byte . \chr($len) . $buffer; } else { if ($len <= 65535) { $encode_buffer = $first_byte . \chr(126) . \pack("n", $len) . $buffer; } else { $encode_buffer = $first_byte . \chr(127) . \pack("xxxxN", $len) . $buffer; } } return $encode_buffer; }
Nach dem Login kopieren使用 在线测试工具 进行测试,可以看到消息已经可以正常发送接收,接下来的文章将继续优化代码,实现简易聊天室,敬请关注:
实现web聊天室
我们紧接着上文的代码继续优化,以实现简易的web聊天室
多路复用
其实就是加一下
socket_select()
函数,本文就不写原理与语法了,详情可参考 之前的文章,以下代码修改自前文 Die PHP+Socket-Serie implementiert einen WebSocket-Chatroom
... socket_listen($socket); +$sockets[] = $socket; +$user = []; while (true) { + $tmp_sockets = $sockets; + socket_select($tmp_sockets, $write, $except, null); + foreach ($tmp_sockets as $sock) { + if ($sock == $socket) { + $sockets[] = socket_accept($socket); + $user[] = ['socket' => $socket, 'handshake' => false]; + } else { + $curr_user = $user[array_search($sock, $user)]; + if ($curr_user['handshake']) { // 已握手 + $msg = socket_read($sock, 102400); + echo '客户端发来消息' . decode($msg); + socket_write($sock, encode('这是来自服务端的消息')); + } else { + // 握手 + } + } + } - $conn_sock = socket_accept($socket); - $request = socket_read($conn_sock, 102400); ...
Nach dem Login kopieren实现聊天室
最终成果演示
我们将上述代码改造成类,并在类变量储存用户信息,添加消息处理等逻辑,最后贴出代码,建议保存下来自己尝试一下,也许会有全新的认知,后端代码:
<?php new WebSocket(); class Websocket { /** * @var resource */ protected $socket; /** * @var array 用户列表 */ protected $user = []; /** * @var array 存放所有 socket 资源 */ protected $socket_list = []; public function __construct() { $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, true); socket_bind($this->socket, 0, 8888); socket_listen($this->socket); // 将 socket 资源放入 socket_list $this->socket_list[] = $this->socket; while (true) { $tmp_sockets = $this->socket_list; socket_select($tmp_sockets, $write, $except, null); foreach ($tmp_sockets as $sock) { if ($sock == $this->socket) { $conn_sock = socket_accept($sock); $this->socket_list[] = $conn_sock; $this->user[] = ['socket' => $conn_sock, 'handshake' => false, 'name' => '无名氏']; } else { $request = socket_read($sock, 102400); $k = $this->getUserIndex($sock); if (!$request) { continue; } // 用户端断开连接 if ((\ord($request[0]) & 0xf) == 0x8) { $this->close($k); continue; } if (!$this->user[$k]['handshake']) { // 握手 $this->handshake($k, $request); } else { // 已握手 $this->send($k, $request); } } } } } /** * 关闭连接 * * @param $k */ protected function close($k) { $u_name = $this->user[$k]['name'] ?? '无名氏'; socket_close($this->user[$k]['socket']); $socket_key = array_search($this->user[$k]['socket'], $this->socket_list); unset($this->socket_list[$socket_key]); unset($this->user[$k]); $user = []; foreach ($this->user as $v) { $user[] = $v['name']; } $res = [ 'type' => 'close', 'users' => $user, 'msg' => $u_name . '已退出', 'time' => date('Y-m-d H:i:s') ]; $this->sendAllUser($res); } /** * 获取用户索引 * * @param $socket * @return int|string */ protected function getUserIndex($socket) { foreach ($this->user as $k => $v) { if ($v['socket'] == $socket) { return $k; } } } /** * 握手 * @param $k * @param $request */ protected function handshake($k, $request) { preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $request, $match); $key = base64_encode(sha1($match[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)); $response = "HTTP/1.1 101 Switching Protocols\r\n"; $response .= "Upgrade: websocket\r\n"; $response .= "Connection: Upgrade\r\n"; $response .= "Sec-WebSocket-Accept: {$key}\r\n\r\n"; socket_write($this->user[$k]['socket'], $response); $this->user[$k]['handshake'] = true; } /** * 接收并处理消息 * * @param $k * @param $msg */ public function send($k, $msg) { $msg = $this->decode($msg); $msg = json_decode($msg, true); if (!isset($msg['type'])) { return; } switch ($msg['type']) { case 'login': // 登录 $this->user[$k]['name'] = $msg['name'] ?? '无名氏'; $users = []; foreach ($this->user as $v) { $users[] = $v['name']; } $res = [ 'type' => 'login', 'name' => $this->user[$k]['name'], 'msg' => $this->user[$k]['name'] . ': login success', 'users' => $users, ]; $this->sendAllUser($res); break; case 'message': // 接收并发送消息 $res = [ 'type' => 'message', 'name' => $this->user[$k]['name'] ?? '无名氏', 'msg' => $msg['msg'], 'time' => date('H:i:s'), ]; $this->sendAllUser($res); break; } } /** * 发送给所有人 * */ protected function sendAllUser($msg) { if (is_array($msg)) { $msg = json_encode($msg); } $msg = $this->encode($msg); foreach ($this->user as $k => $v) { socket_write($v['socket'], $msg, strlen($msg)); } } /** * 解码 * * @param $buffer * @return string */ protected function decode($buffer) { $len = \ord($buffer[1]) & 127; if ($len === 126) { $masks = \substr($buffer, 4, 4); $data = \substr($buffer, 8); } else { if ($len === 127) { $masks = \substr($buffer, 10, 4); $data = \substr($buffer, 14); } else { $masks = \substr($buffer, 2, 4); $data = \substr($buffer, 6); } } $dataLength = \strlen($data); $masks = \str_repeat($masks, \floor($dataLength / 4)) . \substr($masks, 0, $dataLength % 4); return $data ^ $masks; } protected function encode($buffer) { if (!is_scalar($buffer)) { throw new \Exception("You can't send(" . \gettype($buffer) . ") to client, you need to convert it to a string. "); } $len = \strlen($buffer); $first_byte = "\x81"; if ($len <= 125) { $encode_buffer = $first_byte . \chr($len) . $buffer; } else { if ($len <= 65535) { $encode_buffer = $first_byte . \chr(126) . \pack("n", $len) . $buffer; } else { $encode_buffer = $first_byte . \chr(127) . \pack("xxxxN", $len) . $buffer; } } return $encode_buffer; } }
Nach dem Login kopieren前端代码如下(前端内容不在本文讨论范围之内,具体可参考 菜鸟教程):
<!doctype html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <style> * { margin: 0; padding: 0; } h3 { display: flex; justify-content: center; margin: 30px auto; } .but-box { border-radius: 5px; display: flex; justify-content: center; align-items: center; margin-top: 10px; } #box { display: flex; margin: 5px auto; border-radius: 5px; border: 1px #ccc solid; height: 400px; width: 700px; overflow-y: auto; overflow-x: hidden; position: relative; } #msg-box { width: 480px; margin-right: 111px; height: 100%; overflow-y: auto; overflow-x: hidden; } #user-box { width: 110px; overflow-y: auto; overflow-x: hidden; float: left; border-left: 1px #ccc solid; height: 100%; background-color: #F1F1F1; } button { float: right; width: 80px; height: 35px; font-size: 18px; } input { width: 100%; height: 30px; padding: 2px; line-height: 20px; outline: none; border: solid 1px #CCC; } .but-box p { margin-right: 160px; } </style> <body> <h3 id="这是一个php-nbsp-socket实现的web聊天室">这是一个php socket实现的web聊天室</h3> <div id="box"> <div id="msg-box"></div> <div id="user-box"></div> </div> <div> <p><textarea cols="60" rows="3" style="resize:none;pedding: 10px" id="content"> </textarea></p> <button id="send">发送</button> </div> <script src="https://cdn.bootcss.com/jquery/2.2.1/jquery.min.js"></script> <script> let ws = new WebSocket('ws://124.222.85.67:8888'); ws.onopen = function (event) { console.log('连接成功'); var name = prompt('请输入用户名:'); ws.send(JSON.stringify({ type: 'login', name: name })); if (!name) { alert('好你个坏蛋,竟然没有输入用户名'); } }; ws.onmessage = function (event) { let data = JSON.parse(event.data); console.log(data); switch (data.type) { case 'close': case 'login': $("#user-box").html(''); data.users.forEach(function (item) { $("#user-box").append(`<p style="color: grey;">${item}</p>`); }); if (data.msg) { $("#msg-box").append(`<p style="color: grey;">${data.msg}</p>`); } break; case 'message': $("#msg-box").append(`<p><span style="color: #0A89FF">${data.time}</span><span style="color: red">${data.name}</span>${data.msg}</p>`); break; } }; ws.onclose = function (event) { alert('连接关闭'); }; document.onkeydown = function (event) { if (event.keyCode == 13) { send(); } } $("#send").click(function () { send(); }); function send() { let content = $("#content").val(); $("#content").val(''); if (!content) { return; } ws.send(JSON.stringify({ type: 'message', msg: content })); } </script> </body> </html>
Nach dem Login kopieren[^1]:是通讯传输的一个术语。 通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合
[^2]: 为了建立 websocket 连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”(Handshaking)推荐学习:《PHP视频教程》
Das obige ist der detaillierte Inhalt vonDie PHP+Socket-Serie implementiert einen WebSocket-Chatroom. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

PHP 8.4 bringt mehrere neue Funktionen, Sicherheitsverbesserungen und Leistungsverbesserungen mit einer beträchtlichen Menge an veralteten und entfernten Funktionen. In dieser Anleitung wird erklärt, wie Sie PHP 8.4 installieren oder auf PHP 8.4 auf Ubuntu, Debian oder deren Derivaten aktualisieren. Obwohl es möglich ist, PHP aus dem Quellcode zu kompilieren, ist die Installation aus einem APT-Repository wie unten erläutert oft schneller und sicherer, da diese Repositorys in Zukunft die neuesten Fehlerbehebungen und Sicherheitsupdates bereitstellen.

Wenn Sie ein erfahrener PHP-Entwickler sind, haben Sie möglicherweise das Gefühl, dass Sie dort waren und dies bereits getan haben. Sie haben eine beträchtliche Anzahl von Anwendungen entwickelt, Millionen von Codezeilen debuggt und eine Reihe von Skripten optimiert, um op zu erreichen

Visual Studio Code, auch bekannt als VS Code, ist ein kostenloser Quellcode-Editor – oder eine integrierte Entwicklungsumgebung (IDE) –, die für alle gängigen Betriebssysteme verfügbar ist. Mit einer großen Sammlung von Erweiterungen für viele Programmiersprachen kann VS Code c

JWT ist ein offener Standard, der auf JSON basiert und zur sicheren Übertragung von Informationen zwischen Parteien verwendet wird, hauptsächlich für die Identitätsauthentifizierung und den Informationsaustausch. 1. JWT besteht aus drei Teilen: Header, Nutzlast und Signatur. 2. Das Arbeitsprinzip von JWT enthält drei Schritte: Generierung von JWT, Überprüfung von JWT und Parsingnayload. 3. Bei Verwendung von JWT zur Authentifizierung in PHP kann JWT generiert und überprüft werden, und die Funktionen und Berechtigungsinformationen der Benutzer können in die erweiterte Verwendung aufgenommen werden. 4. Häufige Fehler sind Signaturüberprüfungsfehler, Token -Ablauf und übergroße Nutzlast. Zu Debugging -Fähigkeiten gehört die Verwendung von Debugging -Tools und Protokollierung. 5. Leistungsoptimierung und Best Practices umfassen die Verwendung geeigneter Signaturalgorithmen, das Einstellen von Gültigkeitsperioden angemessen.

Dieses Tutorial zeigt, wie XML -Dokumente mit PHP effizient verarbeitet werden. XML (Extensible Markup-Sprache) ist eine vielseitige textbasierte Markup-Sprache, die sowohl für die Lesbarkeit des Menschen als auch für die Analyse von Maschinen entwickelt wurde. Es wird üblicherweise für die Datenspeicherung ein verwendet und wird häufig verwendet

Eine Zeichenfolge ist eine Folge von Zeichen, einschließlich Buchstaben, Zahlen und Symbolen. In diesem Tutorial wird lernen, wie Sie die Anzahl der Vokale in einer bestimmten Zeichenfolge in PHP unter Verwendung verschiedener Methoden berechnen. Die Vokale auf Englisch sind a, e, i, o, u und sie können Großbuchstaben oder Kleinbuchstaben sein. Was ist ein Vokal? Vokale sind alphabetische Zeichen, die eine spezifische Aussprache darstellen. Es gibt fünf Vokale in Englisch, einschließlich Großbuchstaben und Kleinbuchstaben: a, e, ich, o, u Beispiel 1 Eingabe: String = "TutorialPoint" Ausgabe: 6 erklären Die Vokale in der String "TutorialPoint" sind u, o, i, a, o, ich. Insgesamt gibt es 6 Yuan

Statische Bindung (statisch: :) implementiert die späte statische Bindung (LSB) in PHP, sodass das Aufrufen von Klassen in statischen Kontexten anstatt Klassen zu definieren. 1) Der Analyseprozess wird zur Laufzeit durchgeführt.

Was sind die magischen Methoden von PHP? Zu den magischen Methoden von PHP gehören: 1. \ _ \ _ Konstrukt, verwendet, um Objekte zu initialisieren; 2. \ _ \ _ Destruct, verwendet zur Reinigung von Ressourcen; 3. \ _ \ _ Call, behandeln Sie nicht existierende Methodenaufrufe; 4. \ _ \ _ GET, Implementieren Sie den dynamischen Attributzugriff; 5. \ _ \ _ Setzen Sie dynamische Attributeinstellungen. Diese Methoden werden in bestimmten Situationen automatisch aufgerufen, wodurch die Code -Flexibilität und -Effizienz verbessert werden.
