关于php:laravel查询时判断是否存在数据

1.Laravel Eloquent模型Eloquent 返回的所有后果集都是 Illuminate\Database\Eloquent\Collection 对象的实例,包含通过 get 办法检索或通过拜访关联关系获取到的后果。 Eloquent 的汇合对象继承了 Laravel 的 Base Collection,因而它天然也继承了数十种能优雅地解决 Eloquent 模型底层数组的办法。因而要判断数据存在,间接用内置办法即可。// 1.应用内置办法 isEmpty()$userItems = User::where('sex', '=', '1')->get();if ($userItems->isEmpty()) {}// 2.应用内置办法 count() 查看有没有记录if (User::where('email', '=', $email)->count() > 0) { // 有记录}// 3.应用内置办法 exists() 倡议应用该办法$userItems = User::where('sex', '=', '1')->get();if ($userItems->exists()) { // 有记录}// 4.应用内置办法 first()$user = User::where('email', '=', $email)->first();if ($user === null) { // 没记录}2.数据库:查问结构器间接应用is_null()或empty()判段后果集是否为空。$users = DB::table('users')->where('id', $id)->get();// 办法1if($users){ // 有记录}// 办法2if(is_null($users)){ // 没记录}// 办法3if(empty($users)){ // 没记录}

November 26, 2020 · 1 min · jiezi

关于php:设计模式总结理论篇

如何能力写出高质量的代码?问如何写出高质量的代码,也就等同于在问,如何写出易保护、易读、易扩大、灵便、简洁、可复用、可测试的代码。 要写出满足这些评估规范的高质量代码,咱们须要把握一些更加细化、更加能落地的编程方法论,包含面向对象设计思维、设计准则、设计模式、编码标准、重构技巧等。而所有这些编程方法论的最终目标都是为了编写出高质量的代码。 比方,面向对象中的继承、多态能让咱们写出可复用的代码;编码标准能让咱们写出可读性好的代码;设计准则中的繁多职责、DRY、基于接口而非实现、里式替换准则等,能够让咱们写出可复用、灵便、可读性好、易扩大、易保护的代码;设计模式能够让咱们写出易扩大的代码;继续重构能够时刻放弃代码的可维护性等等。 什么是面向对象编程和面向对象编程语言?面向对象编程的英文缩写是 OOP,全称是 Object Oriented Programming。对应地,面向对象编程语言的英文缩写是 OOPL,全称是 Object Oriented Programming Language。 面向对象编程中有两个十分重要、十分根底的概念,那就是类(class)和对象(object)。 面向对象编程是一种编程范式或编程格调。它以类或对象作为组织代码的根本单元,并将封装、形象、继承、多态四个个性,作为代码设计和实现的基石 。面向对象编程语言是反对类或对象的语法机制,并有现成的语法机制,能不便地实现面向对象编程四大个性(封装、形象、继承、多态)的编程语言。面向对象面向对象的四大个性:封装、形象、继承、多态封装(Encapsulation)封装也叫作信息暗藏或者数据拜访爱护。类通过裸露无限的拜访接口,受权内部仅能通过类提供的形式(或者叫函数)来拜访外部信息或者数据。 对于封装这个个性,咱们须要编程语言自身提供肯定的语法机制来反对。这个语法机制就是拜访权限管制。如public,private,protected。 类仅仅通过无限的办法裸露必要的操作,也能进步类的易用性。如果咱们把类属性都裸露给类的调用者,调用者想要正确地操作这些属性,就势必要对业务细节有足够的理解。而这对于调用者来说也是一种累赘。相同,如果咱们将属性封装起来,裸露少许的几个必要的办法给调用者应用,调用者就不须要理解太多背地的业务细节,用错的概率就缩小很多。 形象(Abstraction)类的办法是通过编程语言中的“函数”这一语法机制来实现的。通过函数包裹具体的实现逻辑,这自身就是一种形象。调用者在应用函数的时候,并不需要去钻研函数外部的实现逻辑,只须要通过函数的命名、正文或者文档,理解其提供了什么性能,就能够间接应用了。 形象这个概念是一个十分通用的设计思维,并不单单用在面向对象编程中,也能够用来领导架构设计等。而且这个个性也并不需要编程语言提供非凡的语法机制来反对,只须要提供“函数”这一十分根底的语法机制,就能够实现形象个性、所以,它没有很强的“特异性”,有时候并不被看作面向对象编程的个性之一。 继承(Inheritance)继承是用来示意类之间的 is-a 关系。从继承关系上来讲,继承能够分为两种模式,单继承和多继承。PHP只反对单继承,不反对多重继承。 继承最大的一个益处就是代码复用。如果两个类有一些雷同的属性和办法,咱们就能够将这些雷同的局部,抽取到父类中,让两个子类继承父类。这样,两个子类就能够重用父类中的代码,防止代码反复写多遍。 多态(Polymorphism)多态是指,子类能够替换父类。只有两个类具备雷同的办法,就能够实现多态,并不要求两个类之间有任何关系。多态能够进步代码的扩展性和复用性,是很多设计模式、设计准则、编程技巧的代码实现根底。 面向对象编程与面向过程编程的区别和分割面向对象编程是一种编程范式或编程格调。它以类或对象作为组织代码的根本单元,并将封装、形象、继承、多态四个个性,作为代码设计和实现的基石 。 面向过程编程也是一种编程范式或编程格调。它以过程(能够了解为办法、函数、操作)作为组织代码的根本单元,以数据(能够了解为成员变量、属性)与办法相拆散为最次要的特点。面向过程格调是一种流程化的编程格调,通过拼接一组程序执行的办法来操作数据实现一项性能。 面向过程和面向对象最根本的区别就是,代码的组织形式不同。面向过程格调的代码被组织成了一组办法汇合及其数据结构(struct User),办法和数据结构的定义是离开的。面向对象格调的代码被组织成一组类,办法和数据结构被绑定一起,定义在类中。 以PHP为例,假如咱们有一个记录了用户信息的文本文件 users.txt,每行文本的格局是 name&age&gender(比方,小王 &28& 男)。咱们心愿写一个程序,从 users.txt 文件中逐行读取用户信息,而后格式化成 name\tage\tgender(其中,\t 是分隔符)这种文本格式,并且依照 age 从小到大排序之后,从新写入到另一个文本文件 formatted_users.txt 中。 //面向过程编程function parse_to_user($text){ // 将text(“小王&28&男”)解析成数组 return $user;}function format_to_text($user){ // 将$user格式化成文本("小王\t28\t男") return $user;}function sort_users_by_age($user) { // 依照年龄从小到大排序users return $user}function format_user_file($origin_file_path, $new_file_path) { // open files... $count = 0; $user = array(); while(1) { // read until the file is empty $user[] = parse_to_user(line); } sort_users_by_age(users); for (int i = 0; i < count($user); ++i) { $text = format_to_text(users[i]); // write to new file... } // close files...}format_user_file("user.txt", "formatted_users.txt");//面向对象编程public class User(){ private $name; private $age; private $sex; public static User praseFrom($userInfoText) { // 将text(“小王&28&男”)解析成类User $this->name=$name; $this->age=$age; $this->sex=$sex; } public String formatToText() { // 将类User变量格式化成文本("小王\t28\t男") return $formatUser; }}public class UserFileFormatter { public function format(String userFile, String formattedUserFile) { // Open files... $userArr = array(); while (1) { // read until file is empty // read from file into userText... $user = new User(); $user->praseFrom($line); $userArr[] = $user } // sort users by age... for (int i = 0; i < count($userArr); ++i) { $formattedUserText = $userArr[$i].formatToText(); // write to new file... } // close files... }}$userFileFormatter = new UserFileFormatter();$userFileFormatter->format("user.txt", "formatted_users.txt");1.对于大规模简单程序的开发,程序的解决流程并非繁多的一条主线,而是盘根错节的网状结构。面向对象编程比起面向过程编程,更能应答这种简单类型的程序开发。 ...

November 26, 2020 · 3 min · jiezi

关于php:PHP中的static

PHP中的static对于动态变量和办法的问题也是面试中常常会呈现的问题,这种问题多看手册搞明确原委就能解决,只是的确对于动态变量的问题还是比拟绕的,这里咱们就联合手册用理论的代码来看! class Test{ static $v = 'a'; static function showV() { echo self::$v; } function showVV() { echo self::$v; } static function showVVV() { // $this->showVV(); // 会间接报错 }}先筹备一个类,这外面有动态变量、静态方法,其中showV()办法是静态方法调用动态变量,showVV()办法是一般办法调用动态变量,showVVV()办法是一般办法调用静态方法。 从正文中能够看出第一个问题,一般办法应用$this调用静态方法会报错,也就是说,$this这个东东对于所有动态的货色都是不敌对的,不信您关上正文试试,也能够去调用动态的$v变量,间接就是语法错误的提醒。 接下来,咱们实例化类,并开始一些测试 $t = new Test();$t->showV();//echo $t->v; // 报异样echo Test::$v;//Test::showVV(); // 报异样$t->showVV();1行:实例化的类间接调用showV(),这是没问题的,静态方法能够通过一般的形式调用,当然咱们正规的应该是应用Test::showV()来进行调用,留神这里面试的时候会是坑2行:失常调用2行:间接->v是不行的,办法能够进行一般调用,但属性不行3行:用动态调用的形式是没问题的4行:失常获取动态变量5行: 应用::当然不能调用非静态方法啦6行:失常办法中能够应用动态变量那么问题来了,静态方法中不能应用$this,如何取得变量内容呢?请参考单例模式,未来咱们会在设计模式的系列文章中讲到,这里先卖个关子,大家也能够本人钻研下。 下面是失常来说一些比较简单的动态属性和办法的演示,接下来好玩的货色就来了。 初始化个性class Calculate{ function cacl() { static $a = 1; echo $a; $a++; } static function cacl2() { static $a = 1; echo $a; $a++; } static $b = 1; static function cacl3() { echo self::$b; self::$b++; }}$calculate = new Calculate();$calculate->cacl(); // 1$calculate->cacl(); // 2Calculate::cacl2(); // 1Calculate::cacl2(); // 2Calculate::cacl3(); // 1Calculate::cacl3(); // 2看着代码很多,其实都是在讲一件事儿,如果是一般的$a和$b,那么每次都在从新赋值,echo进去的都是0,然而动态属性可不一样。动态属性是运行时计算的,只在第一次赋值的时候是真正的赋值操作,而后并不会进行赋值,能够相当于这一行代码不存在。 ...

November 25, 2020 · 2 min · jiezi

关于php:浅析php环境配置

PHP作为开源的服务器端脚本语言,在web利用方面十分宽泛。如果你想下载某些开源利用,github上php开源软件抉择往往比Java还多。最近,钻研了linux下php的装置,次要有以下领会。 PHP-INIphp.ini文件是php的外围配置文件且只能命名为php.ini,它是对php应用程序全局起作用的设置文件,外面选项十分多,蕴含php页面应用内存大小限度,上传下载文件大小限度,浮点型的精度等。 FPM-PHPfpm-php(FastCGI ProcessManager)原本是php的第三方包,在php5.3.3后成为了php的核心成员,不须要独自下载安装。FastCGI诞生之前,web端转发一个php申请后,须要从新加载php.ini,通过fpm-php创立master过程,收到多个php申请,创立子过程来共享master过程加载的php.ini信息。装置fpm-php后,启动php实际上通过启动的fpm-php.service来实现。fpm-php和web之间的通信能够通过两种形式实现,socket和tcp形式,通过/etc/php-fpm.d/www.conf的配置来配置。两种形式的差别次要在listen的配置不一样。一个是php-fpm.sock,一个是服务器的ip:9000。 socket形式是长连贯形式,实用于php和其余服务在同一台服务器上 [www]user = nginxgroup = nginxlisten = /run/php-fpm.socktcp形式是http申请形式,实用于集群并发量高的多服务器上 [www]user = nginxgroup = nginxlisten = 127.0.0.1:9000再谈过程如何调配,以上面配置来说,start_servers=10阐明php服务就启动10个worker子过程始终处于期待中,min_spare_servers=5是指最小流动过程。php启动时开启8个过程,如果没有收到web申请,fpm-php就会开释一些,最终达到5个过程。然而最大不能超过max_spare_servers = 35。至于max_children=50,那是动态配置形式,不变的,是一种浪费资源的形式,始终启动50个过程再那里期待,即便网站利用没有一个人拜访也是一样。 pm.max_children = 50pm.start_servers = 10pm.min_spare_servers = 5pm.max_spare_servers = 35扩大包仅装置php往往不能满足应用软件的需要,还须要其余很多扩大包来反对php利用。例如,【odbc,common,ima,mongodb,xml等】,然而须要留神的是装置的时候上面这些包是基于pecl的【apcu,imagick,goeip,mcrypt,redis,zip,memcache】。尤其,zip包特地须要指定pecl,否则扩大包装置不胜利,其余pecl包能够从remi源中主动找到响应包。 yum install php-commonyum install php-apcuyum install php-pecl-zipweb服务器相干配置php和web服务器nginx,apache还须要做一些关联配置,在他们的配置文件外面退出以下: nginx:location ~ .*\.php${ fastcgi_pass unix:/run/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; try_files $uri = 404;}apache:<FilesMatch \.php$> SetHandler "proxy:unix:/run/php-fpm.sock|fcgi://localhost"</FilesMatch>然而,ubuntu零碎下PHP利用应用apache服务器的状况下,须要配置,否则相同apache服务器报错无奈启动。以上对php的配置了解,今后随着对它钻研的加深,还会写一些对于php新的货色。 创作不易,欢送探讨,感激反对!

November 24, 2020 · 1 min · jiezi

关于php:Swoole-v458-版本发布新增-swooleerrorlog-函数并优化-logrotation-参数

Swoole v4.5.8 版本曾经公布了,在这个版本中咱们减少了 swoole_error_log 函数,用户能够手动调用此函数将错误信息输出到日志中。 并且咱们还优化了 Server 的 log_rotation 参数,可能有些小伙伴还不晓得这个参数有什么用: 它是用来设置 Server 日志宰割,默认不启用,之前的版本仅反对按天宰割,在这个版本中咱们反对了按月、按小时和按分钟进行宰割。 $server->set([ 'log_file' => 'swoole', 'log_rotation' => SWOOLE_LOG_ROTATION_HOURLY, //每小时]);不仅仅是这些,在这个版本中咱们还反对了更多的 cURL 选项,同时修复了因为设置了 CURLOPT_WRITEFUNCTION 所导致的一些问题,以及在解决 content-type header 的时候没有辨别名字大小写导致被笼罩问题。 还没有完结,在之后的版本中,咱们将会应用另外的一种形式反对 Hook cURL,敬请期待~ 上面来看看此版本的更新日志 更新日志新增 API新增 swoole_error_log 函数,优化 log_rotation (swoole/swoole-src@67d2bff) (@matyhtf)readVector 和 writeVector 反对 SSL (#3857) (@huanghantao)加强当子过程退出后,让 System::wait 退出阻塞 (#3832) (@matyhtf)DTLS 反对 16K 的包 (#3849) (@matyhtf)Response::cookie 办法反对 priority 参数 (#3854) (@matyhtf)反对更多的 CURL 选项 (swoole/library#71) (@sy-records)解决 CURL HTTP header 没有辨别名字大小写导致被笼罩问题 (swoole/library#76) (@filakhtov) (@twose) (@sy-records)修复修复 readv_all 和 writev_all 错误处理 EAGAIN 的问题 (#3830) (@huanghantao)修复 PHP8 编译正告的问题 (swoole/swoole-src@03f3fb0) (@matyhtf)修复 SwooleTable 二进制平安的问题 (#3842) (@twose)修复 MacOS 下 System::writeFile 追加文件笼罩的问题 (swoole/swoole-src@a71956d) (@matyhtf)修复 CURL 的 CURLOPT_WRITEFUNCTION (swoole/library#74) (swoole/library#75) (@sy-records)修复解析 HTTP form-data 时内存溢出的问题 (#3858) (@twose)修复在 PHP8 中 is_callable() 无法访问类公有办法的问题 (#3859) (@twose)内核重构内存调配函数,应用 SwooleG.std_allocator (#3853) (@matyhtf)重构管道 (#3841) (@matyhtf) ...

November 21, 2020 · 1 min · jiezi

关于php:php-关于图片获取宽高的优化

需要1. 应前端需要,在进入文章详情时须要将所有图片进行占位替换,且占位符须要对应图片信息(次要须要晓得宽高)2. 目标:做点击图片浮窗成果实现计划1. 优化前 1.1 正则匹配图片,而后循环获取每张图片的宽高 1.2 问题:如果文章图片较少,以上操作问题不大。但图片一旦过慢,这个效率将会十分低下 1.3 代码如下: preg_match_all('/<img.*? src="(.*?)".*?>/is', $str, $matchs); if(!empty($matchs[0])){ $pics = []; $i = 0; foreach ($matchs[0] as $key => $m) { $fileInfo = file_get_contents($matchs[1][$key] . '?x-oss-process=image/info'); $fileInfo = json_decode($fileInfo, true); $data['Width'] = $fileInfo['ImageWidth']['value']; $data['Height'] = $fileInfo['ImageHeight']['value']; $imgs[$i]['ref'] = '<!--IMG#' . $key . '-->'; $imgs[$i]['pixel'] = $data['Width'] . '*' . $data['Height']; preg_match('/alt="(.*?)"/i', $matchs[0][$key], $mt); $imgs[$i]['alt'] = isset($mt[1]) ? $mt[1] : ''; //图片alt $imgs[$i]['src'] = $matchs[1][$key]; //图片地址 $str = str_replace($m, '<!--IMG#' . $key . '-->', $str); $i++; } }2. 优化思路 2.1 想着是否会有极速获取图片法子?在网上找了一些材料,基本上都是通过读取图片局部文件信息,不须要下载/读取整个图片。找了一个类库:[https://github.com/tommoor/fastimage](https://github.com/tommoor/fastimage),试了一下。 相比以前的思路(残缺的下载图片) 的确有性能上的晋升。有趣味的敌人能够试试,如果针对单张图片的信息获取,这个还是很举荐的。但批量的实现仿佛还达不到目标 2.2 剖析以上操作,其实慢的过程应该还是停留在循环获取图片资源上。那么换个思路,我批量获取图片是否就ok了?上代码 preg_match_all('/<img.*? src="(.*?)".*?>/is', $str, $matchs);if(!empty($matchs[0])){ //$time = microtime(true); //echo ' ---- start ' . PHP_EOL; foreach ($matchs[0] as $key => $m) { $urls[] = $matchs[1][$key] . '?x-oss-process=image/info'; } $imageInfos = batchCurl($urls); $i = 0; foreach ($matchs[0] as $key => $m) { $image = json_decode($imageInfos[$key], true); $_img['Width'] = $width= $image['ImageWidth']['value']; $_img['Height'] = $height = $image['ImageHeight']['value']; $imgs[$i]['ref'] = '<!--IMG#' . $key . '-->'; $imgs[$i]['pixel'] = $_img['Width'] . '*' . $_img['Height']; preg_match('/alt="(.*?)"/i', $matchs[0][$key], $mt); $imgs[$i]['alt'] = isset($mt[1]) ? $mt[1] : ''; //图片alt $imgs[$i]['src'] = $matchs[1][$key]; //图片地址 $str = str_replace($m, '<!--IMG#' . $key . '-->', $str); $i++; } //echo " ---- end px in " . (microtime(true)-$time) . " seconds \n"; //exit;} function batchCurl($urls){ $res = $conn = []; // 创立批处理cURL句柄 $mh = curl_multi_init(); foreach ($urls as $i => $url) { // 创立一对cURL资源 $conn[$i] = curl_init(); // 设置URL和相应的选项 curl_setopt($conn[$i], CURLOPT_URL, $url); curl_setopt($conn[$i], CURLOPT_HEADER, 0); curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1); curl_setopt($conn[$i], CURLOPT_TIMEOUT, 10); // 302跳转 curl_setopt($conn[$i], CURLOPT_FOLLOWLOCATION, 1); // 减少句柄 curl_multi_add_handle($mh, $conn[$i]); } $active = null; //防卡死写法:执行批处理句柄 do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc == CURLM_OK) { if (curl_multi_select($mh) != -1) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } foreach ($urls as $i => $url) { //获取以后解析的cURL的相干传输信息 $info = curl_multi_info_read($mh); //获取申请头信息 $heards = curl_getinfo($conn[$i]); //获取输入的文本流 $res[$i] = curl_multi_getcontent($conn[$i]); // 移除curl批处理句柄资源中的某个句柄资源 curl_multi_remove_handle($mh, $conn[$i]); //敞开cURL会话 curl_close($conn[$i]); } //敞开全副句柄 curl_multi_close($mh); return $res;}3. 测试性能,20张图片的效率简直能达到秒级![image](/img/bVcKCF2)总结1. 优化的思路很重要,重点在于剖析所提所在,隔靴搔痒。在此记个笔记

November 20, 2020 · 2 min · jiezi

关于php:北京-学而思网校招聘PHP实习生

好将来团体学而思网校招聘PHP实习生。简历发送至 zhangyong1@tal.com 岗位要求:1.本科以上学历,计算机专业优先;2.把握PHP语言3.把握Mysql,Ngnix、Linux应用4.理解如何应用git治理代码5.理解Swoole、Hyperf优先 岗位职责:参加部门外围平台研发 工作地点:北京昌平区回龙观东大街 联系方式:发送简历至邮箱 zhangyong1@tal.com题目格局 姓名-学校

November 18, 2020 · 1 min · jiezi

关于php:PhpStorm中两个提升生产力的插件

Php Inspections (EA Extended)一个代码优化和平安提醒的插件 次要性能: 与架构无关的问题弱类型管制和可能的代码结构简化性能问题非最佳,反复和可疑的“如果”条件验证魔术办法的应用罕用表白兼容性问题各种耗时的谬误PHPUnit API用法平安问题提醒场景: TabNine智能主动补全插件,不会本人写代码的 IDE 不是好的 IDE,那么 TabNine 就是让 PhpStorm 变强的插件。 有这两个插件的加持,咱们能够在高低抉择主动提醒的代码抉择更强健的代码,生产力有限进步,不须要额定修福报写代码。 最初恰饭 阿里云全系列产品/短信包特惠购买 中小企业上云最佳抉择 阿里云外部优惠券

November 18, 2020 · 1 min · jiezi

关于php:ubuntu因为意外关机导致-mysql启动不了

操作之前首先要做好重新安装mysql的筹备步骤:在/etc/mysql/mysql.conf.d下的mysqld.cnf中配置[mysqld]innodb_force_recovery = 1其中前面的值设置为1、如果1不能启动胜利,再逐渐减少为2/3/4等。直到能启动mysql为止个别状况下到3为止应该是能够启动的,如果启动了先把数据库备份,最好从新装一下mysql,因为尽管启动了,然而当你第一次拜访我的项目当前,第二次再拜访就会报数据库错,当然你也能够依照网上的办法试试,办法在下方最初,反正我没胜利。这里讲一下卸载数据库首先在终端中查看MySQL的依赖项:dpkg --list|grep mysql而后执行 sudo apt purge mysql-*sudo rm -rf /etc/mysql/ /var/lib/mysqlsudo apt autoremovesudo apt autoclean在执行命令dpkg --list|grep mysql查看mysql下依赖留下php-mysql就行了 参考连贯:记一次服务器宕机后数据库复原的过程Ubuntu18.04彻底删除MySQL数据库Ubuntu20.04上装置MySQL8.0 如果以上链接内容生效,就间接看上面把,我都给复制过去了 ------------------------------------------------------这里我把参考链接的内容复制过去了第一种卸载mysql 首先在终端中查看MySQL的依赖项:dpkg --list|grep mysql 卸载: sudo apt-get remove mysql-common 卸载:sudo apt-get autoremove --purge mysql-server-5.7 革除残留数据:dpkg -l|grep ^rc|awk '{print$2}'|sudo xargs dpkg -P 再次查看MySQL的残余依赖项:dpkg --list|grep mysql 持续删除残余依赖项,如:sudo apt-get autoremove --purge mysql-apt-config 至此曾经没有了MySQL的依赖项,彻底删除,Good Luck链接:https://blog.csdn.net/iehadoo... 第二种办法就是我写的那样 mysql启动不了办法: 景象景象很简略,数据库服务器被宕机,当然是在没有停数据库服务的状况下。 机器重启后,试图重启MySQL服务,无果,查看谬误日志: 170920 0:30:17 InnoDB: Assertion failure in thread 140107687212800 in file /export/home/pb2/build/sb_0-2629600-1291399482.5/mysql-5.5.10/storage/innobase/include/fut0lst.ic line 83InnoDB: Failing assertion: addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATAInnoDB: We intentionally generate a memory trap.InnoDB: Submit a detailed bug report to http://bugs.mysql.com.InnoDB: If you get repeated assertion failures or crashes, evenInnoDB: immediately after the mysqld startup, there may beInnoDB: corruption in the InnoDB tablespace. Please refer toInnoDB: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.htmlInnoDB: about forcing recovery.170920 0:30:17 - mysqld got signal 6 ;This could be because you hit a bug. It is also possible that this binaryor one of the libraries it was linked against is corrupt, improperly built,or misconfigured. This error can also be caused by malfunctioning hardware.We will try our best to scrape up some info that will hopefully help diagnosethe problem, but since we have already crashed, something is definitely wrongand this may fail.key_buffer_size=16777216read_buffer_size=262144max_used_connections=0max_threads=500thread_count=0connection_count=0It is possible that mysqld could use up to key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 406067 Kbytes of memoryHope that's ok; if not, decrease some variables in the equation.thd: 0x0Attempting backtrace. You can use the following information to find outwhere mysqld died. If you see no messages after this, something wentterribly wrong...stack_bottom = (nil) thread_stack 0x40000/usr/local/mysql/bin/mysqld(my_print_stacktrace+0x39)[0x916839]/usr/local/mysql/bin/mysqld(handle_segfault+0x359)[0x4fc0d9]/lib64/libpthread.so.0(+0xf4a0)[0x7f6d5ca9f4a0]/lib64/libc.so.6(gsignal+0x35)[0x7f6d5be4a885]/lib64/libc.so.6(abort+0x175)[0x7f6d5be4c065]/usr/local/mysql/bin/mysqld[0x7d5601]/usr/local/mysql/bin/mysqld[0x7ca012]/usr/local/mysql/bin/mysqld[0x7ca357]/usr/local/mysql/bin/mysqld[0x7cce1a]/usr/local/mysql/bin/mysqld[0x7b89e8]/usr/local/mysql/bin/mysqld[0x78d97d]/usr/local/mysql/bin/mysqld(_Z24ha_initialize_handlertonP13st_plugin_int+0x48)[0x6683a8]/usr/local/mysql/bin/mysqld[0x57ddba]/usr/local/mysql/bin/mysqld(_Z11plugin_initPiPPci+0xb5d)[0x581cbd]/usr/local/mysql/bin/mysqld[0x50212c]/usr/local/mysql/bin/mysqld(_Z11mysqld_mainiPPc+0x3c2)[0x504742]/lib64/libc.so.6(__libc_start_main+0xfd)[0x7f6d5be36cdd]/usr/local/mysql/bin/mysqld[0x4fa3fa]The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html containsinformation that should help you find out what is causing the crash.170920 00:30:17 mysqld_safe mysqld from pid file /usr/local/mysql/data/localhost.localdomain.pid ended170920 01:04:55 mysqld_safe Starting mysqld daemon with databases from /usr/local/mysql/data170920 1:04:55 [Warning] Ignoring user change to 'ser=mysql' because the user was set to 'mysql' earlier on the command line解决过程刚开始的重点放在了这段日志上: ...

November 18, 2020 · 3 min · jiezi

关于php:说一说你不了解的Tailwind-CSS响应式设计

导语响应式置信大家都不生疏,就是应用css的媒体查问设计,进行不同尺寸,显示不同成果,然而Tailwind CSS的响应式设计应用起来会更加爽,更加快捷不便,到底怎么搞呢?咱们一起来探讨一下。简介Tailwind中的每个实用程序类都能够有条件地利用于不同的断点,这使得轻松构建简单的响应式接口变得轻松,而无需来到HTML。默认状况下,Tailwind提供了四个断点,也就是别离对应挪动端,横屏,平板,桌面端。当然你也能够自定义断点。对应断点相应的是最小宽度为界。screens: { sm: '640px', //@media (min-width: 640px) { /* ... */ } md: '768px', //@media (min-width: 768px) { /* ... */ } lg: '1024px', //@media (min-width: 1024px) { /* ... */ } xl: '1280px', //@media (min-width: 1280px) { /* ... */ }},简略应用应用起来当然非常简单,省去了繁冗的过程,间接对应尺寸显示的款式即可,不加限度则全尺寸显示一样的成果。默认状况下,Tailwind应用挪动优先断点零碎,相似于您可能在Bootstrap或Foundation中应用的零碎。 应用:只有应用前缀加上:再加上对应类名即可。例如: md:text-gray-700 <p class="text-red-600 sm:text-yellow-300 lg:text-green-600 xl:text-blue-300">Tailwind CSS text-color测试</p>上述一段代码,意思是:屏幕小于640尺寸为红色,640-1024尺寸显示为黄色,1024-1280尺寸显示为绿色,大于1280尺寸显示为蓝色。 这意味着未加前缀的类对所有屏幕尺寸都无效,而带前缀的类仅在指定的断点及以上断点失效。 几个小技巧能够应用max-w-sm限定此网页为挪动端,在浏览器也只显示小尺寸。要为挪动设备设计款式,您须要应用实用程序的无前缀版本,而不是带sm:前缀的版本。不要将其sm:视为“在小屏幕上”的含意,而应将其视为“在小断点处”。不要sm:用于定位挪动设施<!-- This will only center text on screens 640px and wider, not on small screens --><div class="sm:text-center"></div>应用无前缀的实用程序来定位挪动设施,并在较大的断点处笼罩它们<!-- This will center text on mobile, and left align it on screens 640px and wider --><div class="text-center sm:text-left"></div>5.通常最好先为设计实现挪动布局,而后在对sm屏幕有意义的所有更改上进行分层,而后再对md屏幕等进行分层。 ...

November 17, 2020 · 1 min · jiezi

关于php:标fun在PHP开发API接口时-web和api有什么不同

1.单文件实现多接口有多种形式,如if…elseif…或switch或动静办法(即TP的这种拜访函数体的模式)。第二,json在数据输入方面十分杰出,它有很强的跨平台性,json在市场上的支流编程语言中都反对json解析,json正逐步取代xml成为网络数据的通用格局。三、界面平安,务必减少界面验证。举例来说,客户端和服务器端对不同的接口做了对立的加密解决,而服务端则在每次接口须要时进行验证。确保不会被歹意刷新接口或黑客歹意调用,特地是大型商业应用程序。4.对于在线API,必须保障所有接口都失常运行,并敞开所有错误信息=>error_reporting(0),并且在输入json时,不容许有其余输入,否则,客户机将无奈解析数据,app间接闪退!5.开发API与WEB有肯定的不同之处,如果是WEB,可能会呈现代码谬误,但不会导致特地重大的谬误,可能会导致数据写入和查问失败,可能会导致WEB的某个局部呈现谬误或代码凌乱。然而,如果是API,间接Crash(解体)!客户个别对服务端的响应速度要求很高,所以,用最原始的PHP来实现界面开发,是最无效的,如果用在框架上,也须要加载各种不须要额定的文件,就像夏天衣着冬天的衣服,试想,你在玩手机时,轻易一个应用程序都要操作,等上半天才有动静,你受得了吗?第二,框架对于WEB开发来说,是十分欢快的事件,然而对于API来说,你真的不敢设想它会给你带来什么麻烦!最终您会感到十分苦楚~因为许多框架都是为WEB而生的。在PHP开发API接口时 web和api有什么不同?与web相比,api开发更加简洁,然而可能逻辑更加简单,因为api只返回后果,即只实现数据输入,而不出现页面。Web开发,更多的是GET和POST申请,还有PUT、DELETE申请。就像web开发一样,首先须要一些相干的参数,这些参数会通过客户端传递,可能是GET,也可能是POST,这须要开发团队彼此约定,或者须要指定一个对立的标准。应用参数时,依据利用的须要,实现数据处理,例如:取得用户信息,发送朋友圈,发送音讯,提交一局游戏完结的数据等等。当数据逻辑被解决后,返回客户端须要应用的相干数据,比方:用户信息数组,朋友圈列表,音讯状态,游戏后果数据等等,那么数据如何被返回到客户端?罕用的是XML,JSON,设置相应的header,而后间接打印出要返回的数据。当客户取得您返回的数据时,您将在客户端与用户进行交互。本文起源:标梵互动(https://www.biaofun.com/)

November 16, 2020 · 1 min · jiezi

关于php:Tailwind-CSS安装和构建的正确操作方式

导语就在前段时间laravel更新了8.0版本,其中有一个新个性是Jetstream是Laravel的新应用程序支架,Jetstream应用Tailwind CSS,您能够在Livewire或Inertia之间进行抉择。于是我就开始了tailwindcss钻研之旅。简介个别的UI中CSS框架都是内建各种预设的组件,比方表单、按钮、菜单、模态框等,当须要通过定制化设计时,组件的高度耦合性则带来很大的弊病。Tailwind并不提供事后设计好的内建组件,而是提供了更为根底的工具类(utility classes),可间接在HTML源码上构建齐全定制化的设计。 Tailwind是一个CSS框架的工具集,Tailwind的理念是抽取共用体(Utilities First)。Tailwind CSS是一个高度可定制的根底层CSS框架,提供了构建定制化所需的构建块,无需从新笼罩内建于框架内中的格调。 个性响应式Tailwind CSS的每个工具类都反对响应式布局,应用相似{screen}:的命名前缀以辨别响应式类。 组件敌对仅需应用工具类(utility classes)即可,Tailwind从反复模式中提取组件的工具类。 可定制Tailwind CSS是基于PostCSS开发的,通过JavaScript代码配置。 外围实用为主(Utility-First)传统的Web页面设计需手工为HTML元素编写CSS款式,应用Tailwind能够间接在HTML应用事后定义的类名来设置元素的款式。 自适应设计(Responsive Design)Tailwind中每个工具类均可有条件地利用到不同的断点(breakpoint),默认状况下依据常见挪动设施分辨率划分了4个断点,别离对应4个不同的媒体查问。 装置应用CDN<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">留神:在应用CDN构建之前,请留神,如果没有将Tailwind集成到您的构建过程中,那么许多使Tailwind CSS弱小的性能将不可用。您无奈自定义Tailwind的默认主题你不能应用任何指令一样@apply,@variants等等。您无奈启用以下性能 group-hover您无奈装置第三方插件您不能摇摆未应用的款式为了充分利用Tailwind,您的确应该通过npm装置它。 应用NPM进行装置应用npm装置Tailwind CSS,须要在电脑线装置好node.js环境。这里不再讲怎么装置node,参考本博客的以前公布的文章。初始化npm配置文件应用命令初始化package.json配置文件 npm init而后始终回车,直到实现(大略10次左右)。 或者还有更简略的办法,这里是不是应该写在前边的。(⊙o⊙)… npm init -y 这样就初始化好了package.json配置文件。 装置tailwindcss扩大包npm install tailwindcss这里咱们能够看到,装置的是1.9.6版本。 装置postcss-cli和autoprefixer扩大包npm install postcss-cli autoprefixer 将Tailwind增加到CSS应用@tailwind指令注入逆风的base,components和utilities格调为你的CSS:在我的项目目录新建src目录,新建styles.css文件,蕴含如下内容。 @tailwind base;@tailwind components;@tailwind utilities;css构建批改package.json文件scripts如下: "scripts": { "tailwind": "tailwindcss build src/styles.css -o public/styles.css" },在我的项目目录创立public文件夹。 而后运行命令 npm run tailwind即可实现构建,这时候咱们发现public文件夹内多了styles.css文件,在我的项目中援用测试一下。 <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>tailwindcss测试</title> <link rel="stylesheet" href="public/styles.css" /></head><body class="w-full h-screen flex justify-center items-center"> <div class="w-32 h-32 bg-red-600 rounded-3xl"></div></body></html> ...

November 16, 2020 · 1 min · jiezi

关于php:一款绝对让你惊艳的CSS框架TailwindCSS

前言前段时间,laravel更新8.0版本,零碎内置的Jetstream利用支架应用的是Tailwind CSS,于是勾起了我对Tailwind CSS的趣味。起初我的项目中也是逐渐应用,总体感觉超级爽。就像他的简介一样Utility-First效用优先的CSS框架。 相比bootstrap,semantic ui antd这些组件库,tailwind只是个css库,简略的说就是能够实现任何ui交互,而下面的组件库个别就是做个后盾利用,所以应用tailwind的环境更宽泛一些。 几个亮眼的中央首先是响应式设计。css的媒体查问写起来还是比拟麻烦的,如下: @media only screen and (max-width: 760px) { .navbar { width:100%; }}应用了Tailwind CSS就免去这些繁琐的货色。默认状况下,Tailwind应用挪动优先断点零碎,相似于您在Bootstrap或Foundation中可能应用的零碎。 这意味着未加前缀的实用程序(如uppercase)在所有屏幕尺寸上都无效,而带前缀的实用程序(如md:uppercase)仅在指定的断点及以上断点失效。 如下一段代码就能够实现不同尺寸显示不同款式,是不是比媒体查问写法不便很多呢! <div class="bg-red-500 sm:bg-green-500 md:bg-blue-500 lg:bg-pink-500 xl:bg-teal-500"></div>当然了,媒体尺寸断点也是能够自定义的。 // tailwind.config.jsmodule.exports = { theme: { screens: { 'tablet': '640px', // => @media (min-width: 640px) { ... } 'laptop': '1024px', // => @media (min-width: 1024px) { ... } 'desktop': '1280px', // => @media (min-width: 1280px) { ... } }, }}第二方面是Postcss使用Tailwind CSS联合了 postcss,将根底的 css 全副拆分为原子级别,同时还补全各种浏览器模式前缀,兼容性更好。例如:border: 1px solid #eee;拆分为:border-width、border-style、border-color<div class="border-width border-style border-color"></div>而且还反对依据本人设计稿定义符合本人我的项目的 csss 原子,这点真的很棒。 ...

November 15, 2020 · 1 min · jiezi

关于php:备受争议的PHP前景究竟如何我们该何去何从

原文链接:https://www.wjcms.net/archive...导语: 最近以来,小编在网上总是会看到这样或那样的对于php的新闻或者信息。比方,PHP始终是被黑。尤其是一些培训机构一直设置编程语言排名,以促成python和Java等语言的培训,从而误导了编程的初学者,并给初学者以PHP不好的印象。 PHP真的下坡了吗? PHP语言占据什么市场份额?从市场份额来看。您可能须要依据W3Techs提供的数据和报告,查看最新的PHP应用状况统计信息和市场位置。 W3Techs是一个外国网站,专门从事网络技术钻研,并提供无关各种网络技术应用的信息。从最新的后果中,咱们能够看出其服务器端编程语言的所有网站中,有79%应用PHP,稳居第一!将排在第二位的ASP.NET和第三位的JAVA远远甩在身后。而且,从十月以来寰球增长的网站来看,php也排在第二位。从编程语言排名来看。PHP自2001年该指数开始以来,PHP始终处于TIOBE指数的前10位,位置从未波动。而且,PHP长年均匀排名处于前列,第四位和第七位,它甚至是2004年TIOBE的年度编程。从语言倒退来看。PHP最受争议的“弱类型”个性,然而随着语言版本的公布和欠缺,性能和个性方面的批评开始变少了。HHVM通过hack间接“删除”“弱类型”性能的事实表明HHVM不喜爱“弱类型”性能。然而,在许多PHP程序员看来,这是PHP的次要劣势之一。 PHP变量的设计随便而优雅,可向所有河流凋谢,并为所有准备就绪。语言不是很简略吗?HHVM对PHP的性能晋升,让人眼前一亮,而磨刀霍霍的PHP7则让人万分期待。 还有另外一个最受争议的性能问题,就在前几天刚公布了8.0.0RC4,11月 26 日就会公布正式版本。从https://www.phoronix.com/测试...,从 PHP 7.4 stable 到 PHP 8 有小幅度改良,大概是 7% 的晋升,但如果 PHP 8 启用了 JIT,性能改良能够说是非常明显,比 PHP 7.4 stable 晋升了 92%。至于更旧的版本,PHP 8 with JIT 的性能是 PHP 5.4 的 5 倍。最重要的是,越来越多优良的扩大开发进去,给初中级开发者铺好了更多路线,施展好社区化开发的门路,能为疾速构建出本人的我的项目,高级程序员可能轻松利用个性,开发出更多好的扩大,构建更弱小的生态系统。 十分多的优良框架撑持php的弱小,例如Symfony/YII/laravel/thinkphp/CI等,在相似我的项目中重用代码能够节俭开发人员大量工夫和精力。框架提供了用于执行繁琐的代码工作的预构建模块。因而,开发人员能够花工夫开发理论的应用程序,而不用重建每个我的项目的基本功能。 结语: PHP是有史以来最好的语言,没有之一。PHP始终作为Web开发中的统治力量而存在,在PHP8.0版本的加持下,PHP必将开翻新场面,许多PHP业余人员都留在角落,实际上,每个人都必须承受PHP带来的变动和生态。 Swoole解决了IO沉重计划的问题,而JIT解决了计算沉重计划的问题。将来的PHP开发还不错。最初心愿大家都成为一名优良的CTO和架构师。

November 14, 2020 · 1 min · jiezi

关于php:php-字符串十六进制互转

字符串转16进制public static function String2Hex($string){ $hex = ''; for ($i=0; $i<strlen($string); $i++){ $ord = ord($string[$i]); $hexCode = dechex($ord); $hex .= substr('0'.$hexCode, -2); } return strToUpper($hex);}16进制转字符串public static function Hex2String($hex){ $string=''; for ($i=0; $i < strlen($hex)-1; $i+=2){ $string .= chr(hexdec($hex[$i].$hex[$i+1])); } return $string;}

November 14, 2020 · 1 min · jiezi

关于php:php浅拷贝和深拷贝

在PHP中, “=” 作为赋值符号,对于一般变量是深拷贝,对于对象来说是浅拷贝(对象的赋值是援用赋值)。 对象作为参数传递时,也是援用传递,无论函数定义时参数后面是否有&符号。概念:深拷贝:赋值时值齐全复制,齐全的copy,对其中一个作出扭转,不会影响另一个 浅拷贝:赋值时,援用赋值,相当于取了一个别名。对其中一个批改,会影响另一个 实际PHP中, “=” 赋值时,一般对象是深拷贝,然而对象来说,是浅拷贝。也就是说,对象的赋值是援用赋值。(对象作为参数传递时,也是援用传递,无论函数定义时参数后面是否有&符号) <?phpclass A{ public $aa = 100;}$a1 = new A();$a2 = $a1;$a1->aa = 200;echo $a2->aa; // 输入200echo PHP_EOL;要是想实现值的复制,php提供了clone函数来实现复制对象。例如: <?phpclass A{ public $aa = 100;}$a1 = new A();// 应用clone 实现复制对象$a2 = clone $a1;$a1->aa = 200;echo $a2->aa; // 输入100echo PHP_EOL;

November 13, 2020 · 1 min · jiezi

关于php:解决php接收post数据不完整问题

明天线上我的项目呈现了提交表单数据时失败的状况,最初发现是因为php端接管post数据不残缺导致的,关上F12发现前端的数据曾经通过post传递到后端,数据是残缺的,然而在php端接收数据时,数据就变得不残缺了,短少了局部数据,既然找到了问题解决就不便了 解决: 批改php.ini的配置文件,找到配置文件的max_input_vars,如果没有自行减少 max_input_vars = 5000在php中异步max_input_vars 的默认值为1000,这里咱们减少到5000,重启php环境,从新测试,发现提交表单失常

November 12, 2020 · 1 min · jiezi

关于php:使用唯一id生成唯一字符串订单号唯一邀请码等唯一字符串并可以反序列化原id

Hashids包用来把整数生成惟一字符串(比方:通过加密解密id来暗藏实在id)generate short unique ids from integers官网地址 反对多种语言:JavaScript, Ruby, Python, Java, Scala, PHP, Perl, Perl 6, Swift, Clojure, Objective-C, C, C++11, D, F#, Go, Erlang, Lua, Haskell, OCaml, Elixir, Rust, Smalltalk, ColdFusion, Kotlin, Nim, VBA, Haxe, Crystal, Elm, ActionScript, Bash, R, TSQL, PostgreSQL, PLpgSQL, Dart, Io, Julia and for .NET上面次要介绍golang的用法:第一步,下载包go get github.com/speps/go-hashids上代码package mainimport "fmt"import "github.com/speps/go-hashids"func main() { hd := hashids.NewData() hd.Salt = "wozuishuai" // 盐值,能够依据不必的业务,应用不同的盐值 hd.MinLength = 8 // 生成惟一字符串的最小长度,留神:是最小,不是固定 h, _ := hashids.NewWithData(hd) e, _ := h.Encode([]int{2, 45, 1, 44}) // 参数的都是slice,当咱们 fmt.Println(e) d, _ := h.DecodeWithError(e) fmt.Println(d)}留神:1.hd.Salt = "this is my salt" 盐值,能够依据不必的业务,应用不同的盐值2.hd.MinLength = 30 生成惟一字符串的最小长度,留神:是最小,不是固定,生成的有可能比该值要长3.h.Encode([]int{45, 434, 1313, 99}),接管参数是slice,咱们大多数时候应用惟一id操作,所以只须要传[]int{1},一个元素即可4.h.DecodeWithError(e),反序列化出你的原始id,也是slice类型5.有趣味的能够去看看源码包.很简略

November 12, 2020 · 1 min · jiezi

关于php:抓包工具Charles踩坑

一、抓取Https地址呈现unknown的状况 Charles工具默认只能抓取http地址, 若要抓取https地址, 须要做的有两步: SSL配置和装置证书 ssl配置点击上方菜单栏Proxy -> SSL Proxying Settings 在左侧include窗口增加主机和端口, 增加完如下图, :代表所有地 址和端口, *:443是SSL通用端口. 装置证书上一步实现之后, 你刷新谷歌浏览器会发现, 您的链接不是私密链接, 所有页面都打不开. 这是因为没有装置并信赖证书 本机是在win10环境下, 顺次点击:Help -> SSL Proxying -> Install Charles Root Certificate 而后点击装置证书 点击后呈现存储地位抉择, 以后用户和本地计算机都能够, 重点是下一步: 肯定要抉择将所有证书都放入下列存储!!!而后点击浏览, 抉择受信赖的证书颁发机构 最初, 点击实现, 装置.补充: 装置实现后, 机器最好重启一下, 我的机器是重启才失效了的. 此时能够看见, https地址的内容被抓取胜利了, 左侧的小图标亮了阐明是抓取胜利了, 除非一些网站做了特地的防抓包伎俩, 比方上图中谷歌的一些接口.

November 12, 2020 · 1 min · jiezi

关于php:抓包工具Charles使用详解

November 12, 2020 · 0 min · jiezi

关于php:lnmporg如何更改TP60框架的pathinfo模式

网上好多都不论用,搞了一天,最初尝试了一下,只须要改一个就好了.将include enable-php.conf 改为 include enable-php-pathinfo.conf即可而后 lnmp restart 这是一键装置后的 nginx.conf 文件的配置原文 server { listen 443 ssl; listen 80 default_server; #listen [::]:80 default_server ipv6only=on; server_name _;#写本人的域名 index index.html index.htm index.php; root /home/wwwroot/default; #error_page 404 /404.html; # Deny access to PHP files in specific directory #location ~ /(wp-content|uploads|wp-includes|images)/.*.php$ { deny all; } include enable-php.conf;#这是替换的中央:将include enable-php.conf 改为 include enable-php-pathinfo.conf location /nginx_status { stub_status on; access_log off; } location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*.(js|css)?$ { expires 12h; } location ~ /.well-known { allow all; } location ~ /. { deny all; } access_log /home/wwwlogs/access.log; }而后就好了! ...

November 11, 2020 · 1 min · jiezi

关于php:Hyperf-发布-v2018-版本企业级的-PHP-微服务云原生协程框架

更新内容本周次要新增了局部个性,并修复了一些组件的 ????Bug,持续晋升 Hyperf 的稳定性,公布于 2.0.18 版。 倡议用户应用以下命令更新此版本。 composer update "hyperf/*" -o间接拜访 官网 hyperf.io 或 文档 hyperf.wiki 查看更新内容 注意事项请移除 require-dev 中的 doctrine/common 组件doctrine/common 组件的 2.x 版本与 hyperf/utils 抵触,所以会导致 hyperf/utils 无奈更新。 新增#2752 为注解 @AutoController @Controller 和 @Mapping 增加 options 参数,用于设置路由元数据。修复#2768 修复 WebSocket 握手失败时导致内存泄露的问题。#2777 修复低版本 redis 扩大,RedisCluster 构造函数 $auth 不反对 null,导致报错的问题。#2779 修复因没有设置 translation 配置文件导致服务启动失败的问题。变更#2765 变更 Concurrent 类中创立协程逻辑,由办法 Hyperf\\Utils\\Coroutine::create() 代替原来的 Swoole\\Coroutine::create()。优化#2347 为 AMQP 的 ConsumerMessage 减少参数 $waitTimeout,用于在协程格调服务中,平安进行服务。对于 HyperfHyperf 是基于 Swoole 4.5+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量罕用的组件,性能较传统基于 PHP-FPM 的框架有质的晋升,提供超高性能的同时,也放弃着极其灵便的可扩展性,规范组件均基于 PSR 规范 实现,基于弱小的依赖注入设计,保障了绝大部分组件或类都是 可替换 与 可复用 的。 ...

November 11, 2020 · 1 min · jiezi

关于php:使用phpofficephpexcel拓展读取excel内容卡死解决

明天一个线上我的项目反馈导入excel文件时,网页间接卡死,导入excel文件时失败,通过一步一步的验证发现是在读取excel文件时卡死,此我的项目应用的是phpoffice/phpexcel拓展,最初发现是在执行load办法加载excel文件时呈现卡死,之前在导入excel文件始终是失常的,而且excel中的数据也不是很多,到底是因为什么起因造成的呢? 最初在查找phpoffice/phpexcel官网文档中发现,这是因为excel文件中存在了某些特殊字符导致了加载excel文件时解体,既然找到了起因,就肯定有解决办法,在phpoffice/phpexcel中有一个属性能够解决此办法readDataOnly,此属性在拓展中默认时false,咱们须要将readDataOnly属性设置为true $PHPExcel->setReadDataOnly(true);  //过滤excel中的特殊字符所以残缺的读取excel的代码如下: $PHPExcel = new PHPExcel_Reader_Excel2007();$file = 'excel文件';try {    if (!$PHPExcel->canRead($file)) {        //默认用excel2007读取excel,若格局不对,则用之前的版本进行读取        $PHPExcel = new PHPExcel_Reader_Excel5();    }    $PHPExcel->setReadDataOnly(true);  //过滤excel中的特殊字符    $excel = $PHPExcel->load($file);//加载excel    //读取excel文件中的第一个工作表    $currentSheet = $excel->getSheet(0);} catch (Exception $e) {    throw new InvalidValueException('请抉择正确的导入文件!');}$allRow = $currentSheet->getHighestRow() - 1; //获取excel总行数//读取excel信息for ($currentRow = 1; $currentRow <= $allRow; $currentRow++) {//读取指定列数据0示意第一列$currentSheet->getCellByColumnAndRow(0, $currentRow + 1)->getValue()}

November 11, 2020 · 1 min · jiezi

关于php:高手在民间PHP-peclhttp简单可用的短信验证码快速接入代码

在当初,短信验证码利用十分宽泛,然而要想疾速高效的接入并调试好,还是十分消耗工夫的,因为市场的短信服务商太多,一家家的比照考查十分耗时间,上面分享一个我用过且十分稳固的一个短信接口作为演示示例:`<?php$client = new http\Client;$request = new http\Client\Request;$request->setRequestUrl('https://vip.veesing.com/smsAp...');$request->setRequestMethod('POST');$body = new http\Message\Body;$body->append(new http\QueryString(array( 'appId' => '41KYR0EB**', 'appKey' => 'IIWCKKSR7NOQ**', 'phone' => '1561894**', 'templateId' => '1043', 'variables' => '1234')));$request->setBody($body);$request->setOptions(array());$request->setHeaders(array( 'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8'));$client->enqueue($request)->send();$response = $client->getResponse();echo $response->getBody(); `以上就是PHP - pecl_http接入短信验证码的示例,心愿以上的分享,能够晋升大家的工作效率,有须要的复制粘贴拿走去用吧! PHP - pecl_http.php和文档阐明下载

November 10, 2020 · 1 min · jiezi

关于php:作为一个优秀的打工人PHP-HTTPRequest2接入短信验证码还不是手到擒来

作为一个优良的打工人,PHP - HTTP_Request2接入短信验证码还不是手到擒来 前段时间,打工人的梗忽然的火了起来:打工人打工魂,打工都是人上人。 作为资深打工人,明天给大家分享PHP - HTTP_Request2接入短信验证码的示例,心愿大家能够用的上: `<?phprequire_once 'HTTP/Request2.php';$request = new HTTP_Request2();$request->setUrl('https://vip.veesing.com/smsAp...');$request->setMethod(HTTP_Request2::METHOD_POST);$request->setConfig(array( 'follow_redirects' => TRUE));$request->setHeader(array( 'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8'));$request->addPostParameter(array( 'appId' => '41KYR0EB**', 'appKey' => 'IIWCKKSR7NOQ**', 'phone' => '1561894**', 'templateId' => '1043', 'variables' => '1234'));try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody();} else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .$response->getReasonPhrase();}}catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage();}` 以上就是PHP - HTTP_Request2接入短信验证码的示例,感觉有用就珍藏一下吧,万一哪天须要,而后又找不到了呢! PHP - HTTP_Request2.php和文档阐明下载 ...

November 10, 2020 · 1 min · jiezi

关于php:Swoole-如何使用-Xdebug-进行单步调试

在 PHP-FPM 中应用 Xdebug 的人应该不少,而在 Swoole 中应用 Xdebug 的人还是很少的,起因是 Swoole 扩大明确阐明了和 Xdebug 扩大抵触 不过好在咱们社区成员给力,提供了一个 Sdebug ,在此咱们应该感激 @mabu233 和 @huanghantao 进行了兼容,让 Xdebug 可用于 Swoole 环境进行断点、调试 之前在 Swoole 文档中补充了 Sdebug 的装置,同样的 Sdebug 的 README 也进行了批改介绍如何装置,不过都是简略阐明如何胜利加载扩大,没有具体阐明配置 先说一下如何装置 Sdebug 为了防止 Swoole 的检测 Xdebug 正告,所以扩大注册的名称是 Sdebuggit clone git@github.com:swoole/sdebug.git -b sdebug_2_9 --depth=1cd sdebugphpize./configuremake cleanmakemake install步骤很简略,就是 clone 源码,进入目录而后编译 如果你的 PHP 是通用装置,没有批改默认地位等等,也能够间接运行目录下的脚本: ./rebuild.sh如果你的 phpize 不是默认门路的话,请应用绝对路径;同样的 php-config 须要应用--with-php-config=加上你的绝对路径编译胜利后须要在 php.ini 加载扩大 zend_extension=xdebug.so编译实现后生成的 so 文件名还是 xdebug查看是否加载胜利 php --ri sdebug别走,还没完,还须要一些其余的配置,不然你去断点会发现不起作用咱们还须要在 php.ini 中退出这几个配置项 ...

November 10, 2020 · 1 min · jiezi

关于php:Swoole-v457-版本发布新增enableswoolejson编译选项

Swoole 正在参加 2020 年度 OSC 中国开源我的项目评比,评比曾经来到了最初一周,还有没给 Swoole 投票的小伙伴请点击下方链接投出您的一篇:https://www.oschina.net/p/swoole-server在上个版本中增加的 swoole_substr_json_decode 函数,因为少部分用户的扩大依赖程序问题,所以增加了一个编译选项--enable-swoole-json,用于启用 swoole_substr_json_decode 反对 在此版本如果须要应用此函数,须要在编译时加上此选项。同时此版本还反对了负偏移量 $val = json_encode(['hello' => 'swoole']);$str = pack('N', strlen($val)) . $val . "\r\n";$l = strlen($str) - 6;var_dump(json_decode(substr($str, 4, $l), true));var_dump(swoole_substr_json_decode($str, 4, $l, true));var_dump(swoole_substr_json_decode($str, -(strlen($str)-4), $l, true));更新内容如下: 新增 APICoroutine\Socket 客户端新增 writeVector, writeVectorAll, readVector, readVectorAll 办法 (#3764) (@huanghantao)加强为 server->stats 减少 task_worker_num 和 dispatch_count (#3771) (#3806) (@sy-records) (@matyhtf)增加了扩大依赖项,包含 json, mysqlnd, sockets (#3789) (@remicollet)限度 server->bind 的 uid 最小值为 INT32_MIN (#3785) (@sy-records)为 swoole_substr_json_decode 增加了编译选项,反对负偏移量(#3809) (@matyhtf)反对 CURL 的 CURLOPT_TCP_NODELAY 选项 (swoole/library#65) (@sy-records) (@deminy)修复修复同步客户端连贯信息谬误 (#3784) (@twose)修复 hook scandir 函数的问题 (#3793) (@twose)修复协程屏障 barrier 中的谬误 (swoole/library#68) (@sy-records)内核应用 boost.stacktrace 优化 print-backtrace (#3788) (@matyhtf) ...

November 10, 2020 · 1 min · jiezi

关于php:PHP-cURL复制粘贴性接入短信验证码示例

因为我的项目的须要,我找了一个能够间接复制粘贴的短信验证码接入示例,当初分享进去,心愿能够进步各位同仁的工作效率,代码如下: `<?php $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "https://vip.veesing.com/smsApi/verifyCode", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "appId=41KYR0EB&appKey=IIWCKKSR7NOQ&phone=1561894**&templateId=1043&variables=1234", CURLOPT_HTTPHEADER => array( "Content-Type: application/x-www-form-urlencoded;charset=utf-8"),)); $response = curl_exec($curl); curl_close($curl);echo $response;` 这是各大云市的短信供应商的短信接口,稳定性方面,大家也能够测试一下,我本人测过,自认为十分稳固,原创不易,心愿大家给个三连。PHP - cURL.php和文档阐明下载

November 9, 2020 · 1 min · jiezi

关于php:laravel8更新之速率限制改进

原文地址:https://www.wjcms.net/archive...Laravel的申请速率限制器性能已加强,具备更大的灵活性和性能,同时仍放弃与先前版本的throttle中间件API的向后兼容性。 速率限制器是应用RateLimiter立面的for办法定义的。该for办法承受一个速率限制器名称和一个Closure,该Closure返回应利用于调配了该速率限制器的路由的限度配置: use Illuminate\Cache\RateLimiting\Limit;use Illuminate\Support\Facades\RateLimiter;RateLimiter::for('global', function (Request $request) { return Limit::perMinute(1000);});因为速率限制器回调接管传入的HTTP申请实例,因而您能够依据传入的申请或通过身份验证的用户动静构建适当的速率限度: RateLimiter::for('uploads', function (Request $request) { return $request->user()->vipCustomer() ? Limit::none() : Limit::perMinute(100);});有时您可能心愿将速率限度按任意值进行细分。例如,您可能心愿容许用户每个IP地址每分钟100次访问给定路由。为此,您能够by在建设速率限度时应用以下办法: RateLimiter::for('uploads', function (Request $request) { return $request->user()->vipCustomer() ? Limit::none() : Limit::perMinute(100)->by($request->ip());});能够应用throttle 中间件将速率限制器附加到路由或路由组。油门中间件承受您心愿调配给路线的速率限制器的名称: Route::middleware(['throttle:uploads'])->group(function () { Route::post('/audio', function () { // }); Route::post('/video', function () { // });});

November 8, 2020 · 1 min · jiezi

关于php:个人短网址生成平台-自定义域名开启防红统计访问量

在咱们的我的项目当中,如果须要更好流传咱们的流动链接,然而链接太长1来是不美观,2来是太过于“轻便”,例如拼多多,淘宝联盟,他们的推广链接都是有短链接的,还有新浪微博。 然而,这些始终都是他人的,咱们调用他人的API进行生成,不稳固,所以能够本人做一个,注册一个略微短一些的域名就行,这就是咱们本次开源我的项目的初衷,咱们就是为了让大家可能有一个稳固的平台,所以我开发了集体短网址生成零碎。 性能概览1、创立短网址,能够抉择短网址域名、能够抉择防红2、绑定域名,不便创立不同域名下的短网址3、能够设置防红,在微信端点击短网址,疏导用户再浏览器关上4、能够设置短网址的开关,必要时能够敞开短网址的拜访权限5、能够统计短网址的点击次数,即访问量 装置环境php5.6-7.0mysql 5.7左右均可apache服务器 因为我这里只做了apache服务器的伪动态,伪动态只适宜apache服务器应用。 装置步骤间接拜访install即可例如你的域名是:http://www.xxx.com/你的程序放在服务器根目录下的dwz目录那么启动装置的Url是http://www.xxx.com/dwz/install/ 伪动态设置(1)如果你是装置在服务器根目录,则无需设置伪动态(2)如果装置的时候,间接把域名指向指定的子目录作为根目录,则也无需配置伪动态(3)如果你是装置在服务器根目录下的子目录,但你的服务器没法把域名指向指定的目录作为根目录,例如你的代码目录是http://www.xxx.com/dwz/那么你须要设置伪动态规定 设置办法:(1)在服务器根目录,记住,是根目录不是短网址零碎的根目录,是整个服务器的根目录,创立一个问动态文件名称为.htaccess (2)而后拷贝上面代码,保留即可 例如你的代码放在dwz子目录,须要批改上面伪动态规定代码 # 解析xxx.cn到dwz子目录RewriteEngine on RewriteCond %{HTTP_HOST} ^xxx.cn$ RewriteCond %{REQUEST_URI} !^/dwz/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /dwz/$1 RewriteCond %{HTTP_HOST} ^xxx.cn$ RewriteRule ^(/)?$ dwz/index.php [L]这个操作的目标就是当拜访你的域名xxx.cn的时候,就是默认把dwz这个目录作为服务器的目录,当然,如果你在解析域名的时候,能够间接在服务器进行绑定到子目录,就更适合,宝塔面板能够这样做。 后盾地址是:http://www.xxx.cn/dwz/index/ 截图展现 源码https://github.com/likeyun/Pe... Author:TANKINGDate:2020-11-07Web:http://www.likeyun.cnWeChat:face6009

November 7, 2020 · 1 min · jiezi

关于php:laravel8更新之维护模式改进

原文连贯:https://www.wjcms.net/archive...对php artisan down命令进行了一些十分丑陋的改良。 在以前的版本中,为了只容许某些人拜访该网站,您必须应用白名单性能,如本博文所述: 当初反对预渲染保护模式模板,并且打消了最终用户在保护模式期间遇到谬误的机会。然而,为此,必须将以下行增加到您的文件中。这些行应间接放在现有常量定义下:public/index.phpLARAVEL_START define('LARAVEL_START', microtime(true));if (file_exists(__DIR__.'/../storage/framework/maintenance.php')) { require __DIR__.'/../storage/framework/maintenance.php';}注:php artisan down --message已被移除 如何创立自定义Laravel保护页面 应用Laravel 8,您能够领有一个机密,而不是应用IP白名单。要配置它,您要做的就是: php artisan down --secret=YOUR_SECRET_HERE确保YOUR_SECRET_HERE应用平安的弦线更换整机! 而后拜访处于保护模式的网站,请拜访 你的域名+/YOUR_SECRET_HERE,这将生成一个机密cookie,使您能够像平常一样浏览该网站! 这是使您的网站处于保护模式的好办法,然而依然容许某些人能够拜访它! 该php artisan down命令的另一个很棒的补充是您能够预渲染保护页面,这样即便您运行composer update最终用户,依然能够看到保护页面,而不是一些谬误。 为此,只需运行: php artisan down --render="errors::503"这样,您能够进行宽泛的保护,而不用放心用户看到一些奇怪的谬误,而不必放心页面看起来敌对。 很酷的是,您能够将标记组合在一起。例如,您能够运行以下命令以在显示的页面上增加秘密并同时更改状态代码: php artisan down --render="errors::503" --status=200 --secret=YOUR_SECRET_HERE

November 7, 2020 · 1 min · jiezi

关于php:Swoole-中的一些概念整理

Swoole 是一个十分优良的PHP 的协程高性能网络通信引擎。 在学习过程中,遇到了一些新或旧的概念,在此整顿一下。 长连贯/短连贯长连贯: 客户端和服务端建设连贯后不进行断开,之后客户端再次拜访这个服务器上的内容时,持续应用这一条连贯通道。短连贯: 客户端和服务端建设连贯,发送完数据后立马断开连接。下次要取数据,须要再次建设连贯。 串行/并行/并发串行:执行多个工作时,各个工作按程序执行,实现一个之后能力进行下一个。并行:多个工作在同一时刻产生并执行。并发:同一时刻须要执行N 个工作 IO(Input/Output,输入输出)在计算机中,输出 / 输入(即 IO)是指信息处理系统(比方计算机)和内部世界(能够是人或其余信息处理系统)的通信。 输出是指零碎接管的信号或数据,输入是指从零碎收回的数据或信号。 波及到IO 操作的通常有磁盘、网络、文件等。 同步/异步同步和异步是一种音讯通信机制。其关注点在于 被调用者返回 和 后果返回 之间的关系, 形容对象是被调用对象的行为。 同步:在收回一个同步调用后,没有失去后果返回之前,该调用就不会返回,只有期待后果返回之后才会继续执行后续操作。异步:收回调用,间接返回。异步能够通过状态、回调、告诉调用者后果,能够先执行其余操作,直到回调后果返回之后,再回来执行回调那局部的操作。 阻塞/非阻塞阻塞和非阻塞是一种业务流程解决形式。关注点在于调用产生时 调用者状态 和 被调用者返回后果 之间的关系。 形容的是期待后果时候调用者的状态。 此时后果可能是同步返回的,也能是异步返回。 阻塞:在后果返回之前,该线程会被挂起,后续代码只有在后果返回后能力执行。非阻塞:在不能立即获取后果前,该调用不会阻塞以后线程。 同步阻塞/非同步阻塞理论编程中,通过线程实现过程的同步非阻塞,通过协程实现线程的同步非阻塞。 同步阻塞:打电话问老板有没有某书(调用),老板说查一下,让你别挂电话(同步),你始终期待老板给你后果,什么事也不做(阻塞)。 同步非阻塞:打电话问老板有没有某书(调用),老板说查一下,让你别挂电话(同步),等电话的过程中你还一边嗑瓜子(非阻塞)。 异步阻塞/异步非阻塞异步阻塞:打电话问老板有没有某书(调用),老板说你先挂电话,有了后果告诉你(异步),你挂了电话后(完结调用), 除了等老板电话告诉后果,什么事件也不做(阻塞)。 异步非阻塞:打电话问老板有没有某书(调用),老板说你先挂电话,有了后果告诉你(异步),你挂电话后(完结调用),一遍等电话,一遍嗑瓜子。(非阻塞) 参考链接Swoole 中波及的一些基本概念

November 7, 2020 · 1 min · jiezi

关于php:LeetCode-15PHP求解三数之和问题

原文链接:何晓东 博客 三数之和给你一个蕴含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不反复的三元组。 留神:答案中不能够蕴含反复的三元组。 示例: 给定数组 nums = [-1, 0, 1, 2, -1, -4],满足要求的三元组汇合为:[ [-1, 0, 1], [-1, -1, 2]]起源:力扣(LeetCode)链接:https://leetcode-cn.com/probl... 解题思路 1暴力枚举法,三层 for + if 判断就能够了,这样作面试中 offer 会成为他人的。不写代码了,数据量大了也容易超时。 解题思路 2能够先固定一个值,而后寻找后两个值时可采取双指针的办法,将总的工夫复杂度优化到 O(n^2)。 实现的过程中,要留神优化以及去重。 首先咱们先对原数组进行排序,这样能够把反复的值集中到一起,便于去重。 确定第一个元素时,如果它曾经比 0 大了,那么能够间接跳出循环,因为前面的数字都比它大。如 [1, 2, 3, 4], i = 0, nums[i] > 0, 这样是不可能产生非法的状况的,间接 break。 确定第一个元素时,如果发现它与它后面的值一样,那么跳过本轮。如 [-1, -1, 0, 1], 在第一轮后,曾经选出了 {-1, 0, 1}, 当初 i = 1,nums[i] == nums[i - 1], 为了防止反复,间接 continue。 ...

November 7, 2020 · 2 min · jiezi

关于php:打造属于自己的PHP现代框架

1.composer结构我的项目2.增加container容器实现依赖注入3.集成信息调试工作,丑化信息展现4.将路由零碎整合到框架之中5.对返回的response进行优化返回6.视图模板引擎融入到框架之中......待续

November 6, 2020 · 1 min · jiezi

关于php:fzaninottoFaker-不继续维护-基于其自建中文-Faker-生成库

githubpackagistPoppy Faker 是基于 fzaninotto/Faker 的中文版本, 因为之前的版本蕴含语言过多, 作者曾经进行保护, 所以将这个数据进行拆离, 并退出中国特色的局部验证规定. Faker 能够帮忙你创立数据库数据, XML 报表, 填写假地址, 或者匿名的数据. 装置composer require poppy/faker根本应用在我的项目根目录下运行 $ php -S 0.0.0.0:8000 -t tests/PHP 7.2.33 Development Server started at Thu Nov 5 15:21:19 2020Listening on http://0.0.0.0:8000Document root is /path/of/poppy/faker/testsPress Ctrl-C to quit.而后再浏览器拜访即可获取具体的示例数据 http://127.0.0.1:8000/ # 返回 带有款式的示例数据http://127.0.0.1:8000/?md # 返回 Markdown 格局数据基于包的调整我的项目删除 ORM删除除 [en_US, zh_CN, zh_TW] , 之外的语言减少 zhCN 身份证号生成创立假数据应用 \\Poppy\\Faker\\Factory::create('zh_CN') 来创立和初始化生成器, 这里保留之前英文版生成数据的规定 <?php// use the factory to create a \Poppy\Faker\Generator instance$faker = \Poppy\Faker\Factory::create('zh_CN');// generate data by accessing propertiesecho $faker->name; // 'Lucy Cechtelar';echo $faker->address; // "426 Jordy Lodge // Cartwrightshire, SC 88120-6700"echo $faker->text; // Dolores sit sint laboriosam dolorem culpa et autem. Beatae nam sunt fugit // et sit et mollitia sed. // Fuga deserunt tempora facere magni omnis. Omnis quia temporibus laudantium // sit minima sint.Base// 生成随机整数 0 - 9$faker->randomDigit; // 8// 生成惟一整数$faker->unique()->randomDigit; // 1// 生成随机不为空的整数$faker->randomDigitNotNull; // 8// 生成随机数字$faker->randomNumber($nbDigits = 5, $strict = false); // 6783// 生成随机浮点数$faker->randomFloat($nbMaxDecimals = null, $min = 0, $max = null); // 13399.11050914// 在指定范畴内生成随机数$faker->numberBetween($min = 1000, $max = 9000); // 3953// 生成随机字符$faker->randomLetter; // t// 在给定的数组中,随机生成给定的个数字符$faker->randomElements($array = ['a', 'b', 'c'], $count = 2); // Array( [0] => a [1] => c)// 在给定的数组中,生成单个随机字符$faker->randomElement($array = ['a', 'b', 'c']); // a// 打乱给定的字符串$faker->shuffle('hello, world'); // elrlh dowol,// 打乱给定的数组$faker->shuffle([1, 2, 3]); // Array( [0] => 3 [1] => 1 [2] => 2)// 给占位符生成随机整数 (数字为#)$faker->numerify('Hello ###'); // Hello 713// 给占位符生成随机字符串 (字符串为?)$faker->lexify('Hello ???'); // Hello jjg// 给占位符生成混合的随机字符串$faker->bothify('Hello ##??'); // Hello 79ks// 给占位符生成随机的字符(字母、数字、符号)$faker->asciify('Hello ***'); // Hello B.7// 依据正则规定生成随机字符$faker->regexify('[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'); // _XD%HRE@VUREXV2D.OLYELorem// 生成随机个数的字符串$faker->word; // 议// 随机生成指定个数的字符串$faker->words($nb = 3, $asText = false); // Array( [0] => 玩 [1] => 转 [2] => 答)// 随机生成一条语句$faker->sentence($nbWords = 6, $variableNbWords = true); // 纳怀房海交知.// 随机生成指定条数的语句$faker->sentences($nb = 3, $asText = false); // Array( [0] => 授界类表如守. [1] => 尼痛念化人归懂总. [2] => 圣味送杂含贝机四.)// 随机生成一个段落$faker->paragraph($nbSentences = 3, $variableNbSentences = true); // 雄摇马史她戴袋. 层关飞某阿喊. 松上助仍奥外讲.// 随机生成指定个数段落$faker->paragraphs($nb = 3, $asText = false); // Array( [0] => 充条数和制尔进知中. 果藏供创阵急遗然. 从请生反雄仍洲叶护. [1] => 报停暗险端市. 兴定北洛革. 去夜慢纳脚脱. 调雪妙托脱走它相. 汉典儿九刻. [2] => 真语强究授童剧银. 型济著武热吧克藏. 母英封蒙.)// 随机生成一个文本$faker->text($maxNbChars = 200); // 熟称喝救告吸确. 馆推布信久识. 民又事黄要之怎划. 奇兰现介先对戏. 罪总乎论雪兵黄岛. 禁安议做亲差学极.Person// 职位$faker->title; // 太太// 称呼$faker->titleMale; // 传授// 女性称呼$faker->titleFemale; // 律师// 姓名$faker->name // 萧文君// 名字$faker->firstName // 志明// 男性名字$faker->firstNameMale // 华// 女性名字$faker->firstNameFemale // 楠// 姓$faker->lastName // 马// 随机生成一个能够校验的身份证号$faker->idNumber // 640181200809108307Address// 随机生成省份/州$faker->state; // 河南省// 随机城市省份/州缩写$faker->stateAbbr; // 蒙// 随机生成城市后缀$faker->citySuffix; // Ville// 随机生成街道后缀$faker->streetSuffix; // Street// 随机生成修建编号$faker->buildingNumber; // 11// 随机生成城市$faker->city; // 拉萨// 随机生成街道名$faker->streetName; // 畅 Street// 随机生成街道地址$faker->streetAddress; // 71 孟 Street// 随机生成邮编$faker->postcode; // 217000// 随机生成地址$faker->address; // 沈阳兴山区// 随机生成国家$faker->country; // 圣马力诺// 随机生成纬度$faker->latitude($min = -90, $max = 90); // 75.15737// 随机生成经度$faker->longitude($min = -180, $max = 180); // -81.385411Phone Number// 生成随机电话号码$faker->phoneNumber; // 13273265620// 随机生成e164电话$faker->e164PhoneNumber; // +3411056457052Company// 随机生成公司$faker->company; // 巨奥信息有限公司// 随机生成公司后缀$faker->companySuffix; // 传媒有限公司// 随机生成职务$faker->jobTitle; // 必Text// 随机生成一段文本$faker->realText($maxNbChars = 200, $indexSize = 2); // CHAPTER IV. The Rabbit Sends in a deep, hollow tone: 'sit down, both of you, and don't speak a word till I've finished.' So they had to pinch it to make out exactly what they WILL do next! If they.Datetime// 随机生成工夫戳$faker->unixTime($max = 'now'); // 84146285// 随机生成工夫$faker->dateTime($max = 'now', $timezone = date_default_timezone_get()); // DateTime Object( [date] => 1981-09-02 21:14:42.000000 [timezone_type] => 3 [timezone] => Asia/Shanghai)// dateTimeAd$faker->dateTimeAD; // DateTime Object( [date] => 0308-03-16 05:39:50.000000 [timezone_type] => 3 [timezone] => Asia/Shanghai)// 随机生成ios8601工夫$faker->iso8601($max = 'now'); // 1991-03-04T20:59:46+0800// 依据格局随机生成日期$faker->date($format = 'Y-m-d', $max = 'now'); // 1983-03-01// 依据格局随机生成工夫$faker->time($format = 'H:i:s', $max = 'now'); // 22:34:27// 生成指定范畴的工夫$faker->dateTimeBetween($startDate = '-30 years', $endDate = 'now'); // DateTime Object( [date] => 2006-07-12 13:47:24.000000 [timezone_type] => 3 [timezone] => Asia/Shanghai)// 随机生成一个指定距离的工夫$faker->dateTimeInInterval($startDate = '-30 years', $interval = '+ 5 days', $timezone = date_default_timezone_get()); // DateTime Object( [date] => 1990-11-08 17:13:04.000000 [timezone_type] => 3 [timezone] => Asia/Shanghai)// 随机生成以后世纪的工夫$faker->dateTimeThisCentury($max = 'now', $timezone = date_default_timezone_get()); // DateTime Object( [date] => 1991-02-19 01:39:03.000000 [timezone_type] => 3 [timezone] => Asia/Shanghai)// 随机生成以后十年的工夫$faker->dateTimeThisDecade($max = 'now', $timezone = date_default_timezone_get()); // DateTime Object( [date] => 2013-12-25 22:46:17.000000 [timezone_type] => 3 [timezone] => Asia/Shanghai)// 随机生成以后年的工夫$faker->dateTimeThisYear($max = 'now', $timezone = date_default_timezone_get()); // DateTime Object( [date] => 2020-05-18 23:34:51.000000 [timezone_type] => 3 [timezone] => Asia/Shanghai)// 随机生成以后月的工夫$faker->dateTimeThisMonth($max = 'now', $timezone = date_default_timezone_get()); // DateTime Object( [date] => 2020-10-27 04:22:07.000000 [timezone_type] => 3 [timezone] => Asia/Shanghai)// 随机生成 am/pm$faker->amPm($max = 'now'); // 下午// 随机生成月份的某一天$faker->dayOfMonth($max = 'now'); // 30// 随机生成星期$faker->dayOfWeek($max = 'now'); // 星期日// 随机生成月份$faker->month($max = 'now'); // 03// 随机生成月份的名称$faker->monthName($max = 'now'); // 十一月// 随机生成年份$faker->year($max = 'now'); // 2004// 随机生成世纪$faker->century; // XV// 随机生成时区$faker->timezone; // Asia/HebronInternet// 随机生成邮箱地址$faker->email; // xiao_er@hotmail.com// 随机生成平安的邮箱地址$faker->safeEmail; // an82@example.net// 随机生成收费的邮箱地址$faker->freeEmail; // alian@126.com// 随机生成公司邮箱地址$faker->companyEmail; // tong_mai@qu.com// 随机生成免费邮箱域名$faker->freeEmailDomain; // 126.com// 随机生成平安邮箱域名$faker->safeEmailDomain; // example.org// 随机生成用户名$faker->userName; // ting_du// 随机生成明码$faker->password; // h1RZMuV54|n=Q$L-in]// 随机生成域名$faker->domainName; // yan.org// 随机生成域$faker->domainWord; // bai// todo Tld$faker->tld; // biz// 随机生成url地址$faker->url; // https://zhou.info/方-农-死-规.html// 随机生成块$faker->slug; // 的-城-心-古-终-参-济-文// 随机生成ipv4地址$faker->ipv4; // 243.54.13.136// 随机生成本地ipv4地址$faker->localIpv4; // 10.5.211.82// 随机生成ipv6地址$faker->ipv6; // 7ca1:9d43:46d5:589f:1b2b:e372:5e17:1a91// 随机生成mac地址$faker->macAddress; // 14:38:9C:55:CD:C5UserAgent// 用户代理$faker->userAgent; // Mozilla/5.0 (X11; Linux x86_64; rv:6.0) Gecko/20190828 Firefox/36.0// 谷歌$faker->chrome; // Mozilla/5.0 (Windows 98; Win 9x 4.90) AppleWebKit/5321 (KHTML, like Gecko) Chrome/37.0.885.0 Mobile Safari/5321// 火狐$faker->firefox; // Mozilla/5.0 (Windows NT 5.1; en-US; rv:1.9.2.20) Gecko/20110217 Firefox/36.0// Safari$faker->safari; // Mozilla/5.0 (iPad; CPU OS 7_0_1 like Mac OS X; en-US) AppleWebKit/531.7.5 (KHTML, like Gecko) Version/3.0.5 Mobile/8B111 Safari/6531.7.5// 欧朋$faker->opera; // Opera/8.83 (Windows NT 5.01; en-US) Presto/2.12.189 Version/12.00// ie$faker->internetExplorer; // Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/3.1)Payment// 随机生成信用卡类型$faker->creditCardType; // MasterCard// 随机生成信用卡号$faker->creditCardNumber; // 343611837373950// 随机生成信用卡无效日期$faker->creditCardExpirationDate; // DateTime Object( [date] => 2022-11-09 16:46:16.000000 [timezone_type] => 3 [timezone] => Asia/Shanghai)// 随机生成信用卡无效日期$faker->creditCardExpirationDateString; // 11/20// 随机生成信用卡明细$faker->creditCardDetails; // Array( [type] => Visa [number] => 4556837981031508 [name] => 鄢子安 [expirationDate] => 06/21)// 随机生成国内银行账号$faker->iban($countryCode = null); // GR8189640507T689358O3SK6K5B// todo 瑞士银行账号$faker->swiftBicNumber; // DWDFOKO4S3YColor// 随机生成16进制色彩$faker->hexColor; // #7675e0// 随机生成rgb格局的色彩$faker->rgbColor; // 222,237,164// 随机生成数组格局的rgb色彩$faker->rgbColorAsArray; // Array( [0] => 118 [1] => 160 [2] => 37)// 随机生成css格局的rgb色彩$faker->rgbCssColor; // rgb(133,60,133)// 随机生成色彩名称$faker->safeColorName; // 彩色// 色彩名称$faker->colorName; // 暗兰紫File// 随机生成文件扩展名$faker->fileExtension; // 3dml// 随机生成mime类型$faker->mimeType; // application/vnd.pvi.ptid1Image// 随机生成图片地址$faker->phUrl($width = 640, $height = 480); // https://fakeimg.pl/640x480/282828/eae0d0?// 随机生成头像地址$faker->avatarUrl(300, 'girl'); // https://pravatar.cc/300?img=38// 返回 Svg Url 地址$faker->svgUrl(100, 100) // https://pravatar.cc/bottts/19857.svg?width=100&height=100UUID// 随机生成一个惟一字串$faker->uuid // 47b5b18c-6fee-3188-9d88-ecb7e406da4bCalculator// 随机生成13位ean码$faker->ean13; // 0120309434624// 随机生成8位ean码$faker->ean8; // 44845025// 随机生成13位isbn码$faker->isbn13; // 9798976904019// 随机生成10位isbn码$faker->isbn10; // 7300501559Miscellaneous// 随机生成bool值 false$faker->boolean; // 1// 均衡的生成bool值$faker->boolean($chanceOfGettingTrue = 50); // // Md5$faker->md5; // 02ab746139e35599e12a2a0fc21ece2c// Sha1$faker->sha1; // 81308895610bbe530dec6269e4cce55044dda0dd// Sha256$faker->sha256; // 3cc0882a1c3d7f68298a93c32ce2f094118ad72dbe00ef35e96f4613aaecef2f// Locale$faker->locale; // ja_JP// 随机生成国家编码$faker->countryCode; // IS// 随机生成语言编码$faker->languageCode; // mn// 随机生成货币代码$faker->currencyCode; // KZT// Emoji$faker->emoji; // ????Biased// 在10到20之间失去一个随机数,有更多的几率靠近20$faker->biasedNumberBetween($min = 10, $max = 20, $function = 'sqrt'); // 17Html// 随机生成一个不超过 $maxDepth层的html, 任何级别上都不超过$maxWidth个元素$faker->randomHtml($maxDepth = 2, $maxWidth = 3); // <html><head><title>&#35328;&#33410;&#26174;&#30331;.</title></head><body><form action="example.com" method="POST"><label for="username">&#21017;</label><input type="text" id="username"><label for="password">&#38750;</label><input type="password" id="password"></form><i>&#27700;&#32447;&#21517;&#35785;&#21568;&#23396;&#36215;.</i></body></html>LicenseFaker is released under the MIT License. See the bundled LICENSE file for details. ...

November 6, 2020 · 5 min · jiezi

关于php:Yii使用队列时出现的问题解决

最近在实现微信音讯推送的时候呈现了一些问题,在咱们批量推送微信告诉的时候,我应用了队列的模式来实现微信音讯推送,然而在应用队列的时候呈现了队列过程齐全没有问题,然而队列工作就是不执行的景象,在通过了一个小时左右的钻研后终于发现了问题 问题: 应用队列: Yii::$app->queue->push(new ExaminerNoticeJob([    'test' => $test,]));在执行队列时,在队列记录的queue表中发现,队列过程的确记录下来了,在执行队列后队列过程的确执行了,然而我的队列中的动作就是不执行,起初发现这是因为在调用队列时的传参过于大,导致尽管队列执行了,然而因为传参信息过大导致信息不残缺,故无奈执行我的队列工作 解决: 将传递队列工作的参数尽可能的缩小即能够发现队列工作执行失常了。。。

November 5, 2020 · 1 min · jiezi

关于php:PHPFPM源码分析

PHP-FPM源码剖析一个申请从浏览器达到PHP脚本执行两头有个必要模块是网络解决模块,FPM是这个模块的一部分,配合fastcgi协定实现对申请的从监听到转发到PHP解决,并将后果返回这条流程。FPM采纳多过程模型,就是创立一个master过程,在master过程中创立并监听socket,而后fork多个子过程,而后子过程各自accept申请,子过程在启动后阻塞在accept上,有申请达到后开始读取申请 数据,读取实现后开始解决而后再返回,在这期间是不会接管其它申请的,也就是说fpm的子过程同时只能响应 一个申请,只有把这个申请解决实现后才会accept下一个申请,这是一种同步阻塞的模型。master过程负责管理子过程,监听子过程的状态,管制子过程的数量。master过程与worker过程之间通过共享变量同步信息。 从main函数开始int main(int argc, char *argv[]){ zend_signal_startup(); // 将全局变量sapi_module设置为cgi_sapi_module sapi_startup(&cgi_sapi_module); fcgi_init(); // 获取命令行参数,其中php-fpm -D、-i等参数都是在这里被解析进去的 // ... cgi_sapi_module.startup(&cgi_sapi_module); fpm_init(argc, argv, fpm_config ? fpm_config : CGIG(fpm_config), fpm_prefix, fpm_pid, test_conf, php_allow_to_run_as_root, force_daemon, force_stderr); // master过程会在这一步死循环,前面的流程都是子过程在执行。 fcgi_fd = fpm_run(&max_requests); fcgi_fd = fpm_run(&max_requests); request = fpm_init_request(fcgi_fd); // accept申请 // ....}main()函数展示了这个fpm运行残缺的框架,可见整个fpm次要分为三个局部:1、运行前的fpm_init();2、运行函数fpm_run();3、子过程accept申请解决。 FPM中的事件监听机制在具体理解fpm工作过程前,咱们要先理解fpm中的事件机制。在fpm中事件的监听默认应用kqueue来实现,对于kqueue的介绍能够看看我之前整顿的这篇文章kqueue用法简介。 // fpm中的事件构造体struct fpm_event_s { // 事件的句柄 int fd; // 下一次触发的事件 struct timeval timeout; // 频率:多久执行一次 struct timeval frequency; // 事件触发时调用的函数 void (*callback)(struct fpm_event_s *, short, void *); void *arg; // 调用callback时的参数 // FPM_EV_READ:读;FPM_EV_TIMEOUT:;FPM_EV_PERSIST:;FPM_EV_EDGE:; int flags; int index; // 在fd句柄数组中的索引 // 事件的类型 FPM_EV_READ:读;FPM_EV_TIMEOUT:计时器;FPM_EV_PERSIST:;FPM_EV_EDGE:; short which;};// 事件队列typedef struct fpm_event_queue_s { struct fpm_event_queue_s *prev; struct fpm_event_queue_s *next; struct fpm_event_s *ev;} fpm_event_queue;以fpm_run()中master过程注册的一个sp[0]的可读事件为例: ...

November 4, 2020 · 5 min · jiezi

关于php:yii2-Console-yii2开发控制台应用时的还我漂漂拳

yii2 / Console - yii2开发控制台利用时的还我漂漂拳yii2console 公布于 2018-02-24 之所以放到此专栏次要是该文章对咱们学习yii2-queue有很大帮忙。 咱们常常应用yii2开发命令行利用,也会遇到比方让用户在命令行输出信息、抉择等操作,明天为大家介绍的这个yii2的Console类轻松的帮你搞定这件事件,有了它,你的命令行利用将更加高逼格。为了学习更简略,咱们用问答的模式开始。 Console在哪里?Console是yii2的一个帮忙类,所在文件夹为 /vendor/yiisoft/yii2/helpers,外面有 BaseConsole 和 Console ,Console类继承于BaseConsole,BaseConsole不容许被调用,因而咱们都是应用Console类。 在代码里要应用套路 use yiihelpersConsole;...Console::xxxx()Hello World当咱们开发yii2的控制台利用的时候,能够echo一个字符串,这样命令行会显示,那么用Console如何实现那?看代码 public function actionIndex() { Console::output(“Hello World”);}对,用Console::output,你可能会说,“这还没有echo简略那?”,那么咱们接着看。 五彩缤纷的Hello World我当初想让Hello是黄色的,World是绿色的,怎么玩? public function actionIndex() { $hello = Console::ansiFormat("Hello",[Console::FG_YELLOW]); $world = Console::ansiFormat("World",[Console::FG_GREEN]); Console::output("{$hello} {$world}");}Console::ansiFormat能够为字符串减少更多样式。 关键在于ansiFormat的第二个参数,这是一个数组,除了能传递FG_结尾的前景色,还能传递BG_结尾的背景色,也就是说咱们岂但能扭转字体的色彩,还能加背景,比方接下来的这行代码 $hello = Console::ansiFormat("Hello",[Console::FG_YELLOW,Console::BG_BLUE]);看图谈话 那么Console一共反对多少种前景色和背景色那? 前景色 FG_BLACK / FG_RED / FG_GREEN / FG_YELLOW / FG_BLUE / FG_PURPLE / FG_CYAN / FG_GREY背景色 BG_BLACK / BG_RED / BG_GREEN / BG_YELLOW / BG_BLUE / BG_PURPLE / BG_CYAN / BG_GREY哥,内容能加粗么?必须的了,你认为就是色彩么?上面把其余款式再说下,比方加粗、斜体等等,看代码 ...

November 3, 2020 · 1 min · jiezi

关于php:协程-shellexec-如何捕获标准错误流

明天在GitHub主页看到外国友人提了一个很有意思的issue,他在应用Co\\System::exec()执行了一个不存在的命令时,错误信息会间接打印到屏幕,而不是返回错误信息。 实际上Swoole提供的System::exec()行为上与PHP的shell_exec是完全一致的,咱们写一个shell_exec的同步阻塞版本,执行后发现同样拿不到规范谬误流输入的内容,会被间接打印到屏幕。 <?php$result = shell_exec('unknown');var_dump($result);htf@htf-ThinkPad-T470p:~/workspace/debug$ php s.phpsh: 1: unknown: not foundNULLhtf@htf-ThinkPad-T470p:~/workspace/debug$那么如何解决这个问题呢?答案就是应用proc_open+hook实现。 实例代码Swoole\Runtime::setHookFlags(SWOOLE_HOOK_ALL);Swoole\Coroutine\run(function () { $descriptorspec = array( 0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"), ); $process = proc_open('unknown', $descriptorspec, $pipes); var_dump($pipes); var_dump(fread($pipes[2], 8192)); $return_value = proc_close($process); echo "command returned $return_value\n";});应用proc_open,传入了3个形容信息: fd 为 0 的流是规范输出,能够在主过程外向这个流写入数据,子过程就能够失去数据fd 为 1 的流是规范输入,这里能够失去执行命令的输入内容fd 为 2 的 pipe stream 就是 stderr ,读取 stderr 就能拿到错误信息输入应用fread就能够拿到规范谬误流输入的内容。 htf@htf-ThinkPad-T470p:~/workspace/swoole/examples/coroutine$ php proc_open.phparray(3) { [0]=> resource(4) of type (stream) [1]=> resource(5) of type (stream) [2]=> resource(6) of type (stream)}string(26) "sh: 1: unknown: not found"command returned 32512htf@htf-ThinkPad-T470p:~/workspace/swoole/examples/coroutine$Swoole 正在参加 2020 年度 OSC 中国开源我的项目评比,请点击下方链接投出您的一票,投票中转链接:https://www.oschina.net/p/swoole-server ...

November 3, 2020 · 1 min · jiezi

关于php:44-数据结构PHP实现-二分搜索树的结点删除

1. 删除逻辑删除的结点不存在左儿子: 删除的结点不存在右儿子: 删除的结点存在左儿子和右儿子:删除的结点的右边所有值都会比该结点小,所以只有在其中拿出最大的一个值替换成该节点即可 2. 代码<?php/** * content: 二叉树的二分搜寻树的实现 * auth: yujiaming * create: 2020-10-25 */namespace TreeBundle;use ArrayBundle\BaseArray;use QueueBundle\BaseQueue;use StackBundle\BaseStack;class BaseBinaryTree{ /** * 删除某个结点 * @param $value */ public function deleteNode($value) { $node = $this->rootNode; $parentNode = null; while (!is_null($node)) { if (bccomp($node->getValue(), $value) > 0) { $parentNode = $node; $node = $node->getLeftChild(); } elseif (bccomp($node->getValue(), $value) < 0) { $parentNode = $node; $node = $node->getRightChild(); } else { // 如果不存在右儿子,则左儿子间接挂到父节点上面即可 if (is_null($node->getRightChild())) { // 将新节点接到父节点下,这里要判断是父节点的左儿子还是右儿子 if (!is_null($parentNode->getLeftChild()) && bccomp($parentNode->getLeftChild()->getValue(), $node->getValue()) == 0) { $parentNode->setLeftChild($node->getLeftChild()); } elseif (!is_null($parentNode->getRightChild()) && bccomp($parentNode->getRightChild()->getValue(), $node->getValue()) == 0) { $parentNode->setRightChild($node->getLeftChild()); } return; } // 如果不存在左儿子,则右儿子间接挂到父节点上面即可 if (is_null($node->getLeftChild())) { // 将新节点接到父节点下,这里要判断是父节点的左儿子还是右儿子 if (!is_null($parentNode->getLeftChild()) && bccomp($parentNode->getLeftChild()->getValue(), $node->getValue()) == 0) { $parentNode->setLeftChild($node->getRightChild()); } elseif (!is_null($parentNode->getRightChild()) && bccomp($parentNode->getRightChild()->getValue(), $node->getValue()) == 0) { $parentNode->setRightChild($node->getRightChild()); } return; } // 如果左儿子和右儿子都存在,则获取右儿子里最小的结点来代替该结点 // 定义以后结点左儿子的最大结点的父节点 $leftMaxNodeParent = $node; // 定义以后结点左儿子的最大结点 $leftMaxNode = $leftMaxNodeParent->getLeftChild(); // 遍历 while (!is_null($leftMaxNode) && !is_null($leftMaxNode->getRightChild())) { $leftMaxNodeParent = $leftMaxNode; $leftMaxNode = $leftMaxNode->getRightChild(); } // 将以后结点左儿子的最大结点的父节点的右儿子设置为null $leftMaxNodeParent->setRightChild(null); // 将以后结点左儿子的最大结点的左儿子和右儿子设置为该结点的左儿子和右儿子 $leftMaxNode->setLeftChild($node->getLeftChild()); $leftMaxNode->setRightChild($node->getRightChild()); // 将新节点接到父节点下,这里要判断是父节点的左儿子还是右儿子 if (!is_null($parentNode->getLeftChild()) && bccomp($parentNode->getLeftChild()->getValue(), $node->getValue()) == 0) { $parentNode->setLeftChild($leftMaxNode); } elseif (!is_null($parentNode->getRightChild()) && bccomp($parentNode->getRightChild()->getValue(), $node->getValue()) == 0) { $parentNode->setRightChild($leftMaxNode); } return; } } } // ...其余代码}

November 2, 2020 · 1 min · jiezi

关于php:Swoole-Tcp-学习

最近始终在学习Swoole,刚好有个老我的项目的一小部分(一个脚本)有用到了Tcp 协定,借此机会重构一下。 场景形容:该脚本的作用用一句话就能够概述:将本地数据源推送给另外一台服务器。 原始的解决形式,不合理的中央有以下几点: 指标服务器须要凋谢指定端口,这会导致指标服务器向外裸露,不平安。如果有多台指标服务器,这会导致频繁须要批改源码,脚本保护起来不不便。重构重构须要解决的问题有如下: 当客户端连贯胜利后,才会向该客户端推送数据。当客户端断开连接时,进行向该客户端推送数据。容许多个客户端同时连贯。因为数据源是不间断的,实践上只有客户端的连贯不被动断开,服务端的数据推送就不会被动进行。最终应用Swoole 的Tcp + Process 实现了以上需要,外围代码如下: <?phpuse Swoole\Process;/** * 创立Server 对象,监听本地 9501 端口。 */$server = new Swoole\Server("0.0.0.0", 9501);$workers = [];/** * 监听连贯进入事件 */$server->on("Connect", function ($server, $fd) { global $workers; // 创立子过程 $process = new swoole_process(function (swoole_process $worker) use ($server, $fd) { echo "Client Connect" . PHP_EOL; // todo 业务逻辑 ... // 向客户端推送音讯 $server->send($fd, $str); }, true, 0, false); // 启动子过程 $pid = $process->start(); array_push($workers, ["pid" => $pid, "fd" => $fd]);});/** * 监听数据接管事件 */$server->on("Receive", function ($server, $fd, $from_id, $data){ $server->send($fd, "Server: " . $data);});/** * 监听连贯敞开事件 */$server->on("Close", function ($server, $fd) { global $workers; foreach ($workers as $worker) { if ($worker['fd'] === $fd){ // 查看子过程是否存在 if (Process::kill($worker['pid'], 0)){ array_shift($worker); // 通过信号终止子过程 Process::kill($worker['pid'], SIGKILL); } } } echo "Client Close" . PHP_EOL;});// 启动TCP 服务器$server->start();其实实现的原理很简略,利用Swoole 的基于事件的 Tcp 异步编程,当有客户端连贯时,就创立一个子过程进行推送数据,但客户端连贯断开时,就通过信号完结该客户端对应的子过程。 ...

November 2, 2020 · 1 min · jiezi

关于php:高颜值低成本这个基于Laravel的资产管理系统很值得一看

随着企业内信息化设施数量越来越多,设施的治理和运维对于宽广中小企业来说是一个不小的难题。目前仍旧有很多公司应用 Excel 来进行公司设施的治理,这样可能会造成信息失落、人工录入不及时、信息谬误等等问题,导致管理混乱。 对于企业的此类问题,一个开源的设施资产管理系统就是十分好的解决方案。 项目名称: Chemex 我的项目作者: 绯末 开源许可协定: GPL-3.0 我的项目地址:https://gitee.com/celaraze/Chemex 我的项目简介Chemex 是一个轻量的、古代设计格调的 ICT 设施资产管理系统。得益于 Laravel 框架以及 Dcat Admin 开发平台,使其具备了优雅、简洁的优良体验。 Chemex 是完全免费且开源的,任何人都能够无限度的批改代码以及部署服务,这对于很多想要对 ICT 资产做信息化治理的中小型企业来说,是一个很好的抉择:低廉的老本换回的是高效的治理计划,同时又有衰弱的生态提供反对。 我的项目个性模块化设计所有性能均以模块化形式设计开发,正当应用RESTful格调对权限RBAC化治理。 私有化部署自在部署,解决企业受权痛点,麻利开发模式,缺点修复更迅速。 社区生态强有力的IT运维圈生态,听取一线运维人员倡议进行改善。 我的项目模块设施台账治理 其中蕴含了设施的名称、所有软硬件、制造商、购入日期、爱护日期、IP地址、MAC、使用者等保护内容,同时领有设施相干历史记录。反对在线 SSH 近程拜访治理设施。设施归属到使用者。设施故障报告。硬件台账治理 其中蕴含了硬件的名称、规格、序列号、归属设施治理等保护内容,同时领有硬件相干历史记录。设施故障报告。软件台账治理 其中蕴含了软件的名称、版本、散发形式、受权形式、购入金额、序列号、受权数量治理等保护内容,也有软件相干历史记录。雇员治理 雇员清单。部门清单。服务程序治理 其中蕴含了服务程序所在的宿主服务器、服务状态、异样报告等。服务程序异样的修复。首页特地的看板。盘点治理 设施、硬件、软件盘点工作的创立、实现和勾销。盘盈盘亏。指定盘点负责人员。Chemex Tool 挪动端盘点工具。数据图表 各模块的根底数据。各服务状态实时展现,包含异样内容,产生工夫和复原工夫。盘点进度展现。多国语言 目前临时最优反对中文简体,后续会公布英文语言,同时会反对语言切换。私有化部署 是的,只须要一个 LNMP 环境,就能够无限度的私有化部署。OTA降级 曾经反对了在线降级,不必本地手工进行版本保护。我的项目截图 如果你想要理解该项目标更多信息,那么就点击前面的链接返回我的项目主页看看吧:https://gitee.com/celaraze/Chemex

November 2, 2020 · 1 min · jiezi

关于php:Hyperf-发布协程安全的-View-组件及-v2017-版本企业级的-PHP-微服务云原生协程框架

更新内容本周次要新增了 view-engine 组件,view-engine 组件衍生于 Laravel 的 Blade 模板引擎,能够间接在 Worker 过程中渲染视图,无需启动额定的 Task 过程。同时咱们修复了一些组件的 ????Bug,持续晋升 Hyperf 的稳定性,公布于 2.0.17 版。 倡议用户应用以下命令更新此版本。 composer update "hyperf/*" -o间接拜访 官网 hyperf.io 或 文档 hyperf.wiki 查看更新内容 新增#2625 新增 Hyperf\\Tracer\\Aspect\\JsonRpcAspect, 能够让 Tracer 组件反对 JsonRPC 的链路追踪。#2709 #2733 为 Model 新增了对应的 @mixin 正文,晋升模型的静态方法提醒能力。#2726 #2733 为 gen:model 脚本减少可选项 --with-ide, 能够生成对应的 IDE 文件。#2737 新增 view-engine 组件,能够不须要在 Task 过程中渲染页面。修复#2719 修复 Arr::merge 会因 array1 中不蕴含 array2 中存在的 $key 时,导致的报错问题。#2723 修复 Paginator::resolveCurrentPath 无奈失常工作的问题。优化#2746 优化 @Task 注解,只会在 worker 过程中执行时,会投递到 task 过程执行对应逻辑,其余过程则会降级为同步执行。变更#2728 JsonRPC 中,以 __ 为前缀的办法,都不会在注册到 RPC 服务中,例如 __construct, __call。对于 HyperfHyperf 是基于 Swoole 4.5+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量罕用的组件,性能较传统基于 PHP-FPM 的框架有质的晋升,提供超高性能的同时,也放弃着极其灵便的可扩展性,规范组件均基于 PSR 规范 实现,基于弱小的依赖注入设计,保障了绝大部分组件或类都是 可替换 与 可复用 的。 ...

November 2, 2020 · 1 min · jiezi

关于php:数据结构PHP-字典树Trie的实现

这篇文章介绍一下字典树的实现原理,又称单词查找树、Trie树,是一种树形构造,是一种哈希树的变种。典型利用是用于统计,排序和保留大量的字符串(但不仅限于字符串),所以常常被搜索引擎零碎用于文本词频统计。它的长处是:利用字符串的公共前缀来缩小查问工夫,最大限度地缩小无谓的字符串比拟,查问效率比哈希树高。 1.字典树(Trie)示意图 2.节点定义class Node{ public $isWord; public $value;//能够存储示意其余信息 public $next; //这是一颗 Map 树,指向其余 25 个字母 public function __construct(){ $this->next = new BinarySearchTreeMap(); }}3.Trie 字典树类定义如下定义了一个字典树(Trie),其中add() 办法能够向 字典树 中增加单词,contains() 能够查问 字典树(Trie) 中是否蕴含某个单词,isPrefix() 办法能够判断字典树上是否有指定字符串前缀的单词: <?phprequire $root . "/Map/BinarySearchTreeMap.php";/** * 字典树 * Class Trie */class Trie{ private $root = null; private $size; public function __construct() { $this->root = new TrieNode(); } /** * 向字典树中增加 * @param string $word向字段树中增加元素 */ public function add(string $word, $value) { $node = $this->root; for ($i = 0; $i < strlen($word); $i++) { $c = $word[$i]; if ($node->next->get($c) == null) { $node->next->add($c, new TrieNode($value)); } $node = $node->next->get($c); } if (!$node->isWord) { $node->isWord = true; $this->size++; } } /** * 查看单词 word 是否存在 Trie 树中 * @param $word */ public function contains($word) { $node = $this->root; for ($i = 0; $i < strlen($word); $i++) { $c = $word[$i]; if ($node->next->get($c) == null) { return false; } $node = $node->next->get($c); } if ($node->isWord) { return true; } else { return false; } } /** * 获取字段树节点信息 * @param $word */ public function get($word) { $node = $this->root; for ($i = 0; $i < strlen($word); $i++) { $c = $word[$i]; if ($node->next->get($c) == null) { return null; } $node = $node->next->get($c); } return $node->value; } /** * 判断某个字符串是否为单词前缀 * @param string $prefix * @return bool */ public function isPrefix(string $prefix) { $node = $this->root; for ($i = 0; $i < strlen($prefix); $i++) { $c = $prefix[$i]; if ($node->next->get($c) == null) { return false; } $node = $node->next->get($c); } return false; } public function getSize() { return $this->size; }}class TrieNode{ public $isWord = false; public $next; public $value = null; public function __construct($value = null) { $this->value = $value; $this->next = new BinarySearchTreeMap(); }}4.输入演示<?phprequire 'Trie.php';$trie = new Trie();$trie->add('qsx',123);$trie->add('dog',456);$trie->add('cat',789);$trie->add('else',111);$trie->add('good',111);var_dump($trie->contains('qsx'));var_dump($trie->contains('dog'));var_dump($trie->contains('aaaa'));var_dump($trie->contains('ddd'));var_dump($trie->get('qsx'));var_dump($trie->get('cat'));var_dump($trie->get('dog'));var_dump($trie->get('good'));var_dump($trie->isPrefix('go'));var_dump($trie->isPrefix('goo'));var_dump($trie->isPrefix('goop')); ...

November 1, 2020 · 2 min · jiezi

关于php:数据结构PHP-线段树的实现

1.线段树介绍线段树是基于区间的统计查问,线段树是一种 二叉搜寻树,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。应用线段树能够疾速的查找某一个节点在若干条线段中呈现的次数,工夫复杂度为O(logN),线段树是一颗 均衡二叉树。 2.线段树示意图如下图所示,数组 E中,假如区间 0-9 一共 10 个元素,每个儿子节点区间元素的个数都是父亲节点元素个数的一半,若呈现 奇数 的状况,则右儿子元素区间比 左儿子 元素区间多一个: Tips:如图所示的中节点中区间指的是数组 E 的索引值。3.线段树须要空间剖析假如咱们把 线段树 看做是一颗 满二叉树,并且不思考增加元素的状况(即区间固定),对于区间有 n 个元素的数组若 n=2^k(k是正整数) 则须要 2n 的空间,最差的状况是若 n=2^k+1 则须要 4n 的空间,如下图所示,最上面一层没有元素的节点应用 null 填充: Tips: 若索引是从 i=0 开始的,左儿子 left(i) = 2*i+1,右儿子 right(i) = 2*i+2,parent(i) = (i-1)/2 取整;对于满二叉树来说,须要的节点数如下: 若当 n=2^k+1 须要的的空间数: Tips:对于区间有 n 个元素的数组若 n=2^k(k是正整数) 则须要 2n 的空间,最差的状况是若 n=2^k+1 则须要 4n 的空间就足够了。4.定义 SegmentTree 线段树类其中定义了 leftSon($i) 办法,示意求某个节点左儿子节点索引值的办法,rightSon($i) 示意求某个节点右儿子节点 索引值 的办法: <?phpclass SegmentTree{ private $data = []; //用于存储原始数组 private $tree = []; //用于存储线段树节点元素的值 /** * 构造函数 初始化线段树 * SegmentTree constructor. * @param array $arr */ public function __construct(array $arr) { for ($i = 0; $i < count($arr); $i++) { $this->data[$i] = $arr[$i]; } //若是动态语言须要开 4n 空间来示意 $this->tree } public function getSize() { return count($this->data); } public function get(int $index) { if ($index < 0 || $index >= count($this->data)) { echo "索引谬误"; exit; } return $this->data[$index]; } /** * 获取某个节点儿子节点索引,若索引是从 i=0 开始的,左儿子 left(i) = 2*i+1 * @param $i * @return int */ private function leftSon($i): int { return $i * 2 + 1; } /** * 获取某个节点右儿子节点索引,若索引是从 i=0 开始的,右儿子 left(i) = 2*i+2 * @param $i * @return int */ private function rightSon($i): int { return $i * 2 + 2; }}5.创立线段树接下来应用递归思维去 创立线段树,上面给出递归函数 PHP 代码: ...

October 31, 2020 · 5 min · jiezi

关于php:LeetCode-PHP题解-3-无重复字符的最长子串

题目链接3. longest-substring-without-repeating-characters 难度:medium 知识点1.滑动窗口法经典算法,此处不开展 解法1.暴力循环此处不赘述 2.滑动窗口用一个数组做滑动窗口,每次right向右挪动时候,判断该字符串是否在窗口内存在,若不存在则持续右移,记录以后窗口长度;若存在则将左边界置为窗口中该字符的左边。 class Solution { /** * @param String $s * @return Integer */ function lengthOfLongestSubstring($s) { $len = strlen($s); $left = $right = 0; $ans = 0; $queue = []; while($right < $len){ //判断是否在 $index = array_search($s[$right], $queue); $queue[] = $s[$right]; if(false !== $index ){ $queue = array_slice($queue, $index + 1); } $ans = max($ans, count($queue)); $right++; } return $ans; }}3.滑动窗口2相比于解法2,这里其实没有应用数组,而是哈希记录了左右边界,每次right向右挪动时候,判断该字符串哈希表里对应的值(str索引)是否在left的左边,若在左边,则left=该索引+1,若不存在则持续右移,记录以后窗口长度;若存在则将左边界置为窗口中该字符的左边。 ...

October 30, 2020 · 1 min · jiezi

关于php:中文注释版-Laravel-容器类Container

中文正文版 Laravel 容器类(Container)将 Laravel 的 illuminate/container 移除掉 illuminate/contracts 依赖,便于灵便的在非 Laravel 框架中应用,顺便机翻了一下 illuminate/container 的正文,便于了解 Laravel 的容器。相干链接https://github.com/guanguans/dihttps://github.com/illuminate/container代码<?php/* * This file is part of the guanguans/di. * * (c) guanguans <ityaozm@gmail.com> * * This source file is subject to the MIT license that is bundled. */namespace Guanguans\Di;use ArrayAccess;use Closure;use LogicException;use Psr\Container\ContainerInterface;use ReflectionClass;use ReflectionParameter;/** * This file is modified from `illuminate/container`. * * @see https://github.com/illuminate/container */class Container implements ArrayAccess, ContainerInterface{ /** * The current globally available container (if any). * 以后的全局可用容器(如果有)。 * * @var static */ protected static $instance; /** * An array of the types that have been resolved. * 已解析类型的数组。 * * @var array */ protected $resolved = []; /** * The container's bindings. * 容器的绑定。 * * @var array */ protected $bindings = []; /** * The container's method bindings. * 容器的办法绑定。 * * @var array */ protected $methodBindings = []; /** * The container's shared instances. * 容器的共享实例。 * * @var array */ protected $instances = []; /** * The registered type aliases. * 注册的类型别名。 * * @var array */ protected $aliases = []; /** * The registered aliases keyed by the abstract name. * 以形象名称为关键字的注册别名。 * * @var array */ protected $abstractAliases = []; /** * The extension closures for services. * 服务的扩展名闭包。 * * @var array */ protected $extenders = []; /** * All of the registered tags. * 所有注册的标签。 * * @var array */ protected $tags = []; /** * The stack of concretions currently being built. * 目前正在构建的堆栈。 * * @var array */ protected $buildStack = []; /** * The parameter override stack. * 参数笼罩堆栈。 * * @var array */ protected $with = []; /** * The contextual binding map. * 上下文绑定图。 * * @var array */ public $contextual = []; /** * All of the registered rebound callbacks. * 所有已注册的反弹回调。 * * @var array */ protected $reboundCallbacks = []; /** * All of the global resolving callbacks. * 所有全局解析回调。 * * @var array */ protected $globalResolvingCallbacks = []; /** * All of the global after resolving callbacks. * 解决回调后的所有全局变量。 * * @var array */ protected $globalAfterResolvingCallbacks = []; /** * All of the resolving callbacks by class type. * 按类类型的所有解析回调。 * * @var array */ protected $resolvingCallbacks = []; /** * All of the after resolving callbacks by class type. * 所有按类类型解析后的回调。 * * @var array */ protected $afterResolvingCallbacks = []; /** * Define a contextual binding. * 定义上下文绑定。 * * @param string $concrete * @return \Guanguans\Di\ContextualBindingBuilder */ public function when($concrete) { return new ContextualBindingBuilder($this, $this->getAlias($concrete)); } /** * Determine if the given abstract type has been bound. * 确定给定的形象类型是否已绑定。 * * @param string $abstract * @return bool */ public function bound($abstract) { return isset($this->bindings[$abstract]) || isset($this->instances[$abstract]) || $this->isAlias($abstract); } /** * Determine if the given abstract type has been resolved. * 确定给定的形象类型是否已解析。 * * @param string $abstract * @return bool */ public function resolved($abstract) { if ($this->isAlias($abstract)) { $abstract = $this->getAlias($abstract); } return isset($this->resolved[$abstract]) || isset($this->instances[$abstract]); } /** * Determine if a given type is shared. * 确定给定类型是否共享。 * * @param string $abstract * @return bool */ public function isShared($abstract) { return isset($this->instances[$abstract]) || (isset($this->bindings[$abstract]['shared']) && $this->bindings[$abstract]['shared'] === true); } /** * Determine if a given string is an alias. * 确定给定的字符串是否为别名 * * @param string $name * @return bool */ public function isAlias($name) { return isset($this->aliases[$name]); } /** * Register a binding with the container. * 在容器中注册绑定 * * @param string|array $abstract * @param \Closure|string|null $concrete * @param bool $shared * @return void */ public function bind($abstract, $concrete = null, $shared = false) { // If no concrete type was given, we will simply set the concrete type to the // abstract type. After that, the concrete type to be registered as shared // without being forced to state their classes in both of the parameters. // 如果没有给出具体类型,咱们将简略地将具体类型设置为形象类型。 // 之后,要注册为共享的具体类型,而不用强制在两个参数中申明其类。 $this->dropStaleInstances($abstract); if (is_null($concrete)) { $concrete = $abstract; } // If the factory is not a Closure, it means it is just a class name which is // bound into this container to the abstract type and we will just wrap it // up inside its own Closure to give us more convenience when extending. // 如果工厂不是 Closure,则意味着它只是一个类名称, // 该类名称绑定到此容器中,与形象类型绑定, // 咱们将其包装在本人的 Closure 中,以便在扩大时为咱们提供更多便当。 if (! $concrete instanceof Closure) { $concrete = $this->getClosure($abstract, $concrete); } $this->bindings[$abstract] = compact('concrete', 'shared'); // If the abstract type was already resolved in this container we'll fire the // rebound listener so that any objects which have already gotten resolved // can have their copy of the object updated via the listener callbacks. // 如果形象类型已在此容器中解析,咱们将触发回弹侦听器, // 以便所有已解析的对象都能够通过侦听器回调更新其对象正本。 if ($this->resolved($abstract)) { $this->rebound($abstract); } } /** * Get the Closure to be used when building a type. * 获取要在构建类型时应用的闭包。 * * @param string $abstract * @param string $concrete * @return \Closure */ protected function getClosure($abstract, $concrete) { return function ($container, $parameters = []) use ($abstract, $concrete) { if ($abstract == $concrete) { return $container->build($concrete); } return $container->makeWith($concrete, $parameters); }; } /** * Determine if the container has a method binding. * 确定容器是否具备办法绑定。 * * @param string $method * @return bool */ public function hasMethodBinding($method) { return isset($this->methodBindings[$method]); } /** * Bind a callback to resolve with Container::call. * 绑定回调以应用 Container::call 进行解析。 * * @param string $method * @param \Closure $callback * @return void */ public function bindMethod($method, $callback) { $this->methodBindings[$method] = $callback; } /** * Get the method binding for the given method. * 获取给定办法的办法绑定。 * * @param string $method * @param mixed $instance * @return mixed */ public function callMethodBinding($method, $instance) { return call_user_func($this->methodBindings[$method], $instance, $this); } /** * Add a contextual binding to the container. * 将上下文绑定增加到容器。 * * @param string $concrete * @param string $abstract * @param \Closure|string $implementation * @return void */ public function addContextualBinding($concrete, $abstract, $implementation) { $this->contextual[$concrete][$this->getAlias($abstract)] = $implementation; } /** * Register a binding if it hasn't already been registered. * 注册绑定(如果尚未注册)。 * * @param string $abstract * @param \Closure|string|null $concrete * @param bool $shared * @return void */ public function bindIf($abstract, $concrete = null, $shared = false) { if (! $this->bound($abstract)) { $this->bind($abstract, $concrete, $shared); } } /** * Register a shared binding in the container. * 在容器中注册共享绑定。 * * @param string|array $abstract * @param \Closure|string|null $concrete * @return void */ public function singleton($abstract, $concrete = null) { $this->bind($abstract, $concrete, true); } /** * "Extend" an abstract type in the container. * “扩大”容器中的形象类型。 * * @param string $abstract * @param \Closure $closure * @return void * * @throws \InvalidArgumentException */ public function extend($abstract, Closure $closure) { $abstract = $this->getAlias($abstract); if (isset($this->instances[$abstract])) { $this->instances[$abstract] = $closure($this->instances[$abstract], $this); $this->rebound($abstract); } else { $this->extenders[$abstract][] = $closure; if ($this->resolved($abstract)) { $this->rebound($abstract); } } } /** * Register an existing instance as shared in the container. * 将现有实例注册为在容器中共享的实例。 * * @param string $abstract * @param mixed $instance * @return void */ public function instance($abstract, $instance) { $this->removeAbstractAlias($abstract); $isBound = $this->bound($abstract); unset($this->aliases[$abstract]); // We'll check to determine if this type has been bound before, and if it has // we will fire the rebound callbacks registered with the container and it // can be updated with consuming classes that have gotten resolved here. // 咱们将查看以确定此类型是否以前已绑定, // 如果曾经绑定,将触发在容器中注册的反弹回调, // 并且能够应用在这里已解决的耗费类进行更新。 $this->instances[$abstract] = $instance; if ($isBound) { $this->rebound($abstract); } } /** * Remove an alias from the contextual binding alias cache. * 从上下文绑定别名缓存中删除别名。 * * @param string $searched * @return void */ protected function removeAbstractAlias($searched) { if (! isset($this->aliases[$searched])) { return; } foreach ($this->abstractAliases as $abstract => $aliases) { foreach ($aliases as $index => $alias) { if ($alias == $searched) { unset($this->abstractAliases[$abstract][$index]); } } } } /** * Assign a set of tags to a given binding. * 将一组标签调配给给定的绑定。 * * @param array|string $abstracts * @param array|mixed ...$tags * @return void */ public function tag($abstracts, $tags) { $tags = is_array($tags) ? $tags : array_slice(func_get_args(), 1); foreach ($tags as $tag) { if (! isset($this->tags[$tag])) { $this->tags[$tag] = []; } foreach ((array) $abstracts as $abstract) { $this->tags[$tag][] = $abstract; } } } /** * Resolve all of the bindings for a given tag. * 解决给定标签的所有绑定。 * * @param string $tag * @return array */ public function tagged($tag) { $results = []; if (isset($this->tags[$tag])) { foreach ($this->tags[$tag] as $abstract) { $results[] = $this->make($abstract); } } return $results; } /** * Alias a type to a different name. * 将别名别名为另一个名称。 * * @param string $abstract * @param string $alias * @return void */ public function alias($abstract, $alias) { $this->aliases[$alias] = $abstract; $this->abstractAliases[$abstract][] = $alias; } /** * Bind a new callback to an abstract's rebind event. * 绑定一个新的回调到形象的从新绑定事件。 * * @param string $abstract * @param \Closure $callback * @return mixed */ public function rebinding($abstract, Closure $callback) { $this->reboundCallbacks[$abstract = $this->getAlias($abstract)][] = $callback; if ($this->bound($abstract)) { return $this->make($abstract); } } /** * Refresh an instance on the given target and method. * 在给定的指标和办法上刷新实例。 * * @param string $abstract * @param mixed $target * @param string $method * @return mixed */ public function refresh($abstract, $target, $method) { return $this->rebinding($abstract, function ($app, $instance) use ($target, $method) { $target->{$method}($instance); }); } /** * Fire the "rebound" callbacks for the given abstract type. * 为给定的形象类型触发“反弹”回调。 * * @param string $abstract * @return void */ protected function rebound($abstract) { $instance = $this->make($abstract); foreach ($this->getReboundCallbacks($abstract) as $callback) { call_user_func($callback, $this, $instance); } } /** * Get the rebound callbacks for a given type. * 获取给定类型的反弹回调 * * @param string $abstract * @return array */ protected function getReboundCallbacks($abstract) { if (isset($this->reboundCallbacks[$abstract])) { return $this->reboundCallbacks[$abstract]; } return []; } /** * Wrap the given closure such that its dependencies will be injected when executed. * 包装给定的闭包,以便在执行时注入其依赖项。 * * @param \Closure $callback * @param array $parameters * @return \Closure */ public function wrap(Closure $callback, array $parameters = []) { return function () use ($callback, $parameters) { return $this->call($callback, $parameters); }; } /** * Call the given Closure / class@method and inject its dependencies. * 调用给定的 Closure / class@method 并注入其依赖项。 * * @param callable|string $callback * @param array $parameters * @param string|null $defaultMethod * @return mixed */ public function call($callback, array $parameters = [], $defaultMethod = null) { return BoundMethod::call($this, $callback, $parameters, $defaultMethod); } /** * Get a closure to resolve the given type from the container. * 获取一个容器来解析给定类型的闭包。 * * @param string $abstract * @return \Closure */ public function factory($abstract) { return function () use ($abstract) { return $this->make($abstract); }; } /** * Resolve the given type with the given parameter overrides. * 应用给定的参数笼罩解析给定的类型。 * * @param string $abstract * @param array $parameters * @return mixed */ public function makeWith($abstract, array $parameters) { return $this->resolve($abstract, $parameters); } /** * Resolve the given type from the container. * 从容器解析给定类型。 * * @param string $abstract * @return mixed */ public function make($abstract) { return $this->resolve($abstract); } /** * Resolve the given type from the container. * 从容器解析给定类型。 * * @param string $abstract * @param array $parameters * @return mixed */ protected function resolve($abstract, $parameters = []) { $abstract = $this->getAlias($abstract); $needsContextualBuild = ! empty($parameters) || ! is_null( $this->getContextualConcrete($abstract) ); // If an instance of the type is currently being managed as a singleton we'll // just return an existing instance instead of instantiating new instances // so the developer can keep using the same objects instance every time. // 如果以后正在以单例形式治理该类型的实例, // 咱们将只返回一个现有实例,而不是实例化新实例, // 以便开发人员每次都能够持续应用雷同的对象实例。 if (isset($this->instances[$abstract]) && ! $needsContextualBuild) { return $this->instances[$abstract]; } $this->with[] = $parameters; $concrete = $this->getConcrete($abstract); // We're ready to instantiate an instance of the concrete type registered for // the binding. This will instantiate the types, as well as resolve any of // its "nested" dependencies recursively until all have gotten resolved. // 咱们曾经筹备好实例化为绑定注册的具体类型的实例。 // 这将实例化类型,并以递归形式解析其“嵌套”依赖项中的任何一个,直到全副解析结束。 if ($this->isBuildable($concrete, $abstract)) { $object = $this->build($concrete); } else { $object = $this->make($concrete); } // If we defined any extenders for this type, we'll need to spin through them // and apply them to the object being built. This allows for the extension // of services, such as changing configuration or decorating the object. // 如果咱们为此类型定义了任何扩大程序,则须要遍历它们并将其利用于正在构建的对象。 // 这容许扩大服务,例如更改配置或装璜对象。 foreach ($this->getExtenders($abstract) as $extender) { $object = $extender($object, $this); } // If the requested type is registered as a singleton we'll want to cache off // the instances in "memory" so we can return it later without creating an // entirely new instance of an object on each subsequent request for it. // 如果将申请的类型注册为单例,咱们将将实例缓存在“内存”中, // 这样咱们当前就能够返回它,而无需在随后的每次申请上都创建对象的全新实例。 if ($this->isShared($abstract) && ! $needsContextualBuild) { $this->instances[$abstract] = $object; } $this->fireResolvingCallbacks($abstract, $object); // Before returning, we will also set the resolved flag to "true" and pop off // the parameter overrides for this build. After those two things are done // we will be ready to return back the fully constructed class instance. // 在返回之前,咱们还将解析标记设置为 “true”,并弹出此版本的参数代替。 // 实现这两件事之后,咱们将筹备好返回残缺结构的类实例。 $this->resolved[$abstract] = true; array_pop($this->with); return $object; } /** * Get the concrete type for a given abstract. * 获取给定摘要的具体类型。 * * @param string $abstract * @return mixed $concrete */ protected function getConcrete($abstract) { if (! is_null($concrete = $this->getContextualConcrete($abstract))) { return $concrete; } // If we don't have a registered resolver or concrete for the type, we'll just // assume each type is a concrete name and will attempt to resolve it as is // since the container should be able to resolve concretes automatically. // 如果咱们没有该类型的注册解析器或具体对象,咱们将假如每种类型都是具体名称, // 并尝试按原样解析它,因为容器应该可能主动解析具体对象。 if (isset($this->bindings[$abstract])) { return $this->bindings[$abstract]['concrete']; } return $abstract; } /** * Get the contextual concrete binding for the given abstract. * 获取给定摘要的上下文具体绑定。 * * @param string $abstract * @return string|null */ protected function getContextualConcrete($abstract) { if (! is_null($binding = $this->findInContextualBindings($abstract))) { return $binding; } // Next we need to see if a contextual binding might be bound under an alias of the // given abstract type. So, we will need to check if any aliases exist with this // type and then spin through them and check for contextual bindings on these. // 接下来,咱们须要查看是否能够在给定形象类型的别名下绑定上下文绑定。 // 因而,咱们将须要查看此类型是否存在别名,而后旋转它们并查看这些别名的上下文绑定。 if (empty($this->abstractAliases[$abstract])) { return; } foreach ($this->abstractAliases[$abstract] as $alias) { if (! is_null($binding = $this->findInContextualBindings($alias))) { return $binding; } } } /** * Find the concrete binding for the given abstract in the contextual binding array. * 在上下文绑定数组中找到给定摘要的具体绑定 * * @param string $abstract * @return string|null */ protected function findInContextualBindings($abstract) { if (isset($this->contextual[end($this->buildStack)][$abstract])) { return $this->contextual[end($this->buildStack)][$abstract]; } } /** * Determine if the given concrete is buildable. * 确定给定的具体是否可构建。 * * @param mixed $concrete * @param string $abstract * @return bool */ protected function isBuildable($concrete, $abstract) { return $concrete === $abstract || $concrete instanceof Closure; } /** * Instantiate a concrete instance of the given type. * 实例化给定类型的具体实例。 * * @param string $concrete * @return mixed * * @throws \Guanguans\Di\BindingResolutionException */ public function build($concrete) { // If the concrete type is actually a Closure, we will just execute it and // hand back the results of the functions, which allows functions to be // used as resolvers for more fine-tuned resolution of these objects. // 如果具体类型实际上是 Closure,咱们将间接执行它并返回函数的后果, // 这容许将函数用作解析器,以便对这些对象进行更精密的解析。 if ($concrete instanceof Closure) { return $concrete($this, $this->getLastParameterOverride()); } $reflector = new ReflectionClass($concrete); // If the type is not instantiable, the developer is attempting to resolve // an abstract type such as an Interface of Abstract Class and there is // no binding registered for the abstractions so we need to bail out. // 如果类型不是可实例化的,则开发人员正尝试解析形象类型, // 例如 Abstract Class 的接口,并且没有为形象注册任何绑定,因而咱们须要纾困。 if (! $reflector->isInstantiable()) { return $this->notInstantiable($concrete); } $this->buildStack[] = $concrete; $constructor = $reflector->getConstructor(); // If there are no constructors, that means there are no dependencies then // we can just resolve the instances of the objects right away, without // resolving any other types or dependencies out of these containers. // 如果没有构造函数,则意味着没有依赖项,咱们能够立刻解析对象的实例, // 而无需从这些容器中解析任何其余类型或依赖项。 if (is_null($constructor)) { array_pop($this->buildStack); return new $concrete; } $dependencies = $constructor->getParameters(); // Once we have all the constructor's parameters we can create each of the // dependency instances and then use the reflection instances to make a // new instance of this class, injecting the created dependencies in. // 一旦有了所有构造函数的参数,就能够创立每个依赖实例, // 而后应用反射实例创立此类的新实例,将创立的依赖注入其中。 $instances = $this->resolveDependencies( $dependencies ); array_pop($this->buildStack); return $reflector->newInstanceArgs($instances); } /** * Resolve all of the dependencies from the ReflectionParameters. * 从 ReflectionParameters 解析所有依赖项。 * * @param array $dependencies * @return array */ protected function resolveDependencies(array $dependencies) { $results = []; foreach ($dependencies as $dependency) { // If this dependency has a override for this particular build we will use // that instead as the value. Otherwise, we will continue with this run // of resolutions and let reflection attempt to determine the result. // 如果此依赖项对此特定构建具备代替,咱们将应用作为值。 // 否则,咱们将继续执行的分辨率,并让反射尝试确定后果。 if ($this->hasParameterOverride($dependency)) { $results[] = $this->getParameterOverride($dependency); continue; } // If the class is null, it means the dependency is a string or some other // primitive type which we can not resolve since it is not a class and // we will just bomb out with an error since we have no-where to go. // 如果该类为 null,则示意依赖项是字符串或其余类型的原始类型, // 因为它不是类,因而咱们无奈解析,并且因为没有地位,咱们将抛出谬误去。 $results[] = is_null($class = $dependency->getClass()) ? $this->resolvePrimitive($dependency) : $this->resolveClass($dependency); } return $results; } /** * Determine if the given dependency has a parameter override from makeWith. * 确定给定的依赖项是否具备来自 makeWith 的参数重写。 * * @param \ReflectionParameter $dependency * @return bool */ protected function hasParameterOverride($dependency) { return array_key_exists( $dependency->name, $this->getLastParameterOverride() ); } /** * Get a parameter override for a dependency. * 获取依赖项的参数笼罩。 * * @param \ReflectionParameter $dependency * @return mixed */ protected function getParameterOverride($dependency) { return $this->getLastParameterOverride()[$dependency->name]; } /** * Get the last parameter override. * 获取最初一个参数笼罩。 * * @return array */ protected function getLastParameterOverride() { return count($this->with) ? end($this->with) : []; } /** * Resolve a non-class hinted primitive dependency. * 解析非类提醒的原始依赖项。 * * @param \ReflectionParameter $parameter * @return mixed * * @throws \Guanguans\Di\BindingResolutionException */ protected function resolvePrimitive(ReflectionParameter $parameter) { if (! is_null($concrete = $this->getContextualConcrete('$'.$parameter->name))) { return $concrete instanceof Closure ? $concrete($this) : $concrete; } if ($parameter->isDefaultValueAvailable()) { return $parameter->getDefaultValue(); } $this->unresolvablePrimitive($parameter); } /** * Resolve a class based dependency from the container. * 解析容器中基于类的依赖关系。 * * @param \ReflectionParameter $parameter * @return mixed * * @throws \Guanguans\Di\BindingResolutionException */ protected function resolveClass(ReflectionParameter $parameter) { try { return $this->make($parameter->getClass()->name); } // If we can not resolve the class instance, we will check to see if the value // is optional, and if it is we will return the optional parameter value as // the value of the dependency, similarly to how we do this with scalars. // 如果无奈解析类实例,则将查看该值是否为可选,如果为可选, // 们将返回可选参数 value 作为依赖项的值,相似于执行此操作的形式标量。 catch (BindingResolutionException $e) { if ($parameter->isOptional()) { return $parameter->getDefaultValue(); } throw $e; } } /** * Throw an exception that the concrete is not instantiable. * 抛出一个具体无奈实例化的异样。 * * @param string $concrete * @return void * * @throws \Guanguans\Di\BindingResolutionException */ protected function notInstantiable($concrete) { if (! empty($this->buildStack)) { $previous = implode(', ', $this->buildStack); $message = "Target [$concrete] is not instantiable while building [$previous]."; } else { $message = "Target [$concrete] is not instantiable."; } throw new BindingResolutionException($message); } /** * Throw an exception for an unresolvable primitive. * 为无奈解析的原语抛出异样。 * * @param \ReflectionParameter $parameter * @return void * * @throws \Guanguans\Di\BindingResolutionException */ protected function unresolvablePrimitive(ReflectionParameter $parameter) { $message = "Unresolvable dependency resolving [$parameter] in class {$parameter->getDeclaringClass()->getName()}"; throw new BindingResolutionException($message); } /** * Register a new resolving callback. * 注册一个新的解析回调。 * * @param string $abstract * @param \Closure|null $callback * @return void */ public function resolving($abstract, Closure $callback = null) { if (is_string($abstract)) { $abstract = $this->getAlias($abstract); } if (is_null($callback) && $abstract instanceof Closure) { $this->globalResolvingCallbacks[] = $abstract; } else { $this->resolvingCallbacks[$abstract][] = $callback; } } /** * Register a new after resolving callback for all types. * 在解析所有类型的回调之后注册一个新的。 * * @param string $abstract * @param \Closure|null $callback * @return void */ public function afterResolving($abstract, Closure $callback = null) { if (is_string($abstract)) { $abstract = $this->getAlias($abstract); } if ($abstract instanceof Closure && is_null($callback)) { $this->globalAfterResolvingCallbacks[] = $abstract; } else { $this->afterResolvingCallbacks[$abstract][] = $callback; } } /** * Fire all of the resolving callbacks. * 触发所有解析的回调。 * * @param string $abstract * @param mixed $object * @return void */ protected function fireResolvingCallbacks($abstract, $object) { $this->fireCallbackArray($object, $this->globalResolvingCallbacks); $this->fireCallbackArray( $object, $this->getCallbacksForType($abstract, $object, $this->resolvingCallbacks) ); $this->fireAfterResolvingCallbacks($abstract, $object); } /** * Fire all of the after resolving callbacks. * 解决回调后,请执行所有操作。 * * @param string $abstract * @param mixed $object * @return void */ protected function fireAfterResolvingCallbacks($abstract, $object) { $this->fireCallbackArray($object, $this->globalAfterResolvingCallbacks); $this->fireCallbackArray( $object, $this->getCallbacksForType($abstract, $object, $this->afterResolvingCallbacks) ); } /** * Get all callbacks for a given type. * 获取给定类型的所有回调。 * * @param string $abstract * @param object $object * @param array $callbacksPerType * * @return array */ protected function getCallbacksForType($abstract, $object, array $callbacksPerType) { $results = []; foreach ($callbacksPerType as $type => $callbacks) { if ($type === $abstract || $object instanceof $type) { $results = array_merge($results, $callbacks); } } return $results; } /** * Fire an array of callbacks with an object. * 触发带有对象的回调数组。 * * @param mixed $object * @param array $callbacks * @return void */ protected function fireCallbackArray($object, array $callbacks) { foreach ($callbacks as $callback) { $callback($object, $this); } } /** * Get the container's bindings. * 获取容器的绑定。 * * @return array */ public function getBindings() { return $this->bindings; } /** * Get the alias for an abstract if available. * 获取摘要的别名(如果有)。 * * @param string $abstract * @return string * * @throws \LogicException */ public function getAlias($abstract) { if (! isset($this->aliases[$abstract])) { return $abstract; } if ($this->aliases[$abstract] === $abstract) { throw new LogicException("[{$abstract}] is aliased to itself."); } return $this->getAlias($this->aliases[$abstract]); } /** * Get the extender callbacks for a given type. * 获取给定类型的扩大程序回调。 * * @param string $abstract * @return array */ protected function getExtenders($abstract) { $abstract = $this->getAlias($abstract); if (isset($this->extenders[$abstract])) { return $this->extenders[$abstract]; } return []; } /** * Remove all of the extender callbacks for a given type. * 删除给定类型的所有扩展器回调。 * * @param string $abstract * @return void */ public function forgetExtenders($abstract) { unset($this->extenders[$this->getAlias($abstract)]); } /** * Drop all of the stale instances and aliases. * 删除所有过期的实例和别名。 * * @param string $abstract * @return void */ protected function dropStaleInstances($abstract) { unset($this->instances[$abstract], $this->aliases[$abstract]); } /** * Remove a resolved instance from the instance cache. * 从实例缓存中删除已解析的实例。 * * @param string $abstract * @return void */ public function forgetInstance($abstract) { unset($this->instances[$abstract]); } /** * Clear all of the instances from the container. * 从容器中革除所有实例。 * * @return void */ public function forgetInstances() { $this->instances = []; } /** * Flush the container of all bindings and resolved instances. * 刷新容器中的所有绑定和已解决的实例。 * * @return void */ public function flush() { $this->aliases = []; $this->resolved = []; $this->bindings = []; $this->instances = []; $this->abstractAliases = []; } /** * Set the globally available instance of the container. * 设置容器的全局可用实例。 * * @return static */ public static function getInstance() { if (is_null(static::$instance)) { static::$instance = new static; } return static::$instance; } /** * Set the shared instance of the container. * 设置容器的共享实例。 * * @param \Guanguans\Di\Container|null $container * @return static */ public static function setInstance(Container $container = null) { return static::$instance = $container; } /** * Determine if a given offset exists. * 确定是否存在给定的 key 。 * * @param string $key * @return bool */ public function offsetExists($key) { return $this->bound($key); } /** * Get the value at a given offset. * 获取给定 key 的值。 * * @param string $key * @return mixed */ public function offsetGet($key) { return $this->make($key); } /** * Set the value at a given offset. * 将值设置为给定的 key 。 * * @param string $key * @param mixed $value * @return void */ public function offsetSet($key, $value) { $this->bind($key, $value instanceof Closure ? $value : function () use ($value) { return $value; }); } /** * Unset the value at a given offset. * 以给定 key 勾销设置值。 * * @param string $key * @return void */ public function offsetUnset($key) { unset($this->bindings[$key], $this->instances[$key], $this->resolved[$key]); } /** * Dynamically access container services. * 动静拜访容器服务。 * * @param string $key * @return mixed */ public function __get($key) { return $this[$key]; } /** * Dynamically set container services. * 动静设置容器服务。 * * @param string $key * @param mixed $value * @return void */ public function __set($key, $value) { $this[$key] = $value; } /** * 通过其标识符查找容器的条目并返回它。 * * @inheritDoc */ public function has($id) { return $this->offsetExists($id); } /** * 如果容器能够返回给定标识符的条目,则返回 true 。 否则返回 false 。 * * @inheritDoc */ public function get($id) { return $this[$id]; }}

October 29, 2020 · 19 min · jiezi

关于php:Swoole-v456-版本发布新增零拷贝-JSON-或-PHP-反序列化

Swoole v4.5.6 版本已公布,底层减少了2个非凡的函数 swoole_substr_json_decodeswoole_substr_unserialize具体有什么用呢?查看Swoole 4.5.6 反对零拷贝 JSON 或 PHP 反序列化 本篇只是阐明一下更新日志: 新增 API新增 swoole_substr_unserialize 和 swoole_substr_json_decode (#3762) (@matyhtf)加强批改 CoroutineHttpServer 的 onAccept 办法为公有 (dfcc83b) (@matyhtf)修复修复 coverity 的问题 (#3737) (#3740) (@matyhtf)修复 Alpine 环境下的一些问题 (#3738) (@matyhtf)修复 swMutex_lockwait (0fc5665) (@matyhtf)修复 PHP-8.1 装置失败 (#3757) (@twose)内核为 Socket::read/write/shutdown 增加了活性检测 (#3735) (@matyhtf)将 session_id 和 task_id 的类型更改为 int64 (#3756) (@matyhtf)最初Swoole 正在加入 2020 年度 OSC 中国开源我的项目评比,记得给 Swoole 投票,投票中转链接:https://www.oschina.net/project/top_cn_2020#swoole-server

October 26, 2020 · 1 min · jiezi

关于php:数据结构PHP-压栈遍历二分搜索树

后面写了一篇的文章,实现的办法是用的递归思维遍历,这篇文章次要介绍一下如何应用 压栈 的思维来遍历二分搜寻树。 1.栈为了更好的联合压栈的思维,上面先来介绍一下 栈 数据结构的常识: 1.1 栈的特点栈是一种线性数据结构。栈只能从一端增加数据,也只能从同一端取出元素,每次删除的元素都是最初入栈的元素。入栈的元素具备后进先出的特点,即 Last In First Out(LIFO)。栈顶解决办法通常有 入栈(push)、出栈(pop)、查看栈顶(peek)。若是用 链表 数据结构实现的 栈,在 栈顶 会有一个 栈顶指针。栈 这种数据结构的利用举例,如:能够实现 撤销(undo)、程序的调用(零碎栈)1.2 栈的图示 1.3 链表的实现这是封装好的一个链表类,能实现链表的基本功能: <?php/** * 链表的实现 * Class LinkedList */class LinkedList{ private $dummyHead; private $size; /** * 初始化链表 null->null * LinkedList constructor. */ public function __construct() { $this->dummyHead = new Node(null, null); $this->size = 0; } /** * 获取链表大小 * @return int */ public function getSize(): int { return $this->size; } /** * 判断链表是否为空 * @return bool */ public function isEmpty(): bool { return $this->size == 0; } /** * 在链表的第 index 地位增加元素 * @param int $index * @param $e */ public function add(int $index, $e): void { if ($index < 0 || $index > $this->size) { echo "索引范畴谬误"; exit; } $prve = $this->dummyHead; for ($i = 0; $i < $index; $i++) { $prve = $prve->next; } //将上插入地位的上一个地位的 next 节点指向插入节点,插入节点的 next 节点信息指向原上节点的 next 节点 $prve->next = new Node($e, $prve->next); $this->size++; } /** * 向链表结尾增加元素 * @param $e */ public function addFirst($e): void { $this->add(0, $e); } /** * 向链表开端增加元素 * @param $e */ public function addLast($e): void { $this->add($this->size, $e); } /** * 获取链表第 index 地位元素 * @param $index */ public function get($index) { if ($index < 0 || $index > $this->size) { echo "索引范畴谬误"; exit; } $node = $this->dummyHead; for ($i = 0; $i < $index + 1; $i++) { $node = $node->next; } return $node->e; } /** * 获取链表第一个元素 * @return mixed */ public function getFirst() { return $this->get(0); } /** * 获取链表最初一个元素 * @return mixed */ public function getLast() { return $this->get($this->size - 1); } /** * 批改链表中第 index 地位元素值 * @param $index * @param $e */ public function update($index, $e) { if ($index < 0 || $index > $this->size) { echo "索引范畴谬误"; exit; } $node = $this->dummyHead; for ($i = 0; $i < $index + 1; $i++) { $node = $node->next; } $node->e = $e; } /** * 判断链表中是否存在某个元素 * @param $e * @return bool */ public function contains($e): bool { for ($node = $this->dummyHead->next; $node != null; $node = $node->next) { if ($node->e == $e) { return true; } } return true; } /** * 删除链表中第 index 地位元素 * @param $index */ public function remove($index) { if ($index < 0 || $index > $this->size) { echo "索引范畴谬误"; exit; } if ($this->size == 0) { echo "链表曾经是空"; exit; } $prve = $this->dummyHead; for ($i = 0; $i < $index; $i++) { $prve = $prve->next; } $node = $prve->next; $prve->next = $node->next; $this->size--; return $node->e; } /** * 删除链表头元素 */ public function removeFirst() { return $this->remove(0); } /** * 删除链表开端元素 */ public function removeLast() { return $this->remove($this->size - 1); } /** * 链表元素转化为字符串显示 * @return string */ public function toString(): string { $str = ""; for ($node = $this->dummyHead->next; $node != null; $node = $node->next) { $str .= $node->e . "->"; } return $str . "null"; }}class Node{ public $e;//节点元素 public $next; //下个节点信息 /** * 构造函数 设置节点信息 * Node constructor. * @param $e * @param $next */ public function __construct($e, $next) { $this->e = $e; $this->next = $next; }}1.4 调用链表实现的栈这是一个封装好的 栈(Stack) ,通过实例化 链表类(LinkedList) 实现了入栈(push)和 出栈(pop),还有查看栈顶(peek): ...

October 25, 2020 · 4 min · jiezi

关于php:php公众号链接提取文章标题封面图摘要作者公众号名称简介微信号正文

办法很简略,就是一段段截取就行,尽管很傻瓜,然而能实现就行。 <?php//设置 header header("Content-type:application/json");//初始化 CURL$ch = curl_init();//指标服务器地址 curl_setopt($ch, CURLOPT_URL, '公众号文章链接');// 对认证证书起源的查看curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);// 从证书中查看SSL加密算法是否存在curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);//获取的信息以文件流的模式返回,而不是间接输入curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//发动申请$result = curl_exec($ch);$str_1 = substr($result,strripos($result,"profile_nickname")+18);$str_2 = substr($str_1,0,strrpos($str_1,"profile_avatar")-52); //公众号名称$str_3 = substr($result,strripos($result,"微信号")+81);$str_4 = substr($str_3,0,strrpos($str_3,"性能介绍")-163); //公众号微信号$str_5 = substr($str_3,strripos($str_3,"性能介绍")+84);$str_6 = substr($str_5,0,strrpos($str_5,"profile_arrow_wrp")-172); //公众号简介$str_7 = substr($result,strripos($result,"twitter:title")+24);$str_8 = substr($str_7,0,strrpos($str_7,"twitter:creator")-23); //公众号文章题目$str_9 = substr($result,strripos($result,"twitter:image")+24);$str_10 = substr($str_9,0,strrpos($str_9,"twitter:title")-23); //公众号文章封面图$str_11 = substr($result,strripos($result,"twitter:description")+30);$str_12 = substr($str_11,0,strrpos($str_11,"var testRdmUrl")-110);$str_13 = substr($str_12,0,strrpos($str_12,">")-3); //公众号文章摘要$str_14 = substr($result,0,strrpos($result,"og:title")-27);$str_15 = substr($str_14,strripos($str_14,"author")+17); //公众号文章作者$str_16 = substr($result,strripos($result,"div class="rich_media_content")+76);$str_17 = substr($str_16,0,strrpos($str_16,"first_sceen__time")-75); //公众号文章正文$gzhmsg = array( "公众号名称" => $str_2, "微信号" => $str_4, "公众号简介" => $str_6, "文章题目" => $str_8, "文章封面图" => $str_10, "文章摘要" => $str_13, "文章作者" => $str_15, "注释" => $str_17);//敞开申请curl_close($ch);// 输入JSONecho json_encode($gzhmsg,JSON_UNESCAPED_UNICODE);?>Author:TANKINGDate:2020-10-24Web:http://www.likeyun.cn/WeChat:face6009 ...

October 24, 2020 · 1 min · jiezi

关于php:数据结构PHP-实现二分搜索树

这篇文章是介绍 二叉树 和 二分搜寻树,而后通过 PHP 代码定义一下 二分搜寻树 的节点,应用递归思维操作向二分搜寻树增加元素,而后实现了递归判断二分搜寻树上是否蕴含某个元素,最初别离实现了前序遍历、中序遍历、后序遍历 二分搜寻树。 1.二叉树1.1 二叉树图示 1.2 二叉树节点定义//二叉树具备惟一根节点class Node{ $e; //节点元素 $left; //左儿子 $right;//右儿子}Tips:二叉树每个节点最多有两个儿子,每个节点最多有一个父亲。1.3 二叉树的特点二叉树具备人造的递归结构,每个节点的左儿子或右儿子也是 二叉树。二叉树不肯定是满的,可能只有左儿子或又儿子。一个节点或 NULL 也能够看做一个二叉树。2.二分搜寻树2.1 二分搜寻树特点二分搜寻树是二叉树。每个节点的元素的值都要大于左儿子所有节点的值。每个节点的元素的值都要小于右儿子所有节点的值。每个子树也是二分搜寻树。二分搜寻树查问速度快。存储的元素必须要有比拟性。2.2 二分搜寻树图示 2.3 PHP 代码定义节点class Node{ public $e; public $left = null; public $right = null; /** * 构造函数 初始化节点数据 * Node constructor. * @param $e */ public function __construct($e) { $this->e = $e; }}2.4 向二分搜寻树增加元素上面展现的的应用递归思维向二分搜寻树增加元素,其中 add($e) 办法示意想二分搜寻树增加元素 $e,recursionAdd(Node $root, $e) 是一个递归函数,示意应用递归向二分搜寻树增加元素: /** * 向二分搜寻树增加元素 * @param $e */ public function add($e) { $this->root = $this->recursionAdd($this->root, $e); } /** * 递归向二分搜寻树增加元素 * @param Node $root * @param $e */ public function recursionAdd(Node $root, $e) { if ($root == null) { //若节点为空则增加元素 并且返回以后节点信息 $this->size++; $root = new Node($e); } elseif ($e < $root->e) { //若元素小于以后节点元素 则向左节点递归增加元素 $root->left = $this->recursionAdd($root->left, $e); } elseif ($e > $root->e) { //若元素大于以后节点元素 则向右节点递归增加元素 $root->right = $this->recursionAdd($root->right, $e); } //若元素等于以后节点元素 则什么都不做 }Tips:这里的二分搜寻树不蕴含反复元素,如果想要蕴含反复元素,能够定义每个左儿子所有元素小于等于父亲节点,或者每个节点右儿子所有节点元素大于等于父亲节点。2.5 查问二分搜寻树是否蕴含某个元素上面展现的的应用递归思维查问二分搜寻树元素是否蕴含某个元素,其中 contains($e) 办法示意查问二分搜寻树是否蕴含元素 $e,recursionContains(Node $root, $e) 是一个递归函数,示意应用递归查问二分搜寻树元素: ...

October 23, 2020 · 3 min · jiezi

关于php:电商系统设计之运费模板下

电商大伙每天都在用,相似某猫,某狗等。电商零碎设计看似简单又很简略,看似简略又很简单本章适宜初中级工程师细看,大佬请随便前言在订单零碎中,运费模板是其中一个重要组成部分,看似简略的一个设置,在其内的设计中,要思考的问题还是很多滴,上一章咱们讲了运费的一些规定以及在数据库表中如何设计,本章聊聊如何计算运费 获取通过上一篇文章咱们建设的数据表获取该商品绑定的哪一个运费模版 $templateId = Product::where('id',$product)->value('template_id');if($template == 0) return [];指定商品或者会应用多项规定,例如像这样 是否包邮指定地区运费达成某种条件下运费多少或者包邮那这么多条件,咱们要保障所有的规定全副都能够检索到,并且还要晋升其计算速度。 在计算前,该当想好有几种可能性,再抉择其优先级,就像有 三个不同色彩的球,拼凑的办法有多种一样我记得这应该是一道小学的数学题。 就近准则相比大家必定做过这道面试题 把一份打乱的字符串,进行排序那依照经典的形式 疾速排序抉择排序插入排序冒泡排序当然,咱们不讲排序,咱们是要通过这类算法去思考如何以疾速的形式去查问到咱们想要的信息。 排序算法归并与一点外围,就是通过比拟的形式进行,无论是从两头开始进行计算,还是从头或者从尾开始,都是通过对字符串自身要出现形式的一种猜想。 那咱们对于运费计算,应该从什么地位开始“排序”呢? 依据业务,首先咱们思考对于是否包邮、指定地区运费、达成指定条件这三种规定,他们的优先级大多是这样的。 达成指定条件 > 指定地区运费 > 是否包邮 一、达成指定条件就不在计算指定地区条件和是否包邮二、达成指定地区条件就不判断是否包邮 思路是不是清晰了一点呢,那么咱们上代码 实战演示为伪代码,这类计算必定不能交给前端去计算,会呈现很多平安问题,例如数据被篡改等等,偷懒的后端不是一个好后端当咱们获取templateId后,在表product_template_config中查问其关联的规定,这是一个一对多的数据列,意味着会查问出多条,首先咱们先查问指定条件。 select count(1) product_template_config where template_id = $templateId and 是否有指定条件当有指定条件则进行计算,例如 达成指定金额,运费固定达成指定金额,运费多少计算就简略了,小学就学过的嘛~ 商品数量*商品单价 > 指定金额 = 运费如果没有指定条件,则去查问指定城市运费,城市咱们应用的是json存储,会有多条,免不了for,这样你必定会说了,那很多个城市不会导致效率低嘛?做任何性能都要以理论业务登程,除了西藏、新疆及偏远地区,会有商家一个市一个市设置不同运费的嘛????,那咱们就应用2种形式 第一种:没有蛇精病的商家 $list = "select * from `product_template_config` where template_id = $templateId";$city = [];for($list){ if($list->city == "北京市"){ return price; }}第二种:有蛇精病的商家这种办法,那咱们就在sql高低点功夫,不应用json查问 select * from `product_template_config` where city like "%北京市%"最初如果以上两种规定都不满足,则就回到最简略都自定义运费和是否包邮,自定义运费的话就计算最终运费,包邮的话,间接return 0就完事喽。 ...

October 23, 2020 · 1 min · jiezi

关于php:2020年10月php面试笔记

1.请阐明目前PHP最新版本的版本号和新个性 2.简要阐明PHP的垃圾回收机制 垃圾回收机制是一种动态存储分配计划.它会主动开释程序已调配的不在须要的内存块.主动回收内存的过程叫垃圾收集.参考:浅析 PHP7 的垃圾回收机制 3.列举相熟的PHP框架,并说出该框架的特点 4.常见的状态码,阐明其含意 5.解释:脏读,幻读,不可反复读 脏读:脏读是指一个事务中拜访到了另一个事务未提交的数据.幻读:一个事务读取2次,失去的记录条数不统一,因为2次读取之间另外一个事务对数据进行了增删. 不可反复读:一个事务读取同一条记录2次,失去的后果不统一,因为2次读取之间另外一个事务对此行数据进行了批改. 补充: 数据库事务的特点:ACID 原子性(A Atomicity):事务是一个原子性的操作单元,事务外面对数据库的操作,要么都执行,要么都不执行. 一致性(C Consistent):在事务开始之前和完结之后,数据都必须保持一致状态,必须保障数据库的完整性.也就是说,数据必须合乎数据库的规定. 隔离性(I ioslation):数据库容许多个并发事务同时对数据进行操作,事务之间是互相独立的,事务处理的中间状态对其余事务是不可见的,以此防止出现数据不统一状态. MySQL中4个事务隔离级别,隔离级别由低到高:隔离级别越高,越能保证数据的完整性和一致性,但对并发性能影响也越大. 读未提交(Read uncommitted),读已提交(Read committed),可反复读(Repeatable read),可串行化(serializable) 应用 _select @@tx_isolation;_ 能够查看 MySQL 默认的事务隔离级别。 不同的事务隔离级别会导致不同的问题: 持久性(D Durable):一个事务完结后,其对数据库的批改是永久性的,即便系统故障也不会失落. 6.具体阐明rsync命令和理论利用 rsync是开源的,疾速,多功能的,可实现全量及增量的本地或近程数据同步工具,实用于linux,unix,window等多种操作系统平台.能够当做文件复制工具,代替mv和cp. 常用命令: 1. rsync -av source destination //除了能够递归同步以外,还能够同步元信息(比方批改工夫、权限等), 2. 目标目录destination如果不存在,rsync 会主动创立。执行下面的命令后, 3. 源目录source被残缺地复制到了目标目录destination上面,即造成了destination/source的目录构造。 5. 如果只想同步源目录source外面的内容到目标目录destination,则须要在源目录前面加上斜杠。 6. $ rsync -a source/ destination 7. 下面命令执行后,source目录外面的内容,就都被复制到了destination目录外面, 8. 并不会在destination上面创立一个source子目录。 11. rsync 除了反对本地两个目录之间的同步,也反对近程同步。它能够将本地内容,同步到近程服务器。 12. $ rsync -av source/ username@remote_host:destination 14. 也能够将近程内容同步到本地。 15. $ rsync -av username@remote_host:source/ destination 参考:rsync 用法教程 ...

October 23, 2020 · 2 min · jiezi

关于php:PHPFPM中D命令的实现

PHP-FPM中-D命令的实现家喻户晓,php-fpm是fastcgi的管理程序,环境部署中咱们应用php-fpm -D 来启动fpm过程,从而监听9000端口来解决nginx转发过去的request工作。对于fpm的启动之后也筹备梳理一篇,本文次要是说一下 -D 这个命令,既而通过这个命令钻研下在Linux下如何编写daemon过程。 什么是Daemon过程Daemon过程是运行在后盾的一种过程,它独立于管制终端并且周期性地执行某种工作或期待解决某些产生的事件。它不须要用户输出就能运行而且提供某种服务,不是对整个零碎就是对某个用户程序提供服务。一个守护过程的父过程是init过程,因为它真正的父过程在fork出子过程后就先于子过程exit退出了,所以它是一个由init继承的孤儿过程。守护过程是非交互式程序,没有管制终端,所以任何输入,无论是向规范输出设备stdout还是规范出错设施stderr的输入都须要非凡解决。 对于Daemon过程的一些原理 Linux中的过程与管制终端,登录会话和过程组之间的关系过程属于一个过程组,过程组号(GID)就是过程组长的过程号(PID)。登录会话能够蕴含多个过程组。这些过程组共享一个管制终端。这个管制终端通常是创立过程的登录终端。管制终端,登录会话和过程组通常是从父过程继承下来的。咱们的目标就是要解脱它们,使之不受它们的影响。 如何实现对于如何实现?个别有几个步骤须要解决: fork()一个子过程继续执行父过程的工作,同时将父过程进行。这样就使得你的过程从管制端进入后盾。脱离管制终端,登录会话和过程组。调用setsid()使子过程成为会话组长。敞开父过程关上的文件描述符。解决SIGCHLD信号。这4步中下面两步是必须的,前面是个别依据须要会须要解决的。 PHP-FPM的实现在fpm中实现daemon的办法与上述统一,最初咱们通过对fpm源码的跟踪来看一下具体实现的例子。(代码有删减) 所有从启动开始/sapi/fpm/fpm/fpm_main.cint main(int argc, char *argv[]){ // 接管到-D参数,设置以daemon模式init fpm while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) { switch (c) { case 'D': /* daemonize */ force_daemon = 1; break; } } if (0 > fpm_init(argc, argv, fpm_config ? fpm_config : CGIG(fpm_config), fpm_prefix, fpm_pid, test_conf, php_allow_to_run_as_root, force_daemon, force_stderr)) { return FPM_EXIT_CONFIG; }}int fpm_init(int argc, char **argv, char *config, char *prefix, char *pid, int test_conf, int run_as_root, int force_daemon, int force_stderr){ // fpm_conf_init_main : 设置fpm的配置,其中daemon=1 if (0 > fpm_php_init_main() || 0 > fpm_stdio_init_main() || 0 > fpm_conf_init_main(test_conf, force_daemon) || 0 > fpm_unix_init_main() || 0 > fpm_scoreboard_init_main() || 0 > fpm_pctl_init_main() || 0 > fpm_env_init_main() || 0 > fpm_signals_init_main() || 0 > fpm_children_init_main() || 0 > fpm_sockets_init_main() || 0 > fpm_worker_pool_init_main() || 0 > fpm_event_init_main()) { if (fpm_globals.test_successful) { exit(FPM_EXIT_OK); } else { zlog(ZLOG_ERROR, "FPM initialization failed"); return -1; } }}int fpm_unix_init_main(){ if (fpm_global_config.daemonize) { struct timeval tv; fd_set rfds; int ret; if (pipe(fpm_globals.send_config_pipe) == -1) { zlog(ZLOG_SYSERROR, "failed to create pipe"); return -1; } /* then fork */ pid_t pid = fork(); switch (pid) { case -1 : /* error */ zlog(ZLOG_SYSERROR, "failed to daemonize"); return -1; case 0 : /* children */ break; default : /* parent */ FD_ZERO(&rfds); FD_SET(fpm_globals.send_config_pipe[0], &rfds); tv.tv_sec = 10; tv.tv_usec = 0; zlog(ZLOG_DEBUG, "The calling process is waiting for the master process to ping via fd=%d", fpm_globals.send_config_pipe[0]); ret = select(fpm_globals.send_config_pipe[0] + 1, &rfds, NULL, NULL, &tv); if (ret == -1) { zlog(ZLOG_SYSERROR, "failed to select"); exit(FPM_EXIT_SOFTWARE); } if (ret) { /* data available */ int readval; ret = read(fpm_globals.send_config_pipe[0], &readval, sizeof(readval)); if (ret == -1) { zlog(ZLOG_SYSERROR, "failed to read from pipe"); exit(FPM_EXIT_SOFTWARE); } if (ret == 0) { zlog(ZLOG_ERROR, "no data have been read from pipe"); exit(FPM_EXIT_SOFTWARE); } else { if (readval == 1) { zlog(ZLOG_DEBUG, "I received a valid acknoledge from the master process, I can exit without error"); fpm_cleanups_run(FPM_CLEANUP_PARENT_EXIT); exit(FPM_EXIT_OK); } else { zlog(ZLOG_DEBUG, "The master process returned an error !"); exit(FPM_EXIT_SOFTWARE); } } } else { /* no date sent ! */ zlog(ZLOG_ERROR, "the master process didn't send back its status (via the pipe to the calling process)"); exit(FPM_EXIT_SOFTWARE); } exit(FPM_EXIT_SOFTWARE); } } // 使以后子过程成为会话组长 setsid();}这个里是实现daemon的外围代码,fpm在这里做了两步fork()一个子过程,setsid()将子过程设置为会话组长。重点说一下 fpm_globals.send_config_pipe 。这是一个数组做共享变量,fpm中将它当过程间通信的管道应用,父过程fork()子过程后期待10秒来接管子过程init的状况,如果子过程init失败,当失败信号写入管道,父过程获取到管道信息后将与子过程返回统一的错误信息,否则父过程返回失常退出。 ...

October 23, 2020 · 2 min · jiezi

关于php:PHP-实现递归删除链表元素

这篇文件介绍一下 递归,递归的实质是将原来的问题转化为更小的同一个问题,解决这些更小问题的过程。上面通过两个递归的例子帮忙学习对递归的了解。 1.递归数组求和例如某个数组 $arr = [1,2,3,4,5,6,7,8,9,10]; 须要求和,通过实现递归函数对数组求和来帮忙学习对递归的了解。 1.1 输入文件 output_recursion.php<?phprequire 'ArrayRecursion.php';/** * 递归实现数组求和 */$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];echo ArrayRecursion::recursionSum($arr);1.2 ArrayRecursion 类这是一个实现数组递归求和的代码,其中 recursionSum() 是一个递归函数,相当于把求和过程转化为更小的求和,最终实现想要的后果: <?php/** * 应用递归对数组求和 不便对递归的了解 * Class ArrayRecursion */class ArrayRecursion{ public static function sum(array $arr) { return self::recursionSum($arr); } public static function recursionSum(array $arr, $i = 0) { if (count($arr) == $i) { return 0; } return $arr[$i] + self::recursionSum($arr, $i + 1); }}Tips:这个求和过程仅仅只是帮忙学习递归思维,理论求和能够间接遍历数组。2.递归删除链表某个元素例如某个链表 10->9->8->99->7->99->6->5->99->4->3->2->1->null 须要删除其中值等于 99 的元素,能够通过实现递归来失去删除指定元素的成果。 ...

October 22, 2020 · 4 min · jiezi

关于php:PHP使用栈实现队列

学习下队列,通过栈来实现队列题起源力扣:https://leetcode-cn.com/probl... 思路:筹备两个栈 inStack、outStack入队时,push 到 inStack 中出队时, (1):如果 outStack是空的,将 inStack 所有的元素逐个弹出,push 到 outStack,outStack 弹出栈顶元素(2):如果 outStack 不为空,outStack 弹出栈顶元素php实现代码<?php/*** 队列* 应用栈实现队列* https://leetcode-cn.com/problems/implement-queue-using-stacks/* 1:筹备两个栈 inStack、outStack* 2: 入队时,push 到 inStack 中* 3:出队时,* (1):如果 outStack是空的,将 inStack 所有的元素逐个弹出,push 到 outStack,outStack 弹出栈顶元素* (2):如果 outStack 不为空,outStack 弹出栈顶元素*/require '../stack/Stack.php';class Queue{ protected $inStack; protected $outStack; public function __construct() { $this->inStack = new Stack(); $this->outStack = new Stack(); } /** * @param $item * push 一个元素 * 入队 */ public function push($item) { $this->inStack->push($item); } /** * 弹出一个元素 * 出队 */ public function pop() { $this->checkOutStack(); return $this->outStack->pop(); } /** * 获取队头元素 */ public function peek() { $this->checkOutStack(); return $this->outStack->top(); } /** * Returns whether the queue is empty. * @return Boolean */ public function empty() { return $this->inStack->isEmpty() && $this->outStack->isEmpty(); } private function checkOutStack(){ if ($this->outStack->isEmpty()) { // 如果出队(outStack)的栈是空的, 将入队(inStack)的栈元素全副弹出并放到 出队的栈 outStack while (!$this->inStack->isEmpty()) { $this->outStack->push($this->inStack->pop()); } } }}源代码下载:gitee ...

October 22, 2020 · 1 min · jiezi

关于php:LeetCode-763PHP-求解划分字母区间

原文链接:何晓东 博客 划分字母区间字符串 S 由小写字母组成。咱们要把这个字符串划分为尽可能多的片段,同一个字母只会呈现在其中的一个片段。返回一个示意每个字符串片段的长度的列表。 示例 1: 输出:S = "ababcbacadefegdehijhklij"输入:[9,7,8]解释:划分后果为 "ababcbaca", "defegde", "hijhklij"。每个字母最多呈现在一个片段中。像 "ababcbacadefegde", "hijhklij" 的划分是谬误的,因为划分的片段数较少。提醒: S的长度在[1, 500]之间。S只蕴含小写字母 'a' 到 'z' 。 起源:力扣(LeetCode)链接:https://leetcode-cn.com/probl...著作权归领扣网络所有。商业转载请分割官网受权,非商业转载请注明出处。 解题思路 1想切割,要有首尾两个指针,确定了结尾指针,就能确定下一个切割的开始指针。遍历字符串,如果已扫描局部的所有字符,都只呈现在已扫描的范畴内,即可做切割。下图已扫描的绿色字符,对应的最远地位,都不超过 8,在 8 这切一刀,[0:8] 的字符都不会呈现在别处。 maintain「已扫描的字符能去到的最远地位」,扫到这个地位就切割,切出的字符不会在之后呈现。更新开始指针,筹备下一次切割。 一些变量 maxPos 一个Map,记录每个字母对应的最远地位。start 做切割的开始地位。scannedCharMaxPos 已扫描的字符能去到的最远地位。作者:xiao_ben_zhu链接:https://leetcode-cn.com/probl...起源:力扣(LeetCode)著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。 class Solution { /** * @param String $S * @return Integer[] */ function partitionLabels($S) { $maxPos = []; $length = strlen($S); for ($i = 0; $i < $length; $i++) { // 寄存字母与它的最远地位 $maxPos[$S[$i]] = $i; } $res = []; $start = 0; // 待切割的起始地位 $scannedCharMaxPos = 0; // 已扫描的字符中最远的地位 for ($i = 0; $i < $length; $i++) { $curCharMaxPos = $maxPos[$S[$i]]; // 以后扫描的字符的最远地位 $scannedCharMaxPos = max($scannedCharMaxPos, $curCharMaxPos); // 更新「已扫描的字符中最远的地位」 if ($i == $scannedCharMaxPos) { // 正好扫描到「已扫描的字符的最远地位」,达到切割点 $res[] = $i - $start + 1; $start = $i + 1; // 更新,下一个待切割的字符串的起始地位 } } return $res; }}参考链接: ...

October 22, 2020 · 1 min · jiezi

关于php:二分搜索树介绍PHP-定义节点

这篇文章是介绍 二叉树 和 二分搜寻树,而后通过 PHP 代码定义一下 二分搜寻树(Binary Search Tree) 的节点。 1.二叉树1.1 二叉树图示 1.2 二叉树节点定义//二叉树具备惟一根节点class Node{ $e; //节点元素 $left; //左儿子 $right;//右儿子}Tips:二叉树每个节点最多有两个儿子,每个节点最多有一个父亲。1.3 二叉树的特点二叉树具备人造的递归结构,每个节点的左儿子或右儿子也是 二叉树。二叉树不肯定是满的,可能只有左儿子或又儿子。一个节点或 NULL 也能够看做一个二叉树。2.二分搜寻树2.1 二分搜寻树特点二分搜寻树是二叉树。每个节点的元素的值都要大于左儿子所有节点的值。每个节点的元素的值都要小于右儿子所有节点的值。每个子树也是二分搜寻树。二分搜寻树查问速度快。存储的元素必须要有比拟性。2.2 二分搜寻树图示 2.3 PHP 代码定义节点<?phpclass BinarySearchTree{ private $root; private $size; /** * 构造函数 初始化二分搜寻树 * BinarySearchTree constructor. */ public function __construct() { $this->root = null; $this->size; } /** * 获取以后搜寻树元素个数 * @return mixed */ public function getSize() { return $this->size; } /** * 判断以后二分搜寻树是否为空 * @return bool */ public function isEmpty(): bool { return $this->size == 0; }}class Node{ public $e; public $left = null; public $right = null; /** * 构造函数 初始化节点数据 * Node constructor. * @param $e */ public function __construct($e) { $this->e = $e; }}

October 22, 2020 · 1 min · jiezi

关于php:3-数据结构PHP实现-用数组来实现队列

阐明:该文章是用数组来实现队列,所以次要会对数组做逻辑操作(数组的逻辑操作在上文有提到 https://segmentfault.com/a/11...)1. 实现逻辑<?php/** * content: 数组队列的实现 * create: 2020-10-21 */namespace QueueBundle;use StackBundleBaseArrayStack;class BaseArrayQueue extends BaseArrayStack{ /** * 从后面插入数据 * @return mixed|null */ public function shift() { return $this->baseArray->del(0); } /** * 从后面弹出数据 * @param $value */ public function unshift($value): void { $this->baseArray->addFirst($value); }}2. 执行逻辑<?php<?phprequire_once __DIR__. '/../vendor/autoload.php';$queue = new QueueBundleBaseArrayQueue(new ArrayBundleBaseArray(1));// 从开端插入3个元素$queue->push('c');$queue->push('d');$queue->push('e');// 从后面插入2个元素$queue->unshift('b');$queue->unshift('a');// 打印队列echo $queue. PHP_EOL;// 从队列的开端弹出echo $queue->pop(). PHP_EOL;// 从队里的头部弹出echo $queue->shift(). PHP_EOL;// 打印队列echo $queue. PHP_EOL;3. 打印后果Array: size = 5, capacity = 8[a,b,c,d,e]eaArray: size = 3, capacity = 4[b,c,d]

October 21, 2020 · 1 min · jiezi

关于php:PHP通过带尾指针的链表实现队列

这篇文章是展现通过 PHP 语言实现一种带尾指针的链表,而后通过链表来实现队列,其中链表的头元素 head 是用于列队出队的,它的工夫复杂度 O(1),若在 head 的根底上实现链表尾部入队工夫度为 O(n),为了升高入队操作的工夫复杂度,能够给链表保护一个带有尾指针的变量 tail,这样每次入队的时候间接操作 tail,出队的时候间接操作 head,这样能够使得 入队和出队 工夫复杂度都是 O(1)。 1.output_queue_by_liked_list.php这是一个演示打印输出后果的文件: <?phprequire 'QueueByLinkedList.php';$queue = new QueueByLinkedList();$queue->enqueue("rr"); //入队$queue->enqueue("tt"); //入队$queue->enqueue("yy"); //入队$queue->enqueue("uu"); //入队$queue->enqueue("ii"); //入队$queue->enqueue("oo"); //入队echo $queue->toString(); //打印 rr->tt->yy->uu->ii->oo->nullecho "<br>";echo $queue->dequeue(); //出队 打印 rrecho "<br>";echo $queue->dequeue(); //出队 打印 ttecho "<br>";echo $queue->dequeue(); //出队 打印 yyecho "<br>";echo $queue->toString(); //打印 uu->ii->oo->nullecho "<br>";$queue->enqueue("11"); //入队$queue->enqueue("22"); //入队$queue->enqueue("33"); //入队$queue->enqueue("44"); //入队$queue->enqueue("55"); //入队$queue->enqueue("66"); //入队echo "<br>";echo $queue->toString(); //打印 uu->ii->oo->11->22->33->44->55->66->null3.QueueByLinkedList 类这是通过带尾指针链表实现的 队列 类,它外面有 入队(enqueue) 办法和 出队(dequque) 办法 : <?phprequire 'Queue.php';/** * 带有尾指针的链表 * Class LinkedListTail */class QueueByLinkedList implements Queue{ private $head; //链表头部 private $tail; //链表尾部 private $size; //链表大小 /** * 构造函数 初始化链表 * QueueByLinkedList constructor. */ public function __construct() { $this->head = null; $this->tail = null; $this->size = 0; } /** * 入队操作 * @param $e */ public function enqueue($e): void { if ($this->tail == null) { $this->tail = $this->head = new Node($e, null); } else { $node = new Node($e, null); $this->tail->next = $node; $this->tail = $node; } $this->size++; } /** * 出队操作 * @return mixed */ public function dequeue() { if ($this->size == 0) { return "队列曾经是空的"; } $node = $this->head; $this->head = $node->next; $this->size--; if ($node->next == null) { $this->tail = null; } return $node->e; } public function getFront() { if ($this->size == 0) { return "队列曾经是空的"; } return $this->head->e; } public function getSize() { return $this->size; } /** * 判断队列是否为空 * @return bool */ public function isEmpty(): bool { return $this->size == 0; } public function toString() { $str = ""; for ($node = $this->head; $node != null; $node = $node->next) { $str .= $node->e . "->"; } $str .= "null"; return $str; }}class Node{ public $e;//节点元素 public $next; //下个节点信息 /** * 构造函数 设置节点信息 * Node constructor. * @param $e * @param $next */ public function __construct($e, $next) { $this->e = $e; $this->next = $next; }}4.interface Queue这里是 队列 类一个实现接口,外面定义了一些函数,继承它之后,必须重构外面的所有办法: ...

October 21, 2020 · 2 min · jiezi

关于php:2-数据结构PHP实现-用数组来实现栈

阐明:该文章是用数组来实现栈,所以会继承数组的逻辑操作(数组的逻辑操作在上文有提到 https://segmentfault.com/a/11...)1. 实现逻辑<?php/** * content: 数组栈的实现 * create: 2020-10-20 */namespace StackBundle;use ArrayBundleBaseArray;class BaseArrayStack extends BaseArray{ /** * 弹出栈顶元素 * @return mixed */ public function pop() { return $this->del($this->size - 1); } /** * 从栈顶插入元素 * @param mixed $value */ public function push($value): void { $this->addLast($value); } /** * 敞开从栈头插入元素的办法 * @param mixed $value */ public function addFirst($value): void { exit('插入谬误!栈构造无奈在最后面插入数据,只能从尾部插入'); }}2. 执行逻辑<?phprequire_once __DIR__. '/../vendor/autoload.php';$stack = new StackBundleBaseArrayStack(1);// 从栈的顶部插入5个元素$stack->push('a');$stack->push('b');$stack->push('c');$stack->push('d');$stack->push('e');// 从栈的顶部弹出4个元素echo $stack->pop(). PHP_EOL;echo $stack->pop(). PHP_EOL;echo $stack->pop(). PHP_EOL;echo $stack->pop(). PHP_EOL;echo $stack;3. 打印后果edcbArray: size = 1, capacity = 1[a]

October 21, 2020 · 1 min · jiezi

关于php:Laravel项目上线注意点

新建我的项目时放弃环境配置统一并记录,composer MySQL PHP Redis Nginx清一下缓存和包主动发现php artisan package:discoverphp artisan config:clearphp artisan cache:clear线下环境删除 \storage\logs 的日志文件,在线上环境给 storage和 bootstrap/cache 775权限。当零碎为centos 7.6,查看SELinux的模式是否开了强制模式查看SELinux状态 默认为强制模式Enforcing-强制模式,根据设定来限度档案资源存取Permissive:宽容模式,不限度档案资源存取,但仍会根据设定查看并记录相干讯息。Disabled:停用模式,SELinux 已被停用。 sestatus批改 sestatus 为停用模式或宽容模式 确保线上线下环境统一相干连贯 https://www.tytrock.com/topic...

October 21, 2020 · 1 min · jiezi

关于php:数据结构PHP通过链表类对象实现-栈

这篇文章是展现如何应用PHP语言实现的链表类(LinkedList),而后通过链表来实现的 栈(Stack) 只能从栈顶增加元素,也只能从栈顶取出元素,是一种 Last In First Out(LIFO),即 后进先出 的构造。 1.output_stack_by_linked_list.php这是一个调用和打印输出后果的展现文件: <?php/** * 栈输入相干 */require 'StackByLinkedList.php';$stack = new StackByLinkedList();$stack->push('aa');$stack->push('bb');$stack->push('cc');$stack->push('dd');$stack->push('ee');$stack->push('ff');$stack->push('gg');$stack->push('hh');echo $stack->peek(); //查看栈顶元素,打印 hhecho "<br>";echo $stack->toString(); //打印栈数据 hh->gg->ff->ee->dd->cc->bb->aa->nullecho "<br>";echo $stack->pop(); //出栈,打印 hhecho "<br>";echo $stack->toString(); //打印栈数据 gg->ff->ee->dd->cc->bb->aa->null2.StackByLinkedList 类这是一个封装好的 栈(Stack) ,通过实例化 链表类(LinkedList) 实现了入栈(push)和 出栈(pop), 还有查看栈顶(peek): <?phprequire 'LinkedList.php';require 'Stack.php';class StackByLinkedList implements Stack{ //链表类对象,用于寄存栈元素 protected $array = null; /** * 构造函数 定义栈的容量 * ArrayStruct constructor. * @param int $capacity */ public function __construct() { $this->array = new LinkedList(); } /** * 获取栈大小 * @return int */ public function getSize(): int { return $this->array->getSize(); } /** * 判断栈是否为空 * @return bool */ public function isEmpty(): bool { return $this->array->isEmpty(); } /** * 元素入栈 */ public function push($e): void { $this->array->addFirst($e); } /** * 出栈 * @return mixed */ public function pop() { return $this->array->removeFirst(); } /** * 查看栈顶元素 * @return mixed */ public function peek() { return $this->array->getFirst(); } /** * 将栈数组转化为字符串 * @return string */ public function toString(): string { return $this->array->toString(); }}Tips:这是一个Stack类,通过继承 LinkedList 类实现 Stack 的基本功能。3.interface Stack<?phpinterface Stack{ /** * 获取栈大小 * @return int */ public function getSize(): int; /** * 判断栈是否为空 * @return bool */ public function isEmpty(): bool; /** * 元素入栈 */ public function push($e): void; /** * 出栈 * @return mixed */ public function pop(); /** * 查看栈顶元素 * @return mixed */ public function peek();}4.LinkedList 类这是封装好的一个链表类,能实现链表的基本功能: ...

October 21, 2020 · 4 min · jiezi

关于php:PHP-常见浮点数操作

浮点数操作在理论利用中还是挺多的,这篇笔记用来整顿常见操作。 保留N位小数做四舍五入想要保留N 位小数同时做四舍五入的形式还是挺多的,上面列举罕用的几种。 sprintfsprintf 函数用于返回一个格式化之后的字符串。 <?php$num = 22.356;echo sprintf("%.2f", $num); // 22.36%.2f 是指标格局,其中2 示意2 位,f示意视为浮点数。 roundround 函数用于对浮点数进行四舍五入。 还能够通过传入参数,决定从第几位开始四舍五入。如果没有参数,默认从小数点后一位开始四舍五入。 <?phpecho round(3.4); // 3echo round(3.5); // 4echo round(22.356, 2); // 22.36保留N位小数不做四舍五入<?php$num = 22.356;echo sprintf("%.2f",substr(sprintf("%.3f", $num), 0, -1)); // 22.35获取小数位长度<?php$num = 22.356;echo strlen(substr(strrchr($num, "."), 1)); // 3

October 20, 2020 · 1 min · jiezi

关于php:Hyperf-发布-v2015-版本企业级的-PHP-微服务云原生协程框架

更新内容本周次要新增了局部个性,并修复了一些组件的 ????Bug,持续晋升 Hyperf 的稳定性,公布于 2.0.15 版。 倡议用户应用以下命令更新此版本。 composer update "hyperf/*" -o间接拜访 官网 hyperf.io 或 文档 hyperf.wiki 查看更新内容 新增#2654 新增办法 Hyperf\Utils\Resource::from,能够不便的将 string 转化为 resource。修复#2634 #2640 修复 snowflake 组件中,元数据生成器 RedisSecondMetaGenerator 会产生雷同元数据的问题。#2639 修复 json-rpc 组件中,异样无奈失常被序列化的问题。#2643 修复 scout:flush 执行失败的问题。优化#2656 优化了 json-rpc 组件,参数解析失败后,也能够返回对应的错误信息。对于 HyperfHyperf 是基于 Swoole 4.5+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量罕用的组件,性能较传统基于 PHP-FPM 的框架有质的晋升,提供超高性能的同时,也放弃着极其灵便的可扩展性,规范组件均基于 PSR 规范 实现,基于弱小的依赖注入设计,保障了绝大部分组件或类都是 可替换 与 可复用 的。 框架组件库除了常见的协程版的 MySQL 客户端、Redis 客户端,还为您筹备了协程版的 Eloquent ORM、WebSocket 服务端及客户端、JSON RPC 服务端及客户端、GRPC 服务端及客户端、OpenTracing(Zipkin, Jaeger) 客户端、Guzzle HTTP 客户端、Elasticsearch 客户端、Consul、Nacos 服务中心、ETCD 客户端、AMQP 组件、Nats 组件、Apollo、ETCD、Zookeeper、Nacos 和阿里云 ACM 的配置核心、基于令牌桶算法的限流器、通用连接池、熔断器、Swagger 文档生成、Swoole Tracker、Blade、Smarty、Twig、Plates 和 ThinkTemplate 视图引擎、Snowflake 全局ID生成器、Prometheus 服务监控 等组件,省去了本人实现对应协程版本的麻烦。 ...

October 20, 2020 · 1 min · jiezi

关于php:数据结构PHP通过-Array-类对象实现-队列

这篇文章是展现如何应用PHP语言实现队列(Queue)这种数据结构,Queue也是一种线性构造,相比 Array 而言,Queue 对应的操作是 Array 的子集,只能从一端(队尾)增加元素,也只能从另外一端(队首)取出元素,是一种 First In First Out(FIFO),即 先进先出 的构造。 1.ArrayStruct 类<?php/** * 数据结构-数组的实现 * Class ArrayStruct */class ArrayStruct{ //用于存放数据 protected $data = []; //用于标记数组大小 protected $size = 0; //用于标记数组的容量 protected $capacity = 10; /** * 构造函数 定义数组容量 * ArrayStruct constructor. * @param int $capacity */ public function __construct(int $capacity = 10) { $this->capacity = $capacity; } /** * 获取数组元素个数 * @return int */ public function getSize(): int { return $this->size; } /** * 获取数组的容量 * @return int */ public function getCapacity(): int { return $this->capacity; } /** * 判断数组是否为空 * @return bool */ public function isEmpty(): bool { return $this->size == 0; } /** * 向数组指定地位插入元素 * @param int $index * @param $e * @throws Exception */ public function add(int $index, $e): void { if ($this->size == $this->capacity) { $this->resize(2); //扩充到原来的2倍 } if ($index < 0 || $index > $this->size) { echo "增加地位超出数组大小"; exit; } //为了不便了解,[1,2,4,5,6],假如 $index = 3; $e = 100,插入之后[1,2,4,100,5,6] for ($i = $this->size; $i >= $index; $i--) { $this->data[$i] = $this->data[$i - 1]; } $this->data[$index] = $e; $this->size++; } /** * 向数组开端增加元素 * @param $e * @throws Exception */ public function addLast($e): void { $this->add($this->size, $e); } /** * 向数组结尾插入元素 * @param $e * @throws Exception */ public function addFirst($e): void { $this->add(0, $e); } /** * 获取 index 地位数组元素 * @param int $index * @return mixed */ public function get(int $index) { if ($index < 0 || $index > $this->size) { echo "index值超出元素的地位范畴,"; exit; } return $this->data[$index]; } /** * 获取数组开端元素 * @return mixed */ public function getLast() { return $this->get($this->size - 1); } /** * 获取数组结尾元素 * @return mixed */ public function getFirst() { return $this->get(0); } /** * 判断数组中是否存在某个元素 * @param $e * @return bool */ public function contains($e): bool { for ($i = 1; $i < $this->size; $i++) { if ($this->data[$i] == $e) { return true; } } return false; } /** * 查某个元素在数组的地位索引值,若不存在则返回 -1 * @param $e * @return int */ public function find($e): int { for ($i = 0; $i < $this->size; $i++) { if ($this->data[$i] == $e) { return $i; } } return -1; } /** * 删除数组指定地位元素,返回删除元素的值 * @param $index * @return mixed */ public function remove($index) { if ($index < 0 || $index > $this->size) { echo "index值超出元素的地位范畴,"; exit; } $e = $this->data[$index]; for ($i = $index; $i < $this->size - 1; $i++) { $this->data[$i] = $this->data[$i + 1]; } $this->size--; $this->data[$this->size] = null; //loitering objects ! =memory /** 若以后数组大小,小于容量的一半,则重新分配一半的数组空间大小 **/ if ($this->size <= $this->capacity / 4 && $this->capacity % 2 == 0) { $this->resize(0.5); } return $e; } /** * 删除数组首个元素,返回删除元素的值 */ public function removeFirst() { return $this->remove(0); } /** * 删除数组首个元素,返回删除元素的值 */ public function removeLast() { return $this->remove($this->size - 1); } /** * 删除数组中特定元素 * @param $e */ public function removeElement($e) { for ($i = 0; $i < $this->size; $i++) { if ($this->data[$i] == $e) { $this->remove($i); $this->removeElement($e); break; } } } /** * 数组扩容,若是其余语言,如JAVA这里须要从新开拓空间 * @param $factor */ protected function resize($factor) { $this->capacity = $factor * $this->capacity; } /** * 将数组转化为字符串 * @return string */ public function toString(): string { $str = "["; for ($i = 0; $i < $this->size; $i++) { $value_str = is_numeric($this->data[$i]) ? $this->data[$i] : "'{$this->data[$i]}'"; $str .= $i . " => " . $value_str . ","; } $str = trim($str, ","); $str .= "]"; return $str; }}Tips:这是一个封装好的数组类,可用于数组的插入、删除、查找。2.QueueStruct 类这里是一个 队列 类,它的继承了数组类的办法,通过数组的增删查封装的一个 队列 类,实现了 入队(enqueue)、出队(dequeue)、查看队首(getFront) : ...

October 20, 2020 · 4 min · jiezi

关于php:PHP-7真实世界的应用开发PHP-7-安装注意事项

PHP 7 装置注意事项获取 PHP 7 次要有三种形式: 间接下载源代码并装置装置预编译的二进制文件装置 *AMP 汇合包(比方:XAMPP、WAMP、LAMP、MAMP等等)如何做这三种办法按难易水平排列。然而,第一种办法尽管简短乏味,然而能够让您对扩大和选项进行最无限的管制。 间接从源码装置为了利用这种办法,您须要有一个 C 编译器。如果您运行的是 Windows,MinGW 是一个收费的编译器,它曾经被证实很受欢迎。它基于 GNU 我的项目提供的 GNU 编译器汇合(GCC)编译器。非收费的编译器包含Borland 公司的经典的 Turbo C 编译器,当然,Windows 开发者首选的编译器是 Visual Studio。不过,后者次要是为 C++ 开发设计的,所以在编译 PHP 时,须要指定 C 模式。 当在Apple Mac上工作时,最好的解决方案是装置 Apple Developer Tools。你能够应用 Xcode IDE 来编译 PHP 7,或者从终端窗口运行 gcc。在 Linux 环境下,从终端窗口运行 gcc。 当从终端窗口或命令行进行编译时,通常的过程如下: configuremakemake testmake install无关配置选项的信息(即在运行 configure 时) ,请应用 help选项: configure --help在配置阶段可能遇到的谬误如下表所示: 谬误修复configure: error: xml2-config not found. Please check your libxml2 installation你只须要装置 libxml2。对于这个谬误,请参考以下链接:http://superuser.com/question...configure: error: Please reinstall readline - I cannot find readline.h装置 libreadline-devconfigure: WARNING: unrecognized options: --enable-spl, --enable-reflection, --with-libxml没什么大不了的。这些选项是默认选项,不须要包含在内。无关详情,请参阅以下连结:http://jcutrer.com/howto/linu...从预编译的二进制文件装置 PHP 7顾名思义,预编译的二进制文件是由他人从 PHP 7 源代码中编译进去的二进制文件。 ...

October 19, 2020 · 2 min · jiezi

关于php:数据结构PHP通过-Array-类对象实现-栈

这篇文章是展现如何应用PHP语言实现栈(Stack)这种数据结构,Stack也是一种线性构造,相比 Array 而言,Stack 对应的操作是 Array 的子集,只能从一端增加元素,也只能从一端取出元素,是一种 Last In First Out(LIFO),即 后进先出 的构造,Stack 的利用很多,如 'undo 操作(撤销)'、'程序调用零碎栈'。 1.ArrayStruct 类<?php/** * 数据结构-数组的实现 * Class ArrayStruct */class ArrayStruct{ //用于存放数据 protected $data = []; //用于标记数组大小 protected $size = 0; //用于标记数组的容量 protected $capacity = 10; /** * 构造函数 定义数组容量 * ArrayStruct constructor. * @param int $capacity */ public function __construct(int $capacity = 10) { $this->capacity = $capacity; } /** * 获取数组元素个数 * @return int */ public function getSize(): int { return $this->size; } /** * 获取数组的容量 * @return int */ public function getCapacity(): int { return $this->capacity; } /** * 判断数组是否为空 * @return bool */ public function isEmpty(): bool { return $this->size == 0; } /** * 向数组指定地位插入元素 * @param int $index * @param $e * @throws Exception */ public function add(int $index, $e): void { if ($this->size == $this->capacity) { $this->resize(2); //扩充到原来的2倍 } if ($index < 0 || $index > $this->size) { echo "增加地位超出数组大小"; exit; } //为了不便了解,[1,2,4,5,6],假如 $index = 3; $e = 100,插入之后[1,2,4,100,5,6] for ($i = $this->size; $i >= $index; $i--) { $this->data[$i] = $this->data[$i - 1]; } $this->data[$index] = $e; $this->size++; } /** * 向数组开端增加元素 * @param $e * @throws Exception */ public function addLast($e): void { $this->add($this->size, $e); } /** * 向数组结尾插入元素 * @param $e * @throws Exception */ public function addFirst($e): void { $this->add(0, $e); } /** * 获取 index 地位数组元素 * @param int $index * @return mixed */ public function get(int $index) { if ($index < 0 || $index > $this->size) { echo "index值超出元素的地位范畴,"; exit; } return $this->data[$index]; } /** * 获取数组开端元素 * @return mixed */ public function getLast() { return $this->get($this->size - 1); } /** * 判断数组中是否存在某个元素 * @param $e * @return bool */ public function contains($e): bool { for ($i = 1; $i < $this->size; $i++) { if ($this->data[$i] == $e) { return true; } } return false; } /** * 查某个元素在数组的地位索引值,若不存在则返回 -1 * @param $e * @return int */ public function find($e): int { for ($i = 0; $i < $this->size; $i++) { if ($this->data[$i] == $e) { return $i; } } return -1; } /** * 删除数组指定地位元素,返回删除元素的值 * @param $index * @return mixed */ public function remove($index) { if ($index < 0 || $index > $this->size) { echo "index值超出元素的地位范畴,"; exit; } $e = $this->data[$index]; for ($i = $index; $i < $this->size - 1; $i++) { $this->data[$i] = $this->data[$i + 1]; } $this->size--; $this->data[$this->size] = null; //loitering objects ! =memory /** 若以后数组大小,小于容量的一半,则重新分配一半的数组空间大小 **/ if ($this->size <= $this->capacity / 4 && $this->capacity % 2 == 0) { $this->resize(0.5); } return $e; } /** * 删除数组首个元素,返回删除元素的值 */ public function removeFirst() { return $this->remove(0); } /** * 删除数组首个元素,返回删除元素的值 */ public function removeLast() { return $this->remove($this->size - 1); } /** * 删除数组中特定元素 * @param $e */ public function removeElement($e) { for ($i = 0; $i < $this->size; $i++) { if ($this->data[$i] == $e) { $this->remove($i); $this->removeElement($e); break; } } } /** * 数组扩容,若是其余语言,如JAVA这里须要从新开拓空间 * @param $factor */ protected function resize($factor) { $this->capacity = $factor * $this->capacity; } /** * 将数组转化为字符串 * @return string */ public function toString(): string { $str = "["; foreach ($this->data as $value) { $str .= $value . ","; } $str = trim($str, ","); $str .= "]"; return $str; }}Tips:这是一个封装好的数组类,可用于数组的插入、删除、查找。2.StackStruct 类<?phprequire 'ArrayStruct.php';require 'Stack.php';/** * 数组实现栈 * Class StackStruct */class StackStruct implements Stack{ //数组类对象,用于寄存栈元素 public $array = null; /** * 构造函数 定义栈的容量 * ArrayStruct constructor. * @param int $capacity */ public function __construct(int $capacity = 10) { $this->array = new ArrayStruct($capacity); } /** * 获取栈大小 * @return int */ public function getSize(): int { return $this->array->getSize(); } /** * 判断栈是否为空 * @return bool */ public function isEmpty(): bool { return $this->array->isEmpty(); } /** * 元素入栈 */ public function push($e): void { $this->array->addLast($e); } /** * 出栈 * @return mixed */ public function pop() { return $this->array->removeLast(); } /** * 查看栈顶元素 * @return mixed */ public function peek() { return $this->array->getLast(); } /** * 将栈数组转化为字符串 * @return string */ public function toString(): string { return rtrim($this->array->toString(), "]"); }}Tips:这是一个Stack类,通过继承 Array 类实现 Stack 的基本功能。3.interface Stack<?phpinterface Stack{ /** * 获取栈大小 * @return int */ public function getSize(): int; /** * 判断栈是否为空 * @return bool */ public function isEmpty(): bool; /** * 元素入栈 */ public function push($e): void; /** * 出栈 * @return mixed */ public function pop(); /** * 查看栈顶元素 * @return mixed */ public function peek();}4.output_stack.php<?php/** * 栈输入相干 */require 'StackStruct.php';$stack = new StackStruct();$stack->push('aa');$stack->push('bb');$stack->push('cc');$stack->push('dd');$stack->push('ee');$stack->push('ff');$stack->push('gg');$stack->push('hh');echo $stack->peek(); //查看栈顶元素,打印 hhecho $stack->toString(); //打印栈数据 [aa,bb,cc,dd,ee,ff,gg,hhecho $stack->pop(); //出栈,打印 hhecho $stack->toString(); //打印栈数据 [aa,bb,cc,dd,ee,ff,gg

October 19, 2020 · 4 min · jiezi

关于php:PHP8x-你必须知道的这些新特性

前言Hello 大家好,我是CrazyCodes,间隔上次发文曾经过来4个月的工夫,往年是悲惨的一年,也是发奋的一年,我会公布一些更好更实用的文章与大家分享,谢谢大家始终以来的反对。 本篇是我加入《2020 PHP开发者峰会》 Nikita分享内理解到的一些常识与大家分享 Nikita 是PHP8的外围开发者。PHP8的版本会在往年11月26日与各位开发者见面,敬请期待JIT值得被提起的则是JIT新的个性,它会将PHP代码转换为传统的机器码,而并非通过zend虚拟机来运行,这样大大的减少了运行速度,但并不向下兼容,这意味着你不能通过像PHP5降级到PHP7那样取得该个性。 JIT能够通过php.ini去设置,例如这样 opcache.jit=on // on 代表关上,则off代表敞开注解PHP8版本彻底把注解扶正,当然在这之前像 Symfony,hyperf通过php-parser退出注解的应用办法,但这毕竟不属于PHP8内核真正的局部,在PHP8的版本中,但仍旧须要反射 new ReflecationProperty(User::class,"id");去获取到注解局部,看来注解在PHP的历史长河中还是须要持续不断完善的。 类中的成员变量小的知识点在PHP8之前,咱们个别会这样定义一个类,首先要设置成员变量,而后在结构或者某一个办法为它赋值。 class User{ public $username; public $phone; public $sex; public function __contruct( $username,$phone,$sex ){ $this->username = $username; $this->phone = $phone; $this->sex = $sex; }}但在PHP8上,咱们能够这样做 class User{ public function __contruct( public string $username = "zhangsan", public string $phone = "110110"; public string $sex = "男" ){}}命名参数当咱们创立一个函数时,例如 function roule($name,$controller,$model){ // ... code}在调用这个函数时,咱们须要程序输出参数 roule("user/login","UserController","login");但在PHP8中,咱们能够这样做 ...

October 19, 2020 · 1 min · jiezi

关于php:php-工厂设计模式

<?php# 定义一个形象办法abstract class PubAction{ abstract public function index(); public function demo(){ }}#如果继承抽象类,那么抽象类中的形象办法,必须要全副实现# 定义一个A类 继承 抽象类class A extends PubAction{ public function index() { return "我是A中的办法"; }}# 定义一个B类 继承 抽象类class B extends PubAction{ public function index() { return "我是B中的办法"; }}# 定义工厂类class Factory{ # 定义 一个公共的静态方法 用来创建对象 public static function index($str) { if($str == "A") { return new A; }else if($str == "B") { return new B; }else{ return "没有此类"; } }}$obj = Factory::index("A");# 判断是否是一个对象,如果是一个对象则输入一个公共的办法if(is_object($obj)){ echo $obj->index();}else{ echo $obj;}# 应用工厂模式,益处是只须要将对应的信息传递到工厂类中,即可生产出一个对应的对象。 毛病是:如果每减少一个类就须要创立一个具体的类和对象来实现工厂。

October 19, 2020 · 1 min · jiezi

关于php:对于null空0false等数据类型的理解

之所以决定写这片笔记,是因为始终对 空 这个概念很含糊,在代码逻辑中常会遇到须要判断的时候,总是模仿两可。 常见的“空”有以下这些: 整形0:0字符1:1字符空:""字符零:"0"空数组:[]truefalsenullNUll 下面的那些都好了解,都是常见的,重点介绍一下NULL。 NULL 是什么?Null是在计算机具备保留的值,能够用于指针不去援用对象,当初很多程序都会应用指针来示意条件,然而在不同的语言中,含意是不一样的。这里咱们只介绍 PHP 中的 NULL。 在 PHP 中,示意一个变量没有赋值、或者是被赋值的值为 NULL,以及被 unset 的。 应用PHP 函数对变量进行比拟:表达式gettype()empty()is_null()isset()boolean : if($x)$x = "";stringTRUEFALSETRUEFALSE$x = null;NULLTRUETRUEFALSEFALSEvar $x;NULLTRUETRUEFALSEFALSE$x is undefinedNULLTRUETRUEFALSEFALSE$x = array();arrayTRUEFALSETRUEFALSE$x = false;booleanTRUEFALSETRUEFALSE$x = true;booleanFALSEFALSETRUETRUE$x = 1;integerFALSEFALSETRUETRUE$x = 42;integerFALSEFALSETRUETRUE$x = 0;integerTRUEFALSETRUEFALSE$x = -1;integerFALSEFALSETRUETRUE$x = "1";stringFALSEFALSETRUETRUE$x = "0";stringTRUEFALSETRUEFALSE$x = "-1";stringFALSEFALSETRUETRUE$x = "php";stringFALSEFALSETRUETRUE$x = "true";stringFALSEFALSETRUETRUE$x = "false";stringFALSEFALSETRUETRUE涣散判断 == TRUEFALSE10-1"1""0""-1"NULLarray()"php"""TRUETRUEFALSETRUEFALSETRUETRUEFALSETRUEFALSEFALSETRUEFALSEFALSEFALSETRUEFALSETRUEFALSEFALSETRUEFALSETRUETRUEFALSETRUE1TRUEFALSETRUEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSEFALSE0FALSETRUEFALSETRUEFALSEFALSETRUEFALSETRUEFALSETRUETRUE-1TRUEFALSEFALSEFALSETRUEFALSEFALSETRUEFALSEFALSEFALSEFALSE"1"TRUEFALSETRUEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSEFALSE"0"FALSETRUEFALSETRUEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSE"-1"TRUEFALSEFALSEFALSETRUEFALSEFALSETRUEFALSEFALSEFALSEFALSENULLFALSETRUEFALSETRUEFALSEFALSEFALSEFALSETRUETRUEFALSETRUEarray()FALSETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSE"php"TRUEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUEFALSE""FALSETRUEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSETRUE严格比拟 === TRUEFALSE10-1"1""0""-1"NULLarray()"php"""TRUETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSE1FALSEFALSETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSE0FALSEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSE-1FALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSE"1"FALSEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSEFALSE"0"FALSEFALSEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSE"-1"FALSEFALSEFALSEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSENULLFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEarray()FALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSETRUEFALSEFALSE"php"FALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSETRUEFALSE""FALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSETRUE参考链接PHP 类型比拟表

October 17, 2020 · 1 min · jiezi

关于php:PhpStorm在使用Yii框架开发的时候程序崩溃假死的解决办法

当你的 PhpStorm 在开发Yii框架相干程序的时候,咱们有的人会启用一个插件 Github:Yii2support,然而当Phpstorm开启这个插件的时候,每当咱们的代码写道 ::class的时候,Phpstorm都会假死。 其实这个插件的作者曾经解决了这个方法,然而这个版本的插件还是测试版,大家能够去这里下载:https://github.com/nvlad/yii2...,或者间接下载 yii2support-0.10.57.24.jar.zip , 以后2020-10-15日的最新版本还是 0.10.57.23,作者说了这个是测试版。 怎么从本地装置插件,本人百度或者摸索去,很简略,我就不多说了。应用后,假死的状况确实没有了。终于解决了一年多了的问题,都差点儿有心理暗影了。

October 15, 2020 · 1 min · jiezi

关于php:Yii-中特殊行为-ActionFilter-的使用示例

新建 app\filters\LoggingFilter 继承 yii\base\ActionFilterLoggingFilter 的性能: 在指定申请的 action 前后各记录一条日志<?phpnamespace app\filters;use yii\base\ActionFilter;class LoggingFilter extends ActionFilter{ public function beforeAction($action) { parent::beforeAction($action); // To do something printf('This is a logging for %s\beforeAction.%s', $this->getActionId($action), PHP_EOL); return true; } public function afterAction($action, $result) { parent::afterAction($action, $result); // To do something printf('This is a logging for %s\afterAction.%s', $this->getActionId($action), PHP_EOL); return true; }}新建 app\controllers\SystemController<?phpnamespace app\controllers;use app\filters\LoggingFilter;class SystemController extends \yii\web\Controller{ public function behaviors() { parent::behaviors(); return [ 'anchorAuth' => [ 'class' => LoggingFilter::className(), 'only' => ['test', 'test-one'], // 仅对 'test'、'test-one' 失效 'except' => ['test-one'], // 排除 'test-one' ], ]; } public function actionTestOne() { printf('This is a testing for %s.%s', $this->getRoute(), PHP_EOL); } public function actionTestTwo() { printf('This is a testing for %s.%s', $this->getRoute(), PHP_EOL); } public function actionTest() { printf('This is a testing for %s.%s', $this->getRoute(), PHP_EOL); }}测试申请 http://yii.test/index.php?r=system/testThis is a logging for test\beforeAction.This is a testing for system/test.This is a logging for test\afterAction.申请 http://yii.test/index.php?r=system/test-oneThis is a testing for system/test-one.申请 http://yii.test/index.php?r=system/test-twoThis is a testing for system/test-two.总结Yii 中的 ActionFilter(过滤器)相当于 Laravel 中的 Middleware(中间件),beforeAction 相当于前置中间件,afterAction 相当于后置中间件。 ...

October 15, 2020 · 1 min · jiezi

关于php:PHP使用protobuf

服务器环境Ubuntu 18.04.5 LTSPHP7.2.24 装置protoc 1.获取v3.13.0.1(截止2020.10.14)wget https://codeload.github.com/protocolbuffers/protobuf/tar.gz/v3.13.0.12.解压tar zxvf v3.13.0.1 cd protobuf-3.13.0.11.生成 configure 脚本;./autogen.sh2.编译装置./configure --prefix=/usr/local/protobufmake && make install3.设置全局export PATH=/usr/local/protobuf/bin:$PATH4.查看装置胜利protoc --version呈现`libprotoc 3.13.0`即装置胜利装置php-protobuf拓展 pecl install protobuf接下来,将`extension=protobuf.so`增加到 `php.ini` 文件(例如 `/etc/php/7.2/fpm/php.ini`)中。查看php.ini地位1.cli命令行 php --ini2.phpinfo();3.ps -ef | grep php在我的项目根目录 protoc --php_out="protobuf/compile" "protobuf/protos/DmpDataProto.proto"生成的构造 ├── compile│ ├── GPBMetadata│ │ └── Protobuf│ │ └── Protos│ │ └── DmpDataProto.php│ └── Toutiao│ └── Dmp│ ├── DmpData.php│ ├── IdItem_DataType.php│ └── IdItem.php└── protos └── DmpDataProto.protocomposer composer require google/protobuf:^3.3在composer.json配置 "autoload": { "classmap": [ "database/seeds", "database/factories" ], "psr-4": { "App\\": "app/", +"Toutiao\\":"protobuf/compile/Toutiao", +"GPBMetadata\\":"protobuf/compile/GPBMetadata/Protobuf/Protos" } },应用 ...

October 14, 2020 · 1 min · jiezi

关于php:Laravel58-遇到的问题

环境问题(2020-10-14 2H)SQLTATE[42000]: Syntax error or access violation: 1071 Specified key was too long: max key length is 1000 bytes (SQL: alter table test and index test_title_index(title)) 解决形式 /app/Providers/AppServiceProvider.php 中boot()

October 14, 2020 · 1 min · jiezi

关于php:PHPFPM-配置初始化

php-fpm(FastCGI Process Manger)是一个PHP FastCGI 管理器,专门和Nginx 的 ngx_fastcgi_modul模块对接,用来解决动静申请。 初始化当装置了PHP 之后,能够从以下三个方向来对默认配置进行批改,以达到优化的成果。 1. 外围配置文件外围配置文件其实就是 php.ini,该配置文件的作用通常是用来启用或禁用第三方模块,及批改PHP 时区等。 # vim /usr/local/etc/php/php.inidate.timezone = Asia/Shanghai2. 全局配置文件全局配置文件php-fpm.conf,通常用来配置一些辅助性性能。 # vim /usr/local/etc/php-fpm.conferror_log = /var/log/php-fpm/error.loglog_level = notice;process_max = 0deamonize = yes参数解析: error_log:谬误日志门路log_level:日志级别,默认为notice alert:必须立刻解决error:谬误状况warning:正告状况notice:个别重要信息debug:调试信息process_max:管制最大子过程数的全局变量,不倡议设置具体数量,因为会限度扩大配置。daemonize:是否开启守护过程,默认为yes通常不会在php-fpm.conf中设定 process_max,因为会限度www.conf中的配置。 3. 扩大配置文件扩大配置文件www.conf通常是与php-fpm服务相干的配置,大部分优化都是须要更改这个配置文件。 # vim /usr/local/etc/php-fpm.d/www.conflisten = 127.0.0.1:9000slowlog = /var/log/php-fpm/www-slow.log# 这里依照10G 的闲暇内存去设定pm = dynamicpm.start_servers = 16pm.max_children = 256pm.min_spare_servers = 16pm.max_spare_servers = 32pm.max_requests = 1000参数解析: listen:有两种形式能够进行通信。 socket:unix:/run/php/php7.3-fpm.sockhttp:127.0.0.1:9000 因为php-fpm与ngx_fastcgi_modul的通信形式是 9000端口,所以默认是 127.0.0.1:9000slowlog:慢查问日志门路pm:过程治理形式 static:动态模式。始终保持固定数量的子过程数,配合最大子过程数一起应用,这个形式很不灵便,通常不是默认。 pm.max_children:最大子过程数。dynamic:动静模式。依照固定的最小子过程数启动,同时用最大子过程数去限度。 pm.start_servers:默认开启的过程数pm.min_spare_servers:最小闲暇的过程数pm.max_spare_servers:最大闲暇的过程数pm.max_children:最大子过程数pm.max_requests:每个过程能响应的申请数量,达到此限度之后,该PHP 过程就会被主动开释掉。nodaemonize:每个过程在闲置肯定时候后就会被杀掉。 pm.max_children:最大子过程数pm.process_idle_timeout:在多少秒之后,一个闲暇的过程将会被杀死留神:max_children 是 PHPFPM Pool 最大的子过程数,它的数值取决于服务器理论闲暇内存。 ...

October 14, 2020 · 1 min · jiezi

关于php:phpstudymysql55升级mysql57

一、MySQL官网下载MySQL5.7版本,我这里下载的是MySQL5.7.24。 二、间接到D:phpStudyPHPTutorial目录下删除之前的MySQL版本,把下载好的MySQL5.7.24版本解压并批改为MySQL,而后在MySQL目录下新建my.ini文件并退出如下内容: [mysqld] port=3306 basedir=`"D:/phpStudy/PHPTutorial/MySQL/"` datadir=`"D:/phpStudy/PHPTutorial/MySQL/data/"` 这是我本人的目录,有不同的依照本人的作相应批改即可 三、装置数据库 1、因为5.7版本没有data文件夹,咱们须要初始化,管理员权限执行如下命令 mysqld `--initialize 而后目录下就会创立好data目录 2、装置MySQL5.7.24,执行 1 mysqld --install mysql --default-file=D:phpStudyPHPTutorialMySQLmy.ini 创立胜利然而当初还是没法启动,关上phpstudy2018也启动后也会进行 ,咱们要在Phpstudy创立一个服务,如下 查看服务有mysql、MySQLa两个服务,mysql是方才装置MySQL创立扔,5.7.24MySQLa的服务是phpstudy创立的(不晓得什么起因phpstudy2018默认装置好没有mysql服务) 而后,咱们在服务外面启动MySQLa服务,而后去看phpstudy,数据库服务也启动了,然而如果咱们重启或者说敞开了再启动还是启动不起来,这是因为有2个服务占用了,起抵触,须要删除一个。 3、删除mysql服务(因为这个不是Phpstudy创立的服务,所以删除,不能删除MySQLa服务) 1 sc delete mysql 而后再试试,重启一下phpstudy 而后登录5.7.24 首次装置后没有明码,须要批改明码的须要执行 update mysql.`user set authentication_string=password('root') where user='root'`; flush privileges`;` phpstudy自带的明码批改对MySQL5.7不起作用,因为他的明码字段是authentication_string,之前是password

October 14, 2020 · 1 min · jiezi

关于php:Base64编码的前世今生

Base64是一种基于64个可打印字符来示意二进制数据的示意办法。因为2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节可示意4个可打印字符。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包含字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的零碎中而不同。一些如uuencode的其余编码方法,和之后binhex的版本应用不同的64字符集来代表6个二进制数字,然而它们不叫Base64。 起因计算机以二进制模式(0和1)进行通信,然而人们通常心愿与更丰盛的表单数据(例如文本或图像)进行通信。 为了在计算机之间传输此数据,首先必须将其编码为0和1,而后发送,而后再次解码。 以文本为例-有许多不同的办法能够执行此编码。 如果咱们都能够批准一个编码,那就简略得多了,但可怜的是事实并非如此。 最后创立了许多不同的编码(例如Baudot码),每个字符应用不同数量的位,直到最终ASCII成为每个字符7位的规范。 然而,大多数计算机将二进制数据存储在每个字节由8位组成的字节中,因而ASCII不适宜传输此类数据。 有些零碎甚至会擦除最高位。 此外,跨零碎的行尾编码的差别意味着有时还会批改ASCII字符10和13。 为了解决这些问题,引入了Base64编码。 这样,您就能够将框架字节编码为已知能够平安发送而不损坏的字节(ASCII字母数字字符和几个符号)。 毛病是应用Base64编码音讯会减少其长度-每3个字节的数据会编码为4个ASCII字符。为了牢靠地发送文本,您能够首先应用所选的文本编码(例如UTF-8)将其编码为字节,而后再对Base64进行编码,将生成的二进制数据编码为可平安发送为ASCII的文本字符串。 接收者将不得不逆转此过程以复原原始音讯。 当然,这要求接收者晓得应用了哪种编码,并且该信息通常须要独自发送。 从历史上看,它已用于对电子邮件中的二进制数据进行编码,其中电子邮件服务器可能会批改行尾。 一个更古代的示例是应用Base64编码将图像数据间接嵌入HTML源代码中。 在这里,有必要对数据进行编码,以防止像“ <”和“>”这样的字符被解释为标签。 原理base64 加密原理,是将待转换字符串转换为二进制并以三个字为一组(数据有余用 0 补足),每 6 位为一个索引组转换为十进制索引,通过索引在 base64 索引表中找到对应的字符作为编码后的字符(若原数据长度不是 3 的倍数时则对 3 取余余数为 1,则在编码后果后加2个=;若余数为 2,则在编码后果后加 1 个 =。)。 base64 转换实例以 helloworld 为例转换过程如下: 通过上述步骤转后字符串为:aGVsbG93d29ybGQ=,到此一个残缺的转码例子便实现了。 利用base64 在须要网络通讯的场景下,有着十分宽泛的利用场景,比方邮件的附件和图象传输,html img 标签的 src 属性也能够是 base64 编码的图片,还有咱们罕用的各类证书(领取证书,ssl 证书)的公钥和私钥.. Summarybase64 是一个很优良的编码方式,他很好的解决了简单文件在传输中的问题,也因而被宽泛的利用在各种场景之中。对于 base64 的应用,你还须要晓得如下几点: base64 转码后的长度会有所变动,会比源数据的长度多出大概 1/3base64 不具备加密个性,因而他不适用于加密的场景因为 base64 字符中会有 +,/ 等字符,因而如果须要 url 传参的时候留神须要应用 URL 编码一下,否则有可能会导致承受到的数据无奈失常解密的状况References维基百科 Why do we use Base64? What is base 64 encoding used for? ...

October 13, 2020 · 1 min · jiezi

关于php:yiigoaop-将-goaop-集成到-Yii在-Yii-中优雅的面向切面编程

yii-goaop - 将 goaop/framework 集成到 Yii,在 Yii 中优雅的面向切面编程。我的项目地址https://github.com/guanguans/yii-goaop环境要求Yii >= 2.0装置$ composer require guanguans/yii-goaop -vvvcomposer.json add: "autoload": { "psr-4": { "backend\\": "backend/", "frontend\\": "frontend/", "common\\": "common/", "console\\": "console/", "app\\": "" }}$ composer dumpautoload配置yii2-app-advanced配置 config/main.php 文件中增加: <?phpreturn [ 'bootstrap' => [ 'aop', ], 'components' => [ 'aop' => [ 'class' => 'Guanguans\YiiGoAop\GoAopComponent', 'initOption' => [ // AOP Debug Mode 'debug' => false, // Application Root Directory 'appDir' => dirname(dirname(__DIR__)), // AOP Cache Directory 'cacheDir' => dirname(__DIR__).'/runtime/aspect', // Cache File Mode 'cacheFileMode' => 511, // Miscellaneous AOP Engine Features 'features' => 0, // Directories White List 'includePaths' => [ dirname(__DIR__), ], // Directories Black List 'excludePaths' => [ dirname(__DIR__).'/runtime', dirname(__DIR__).'/tests', dirname(__DIR__).'/views', ], // AOP Container 'containerClass' => \Go\Core\GoAspectContainer::class, ], // Yours aspects 'aspects' => [ frontend\aspects\LoggingAspect::class, ], ], ]];yii2-app-basic配置 config/web.php 文件中增加: ...

October 13, 2020 · 2 min · jiezi

关于php:????-Hyperf-发布-v2014-版本企业级的-PHP-微服务云原生协程框架

更新内容本周次要新增了 hyperf/scout, hyperf/resource 和 hyperf/resource-grpc 三个组件,并修复了一些组件的 ????Bug,持续晋升 Hyperf 的稳定性,公布于 2.0.14 版,倡议用户应用以下命令更新此版本。 ScoutScout 为模型的全文搜寻提供了一个简略的、基于驱动程序的解决方案。应用模型观察员,Scout 会主动同步你的搜寻索引和模型记录。 目前,Scout 自带了一个 Elasticsearch 驱动;而编写自定义驱动程序很简略,你能够自在地应用本人的搜寻实现来扩大 Scout。 Resource & ResourceGrpc当构建 API 时,你往往须要一个转换层来联结你的 Model 模型和理论返回给用户的 JSON 响应。资源类可能让你以更直观简便的形式将模型和模型汇合转化成 JSON。 composer update "hyperf/*" -o 间接拜访 官网 hyperf.io 或 文档 hyperf.wiki 查看更新内容 新增#1172 新增基于 laravel/scout 实现的组件 hyperf/scout, 能够通过搜索引擎进行模型查问。#1868 新增 Redis 组件的哨兵模式。#1969 新增组件 hyperf/resource and hyperf/resource-grpc,能够更加不便的将模型转化为 Response。修复#2594 修复 hyperf/crontab 组件因为无奈失常响应 hyperf/signal,导致无奈进行的问题。#2601 修复命令 gen:model 因为 getter 和 setter 同时存在时,正文 @property 会被 @property-read 笼罩的问题。#2607 #2637 修复应用 RetryAnnotationAspect 时,会有肯定水平内存泄露的问题。#2624 修复组件 hyperf/testing 因应用了 guzzle 7.0 和 CURL HOOK 导致无奈失常工作的问题。#2632 #2635 修复 hyperfredis 组件集群模式,无奈设置明码的问题。优化#2603 容许 hyperf/database 组件,whereNull 办法承受 array 作为入参。对于 HyperfHyperf 是基于 Swoole 4.5+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量罕用的组件,性能较传统基于 PHP-FPM 的框架有质的晋升,提供超高性能的同时,也放弃着极其灵便的可扩展性,规范组件均基于 PSR 规范 实现,基于弱小的依赖注入设计,保障了绝大部分组件或类都是 可替换 与 可复用 的。 ...

October 13, 2020 · 2 min · jiezi

关于php:Maximum-execution-time-of-30-seconds-exceeded解决错误方法

Maximum execution time of 30 seconds exceeded解决错误方法Fatal error: Maximum execution time of 30 seconds exceeded呈现这个谬误如何解决 去哪里能够设置最大执行工夫 解决办法:批改php.ini:max_execution_time = 300 ,秒能够设置更大,而后重起服务或者在程序写set_time_limit(工夫) //0为无限度

October 12, 2020 · 1 min · jiezi

关于php:halo博客配置阿里云oss上传附件

原文地址:https://www.wjcms.net/archive...起源以前用的本地上传,然而写完的博客复制到其余平台公布的时候,存在跨域问题,如果应用云oss存储,就不会呈现这种问题,所以还是须要配置云oss存储,这里咱们选用阿里云oss,上面开始配置。获取用户AccessKey鼠标挪动到用户图标上,点击AccessKey 治理 抉择应用子用户 输出登录名称以及显示名称 编程拜访打上勾点击确定,而后应用手机获取验证码即可创立好用户。 而后保留AccessKey 信息到本地,后续看不到就须要从新创立了。 留神:这里只开明了编程拜访,请及时保留 AccessKey 信息,该页面敞开后将无奈再次获取信息。再次点击左侧用户,即可看到方才创立胜利的用户。 后侧有增加权限,点击。 而后抉择零碎策略,在搜寻框输出oss,抉择`AliyunOSSFullAccess治理对象存储服务(OSS)权限`一行 看到右侧有个AliyunOSSFullAccess为已抉择即可,而后点击确认。 到此,用户创立实现,并调配好权限。 进行配置进入halo博客控制台,抉择左侧最下边零碎->博客设置->附件设置。 批改存储地位为:阿里云 下边会多出很多内容填写表单。 绑定域名协定:HTTPS绑定域名:如不填写,门路根域名将为 Bucket + EndPointBucket:EndPoint(地区节点):Access Key:Access Secret:文件目录:上面,一一说一下格局及获取形式。1.绑定域名协定:HTTPS这里须要设置https,同时存储对象也要设置https 2.绑定域名:如不填写,门路根域名将为 Bucket + EndPoint注:这里不倡议填写,不倡议配置本人的域名,因为如果后续要公布到其余平台波及图片跨域,无奈上传图片,间接默认为空即可。 3.Bucket:这个即是方才创立的库名称,间接填写即可 4.EndPoint(地区节点):进入oss对象控制台,点击所属Bucket页面,即可看到如下,抉择外网拜访对应的EndPoint(地区节点)即可。 5.Access Key以及Access Secret方才保留的信息。 6.文件目录:能够设置根目录,间接填写/。 填写子目录须要创立,填写例如: blog/ 留神:肯定要加/ 如何创立目录:在Bucket页面,点击左侧文件治理,下面有新建目录,点击增加即可。 另外上面的策略为可选,这里不做阐明,自行钻研。 把上述信息填写结束,保留好,回到附件页面发现上传的文件存在了oss。 关注我,每天分享文章。

October 12, 2020 · 1 min · jiezi

关于php:laravel8更新之路由调整

原文地址:https://www.wjcms.net/archive...在Laravel的晚期版本中,RouteServiceProvider蕴含一个$namespace属性。该属性的值将主动增加到控制器路由定义和对actionhelper /办法的调用之前。 在Laravel 8.x中,默认状况下为此属性。这意味着Laravel不会主动命名空间前缀。因而,在新的Laravel 8.x应用程序中,应应用规范的PHP可调用语法定义控制器路由定义:URL::actionnull 被正文掉了。所以在laravel8中加载路由须要加上命名空间,如下。 use App\Http\Controllers\Admin\AdminController;Route::get('/admin', [AdminController::class, 'index']);或者也能够 use App\Http\Controllers\Admin;# 注:这里第二个参数是数组Route::get('/admin', [Admin\AdminController::class, 'index']);如果是资源路由,则要: # 留神这里第二个参数是类,字符串,不要传数组 Route::resource('/admin', Admin\AdminController::class);对action相干办法的调用应应用雷同的可调用语法: action([Admin\AdminController::class, 'index']);return Redirect::action([Admin\AdminController::class, 'index']);留神如果您更喜爱Laravel 7.x款式控制器的路由前缀,则能够简略地将$namespace属性增加到应用程序的中RouteServiceProvider。门路为: app/Providers/RouteServiceProvider.php找到该文件,将被正文的一行代码勾销正文即可应用之前版本的主动载入命名空间的写法。29行 // protected $namespace = 'App\\Http\\Controllers';关注我每天分享文章。

October 11, 2020 · 1 min · jiezi

关于php:在-Linux-命令行中执行和使用-PHP-代码

家喻户晓,PHP是一门脚本语言,次要用于服务端(JavaScript 用于客户端)以通过HTTP 生成动静网页。 所以与其余脚本语言一样,能够间接在终端中不须要网页浏览器来运行PHP 代码。 获取装置信息在装置完PHP 以及Nginx 之后,接下来咱们通常须要做的是,在/usr/local/var/www (Mac 上的Nginx 工作目录)上创立一个内容为<?php phpinfo(); ?>,名为index.php的文件来测试PHP 是否装置正确。 执行以下命令即可: # echo '<?php phpinfo(); ?>' > /usr/local/var/www/index.php而后,应用浏览器拜访http://127.0.0.1/index.php,不出意外能够看到: 如何在终端中间接查看该信息?# php -f /usr/local/var/www/index.php | less 如果你感觉下面这种形式太麻烦了,那么还有一种更简便的形式能够达到同样的成果。 # php -r 'php phpinfo();' | less交互模式有时候咱们会遇到这样一种状况,想测试一小段代码,看看其运行后果,然而又不想从新创立一个文件,太麻烦了。 如果这个时候有一个中央能够间接运行这段代码且输入后果,那该多好啊。 PHP 为咱们提供了两种交互模式,前者是主动的,后者是手动的。 Interactive shellInteractive mode enabled两种模式都是应用 php -a 命令进入。 Interactive shell应用这个交互式shell,你能够间接在命令行窗口里输出PHP并间接取得输入后果。 $ php -aInteractive shellphp >echo "Hello PHP";Hello PHPphp > echo 10+90;100回车即可查看输入内容。 Interactive mode enabled$ php -aInteractive mode enabledphp >echo "Hello PHP";如果呈现的是这个模式,阐明你的PHP并不反对交互式shell, ...

October 11, 2020 · 1 min · jiezi

关于php:Sight杀手级提升Laravel开发速度的组件现在开源了

Sight——杀手级晋升Laravel开发速度的组件当初开源了!明天,给大家推存一个Laravel的专用组件:SightLaravel开发速度能够算是最快的了。然而,当初如果加上Sight,那么,你的开发速度会更放慢。Sight做了什么呢?Sight是在Server Side实现了一个Presenter层。从而让你把从服务器中查出的数据轻松转换为可展现的数据。自从有了Sight,Laravel成了惟一反对Server Side的MVP模式的框架。为什么要用Sight呢?一、是放慢开发速度。二、国内的Phper都理解,大厂是禁止SQL联表三个表以上的。遇到初学者,会在FOR循环中查询数据库。如果你禁止了,则还有可能是,他们把相干ID PLUCK进去。查出后果,而后,再FOR循环中嵌套FOR循环去查相干的关联数据。Sight则是提供了很好的Pluck函数,查出ID后,申请到相干数据交给Sight,Sight会为你拼接好数据。它的做法是通过关联ID为KEY把数据整顿好。从而大大晋升了程序效率。三、Sight的应用相当简略。比方以下示例,简直相似于Model的应用。 namespace App\Presenteruse Bardoqi\Sight\Presenter;use Bardoqi\Sight\Traits\PresenterTrait;use Bardoqi\Sight\Enums\MappingTypeEnum use Bardoqi\Sight\Enums\PaginateTypeEnum use App\Repositories\ArticleRepository;use App\Repositories\UserRepository; class ArticlePresenter extents Presenter{ use PresenterTrait; public function getArticleList($where) { $articleArray = ArticleRepository::getList($where); $user_ids = $this->selectFields('id','title','created_at','created_by') ->fromLocal($articleArray,'articles') ->pluck('created_by'); $users = UserRepository::getUsersWithIds($user_ids); $this->innerJoinForeign($users,'userss') ->onRelationByObject(Relation::of() ->localAlias('articles') ->localField('created_by') ->foreignAlias('users') ->foreighField('id')) ->addFieldMappingByObject(FieldMapping::of() ->key('created_at') ->src('created_at') ->type(MappingTypeEnum::METHOD_NAME)) ->addFieldMappingByObject(FieldMapping::of() ->key('created_by') ->src('user_name') ->type(MappingTypeEnum::JOIN_FIELD)); return $this->toPaginateArray(PaginateTypeEnum::PAGINATE_API); }}上例中,代码则是把created_at从int转换成了工夫,把created_by从user id转换成了用户名。咱们看出:created_at所用的是MappingTypeEnum::METHOD_NAME,这个办法在哪里呢,是在PresenterTrait中。所以,你也能够定义本人的Trait。created_by则是间接读取关联数组中的user_name,因为用的是MappingTypeEnum::JOIN_FIELD。下面代码看起来有些长,然而,onRelationByObject()能够改用 onRelation()传参形式,代码就短了。同样addFieldMappingByObject(),改用addFieldMappingList()用数组传入,代码也短了。 Sight远远不只是这一点性能,它不仅反对MySQL查出的数据,同时反对ElasticSearch查出的数据。尽管是纯数组操作,它一样也有innerJoin和outerJoin,并且,有hasOne,hasMany ......当然,还有更多的性能,这个你就要认真看文档了。 Sight试图解决你查出数据后,将其转换成可展现数据中的不爽,它做得很好,真的能让你 Coding More Happy; Coding More Quickly! Github 地址: https://github.com/BardoQi/Sight ...

October 11, 2020 · 1 min · jiezi

关于php:yiivardumper-将-symfony-的-dump-server-集成到-Yii中

将 symfony 的 dump server 适配到 Yii中。我的项目地址https://github.com/guanguans/yii-var-dumper环境要求Yii >= 2.0装置$ composer require guanguans/yii-var-dumper -v配置配置文件 config/main.php 中增加: ...'bootstrap' => [ ... 'dumper', ...],'modules' => [ ... 'dumper' => [ 'class' => 'Guanguans\YiiVarDumper\Module', // 'host' => 'tcp://127.0.0.1:9913', ], ...],...应用启动运行 dump server$ php yii dumper/server应用 --format 选项将输入格局设置为 HTML$ php yii dumper/server --format=html > dump.html# or$ php yii dumper/server -f=html > dump.html调试输入你的变量<?phpdump($yourVariate);输入 相干链接https://github.com/symfony/var-dumper, by symfonyhttps://github.com/beyondcode/laravel-dump-server, by beyondcode

October 9, 2020 · 1 min · jiezi

关于php:ThinkPHP-的join关联查询不使用默认的表前缀

对于ThinkPHP 的关联查问,官网文档是这样形容的: 上述join函数中须要三个参数,别离是: join要关联的(残缺)表名以及别名,反对三种写法: 写法1:[ '残缺表名或者子查问'=>'别名' ]写法2:'残缺表名 别名'写法3:'不带数据表前缀的表名'condition关联条件,能够为字符串或数组, 为数组时每一个元素都是一个关联条件。type关联类型,能够为: INNER、LEFT、RIGHT、FULL,不辨别大小写,默认为INNER。不同前缀个别状况下,都是一个数据库中查问的,这样的状况下默认应用的都是雷同的表前缀,比方(shop_),所以在应用数据库模型关联查问时往往都是这样写的: Order::alias('o') ->join('user u', 'o.user_id = u.id') ->select();在以上代码中,因为是应用模型查问,所以默认都会加上表前缀,两张表的残缺表名就是shop_order和shop_user,而关联类型则默认为INNER关联。 但这时如果关联了一张不同前缀的表(比方:pay_record),上述的查问语句显然就行不通了,这时就须要在关联语句处稍作批改,批改后的代码如下: Order::alias('o') ->join(['pay_record' => 'r'], 'o.pay_id = r.id') ->select();这样便能应用模型关联不同前缀的表进行查问了。 总结上述的形式其实也就是把join函数中的join参数由字符串批改为数组;ThinkPHP是一个很优良的开发框架,上述的关联形式也只是其中一种,更多形式能够查阅官网手册:ThinkPHP官网手册。

October 9, 2020 · 1 min · jiezi

关于php:Laravel-markdown渲染输出到blade模版

原文地址:https://www.wjcms.net/archive...前言昨天,公布了laravel反对markdown编辑器的文章,还附上了配置图片上传,然而有网友问怎么在blade模版中渲染输入,这里写个文章记录一下。装置扩大包Laravel Markdown须要PHP 7.2-8.0 。此特定版本反对Laravel 6-8。 对照上边的表,抉择对应适合的版本,这里我的版本是8,所以装置13.1版本。 composer require graham-campbell/markdown:^13.1在我装置的时候发现报错: PHP Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///www/server/php/74/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223 Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///www/server/php/74/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223 Check https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors for more info on how to handle out of memory errors.# 所以这里咱们应用如下命令进行装置: php -d memory_limit=-1 /usr/bin/composer require graham-campbell/markdown:^13.1上述命令中的/usr/bin/composer,为composer装置地址可应用composer -h命令进行获取。 ...

October 9, 2020 · 1 min · jiezi

关于php:OrzClick-国庆写个-ClickHouse-客户端

起因我看 ClickHouse 有 C++ 客户端(clickhouse-cpp),我又用过 PHP-CPP 写扩大,于是就在国庆写了 OrzClick ,一个 PHP 用的 ClickHouse 客户端。 比拟难堪的是,我写到一半才发现 SeasClick,它也是 clickhouse-cpp 的绑定, 而且是 C 写的,感觉用 PHP-CPP 我就曾经输了一半呀,所以我的小指标就是性能超过 SeasClick。 性能测试Select 后果: 应用 PDO 拜访 ClickHouse 的 MySQL 接口,查问小量数据性能更好 小量数据时,OrzClick 和 SeasClick 性能相近,数据大时 OrzClick > SeasClick > MySQL 接口 Insert 后果: OrzClick-Indexed 对标的是 SeasClick,API 最相近(可看代码:1 2),算是达到了小指标SeasClick 和 OrzClick 都有进步插入性能的 API,SeasClick 的 startWrite-write-endWrite 性能十分好(图上的 SeasClick-Block),OrzClick 的 InsertColumnar 只有数据量大于 5 千时能力超过它(图上的 OrzClick-Columnar)哪个 clickhouse-cpp ?在 Github 搜寻 clickhouse-cpp, 你会发现有两个类似的库: ...

October 9, 2020 · 4 min · jiezi

关于php:Laravel-支持markdown编辑器解决方案

原文连贯:https://www.wjcms.net/archive...laravel-markdown-editor--markdown编辑器 阐明此扩大包兼容laravel5.8以上版本筹备工作装置扩大包composer require wjcms/laravel-markdown-editor配置providers//cconfig/app.php'providers' => [ //增加如下一行 wjcms\laravelmd\LaravelmdServiceProvider::class,]拷贝相干文件到我的项目文件夹中php artisan vendor:publish --provider="wjcms\laravelmd\LaravelmdServiceProvider"应用1.在blade模版引入 @include('layouts.md.md')2.父模版中须要增加上 #留神在scripts上边须要引入jquery@stack('styles')@stack('scripts')3.批改md.blade.php文件的 imageUploadURL批改为接口门路 4.创立service服务uploadservice.php,实现如下办法。 public function upload(UploadedFile $file) { $path = '/uploads/'.$file->store(date('y/m'), 'uploads'); return $this->save($file, $path); }//留神这里还须要创立Attachment模型和数据库(蕴含path,extension,name三个字段) protected function save(UploadedFile $file, $path) { return Attachment::create([ 'path'=>$path, 'extension'=>$file->extension(), 'name'=>$file->getClientOriginalName() ]); }5.admin控制器创立办法 /** * 图片上传办法 */ public function uploadPic(Request $request, UploadService $uploadService) { $res = $uploadService->upload($request->file('editormd-image-file')); return response()->json([ 'success'=>1, 'message'=>'图片上传胜利', 'url'=> $res->path ]); }6.routes/web.php文件增加路由 use App\Http\Controllers\Admin;//留神这里是laravel8的写法,之前版本自行批改Route::prefix('admin')->name('admin.')->group(function () { Route::post('upload', [Admin\AdminController::class,'uploadPic'])->name('upload');}就能够发现markdown编辑器能够应用了。 ...

October 8, 2020 · 1 min · jiezi

关于php:php80-性能上有多大提升

最近一个我的项目用github的actions做测试。应用了4个PHP版本,别离是7.2,7.3,7.4,8.0后面3个版本运行完耗时根本在8秒左右。 php8.0运行实现只须要2秒 测试内容为: 连贯数据库建表写入3条数据12次查问建表写入5条数据聚合查问1次建表写入100w条数据测试后果 在这个测试里php8.0有 4倍 以上的性能晋升

October 8, 2020 · 1 min · jiezi

关于php:PHP-7真实世界的应用开发中文翻译

前言PHP 7:真实世界的利用开发(中文翻译)作者:Doug Bierer, Altaf Hussain, Branko Ajzele原书名称:《PHP 7: Real World Application Development》译者:金弘扬(ganymedenil@gmail.com)Gitbook地址:PHP 7:真实世界的利用开发github:https://github.com/AnyStudy/PHP-7-Real-World-Application-Development举荐应用 Gitbook 以获取最佳浏览体验。 译序作为一个应用了php多年的程序员,公司我的项目也经验过5到7的降级,期间我的项目也呈现过一些因为php7性能与php5 不统一导致的bug。我始终在寻找一本能具体介绍 php 7 新个性与性能的书,起初找到了这本,尽管这本书公布到当初曾经差不多4年了,然而对于想具体理解php7的敌人来说外面所讲述的内容我认为还是很有价值的。并且本书作者的一些观点我也十分认同,就想着心愿能让更多人看到,趁着十一假期有工夫想试着翻译一下本书。本书理论是三本独立的书,但如果独自看这三本都感觉毛病什么,把这三本书合并为一本我感觉就很相辅相成。本书的模块2也就是《高性能 php 7》局部曾经由吕毅老师翻译,自己就不再对本模块进行翻译。如果我的翻译能帮忙到大家,也是我最大到荣幸。 前言PHP 7 在开源社区掀起了一场风暴,它突破了之前版本的速度记录,也从新引起了人们对它的关注。从最基本的意义上讲,外围工程团队曾经对它进行了重大重写,但仍能放弃高度的向后兼容性。PHP是一门开发Web利用的好语言。它实质上是一类服务器端脚本语言,也用于通用编程。PHP 7是最新的版本,提供了次要的向后兼容性冲破,并专一于进步性能和速度。这意味着你能够通过多线程网络服务器,用低成本的硬件和服务器维持网站的高流量。 这条学习之路都涵盖了什么模块1,PHP 7 编程指南,本模块以 PHP 7 为核心,展现了中高级的PHP技术。每个示例都是为了解决像您这样的 PHP 开发人员每天面临的理论问题。其中还介绍了只有在 PHP 7 中才有的,新的编写 PHP 代码的办法。此外,咱们还探讨了向后兼容性中断的问题,并为您提供了大量领导,告诉您何时何地须要批改 PHP 5 代码,以便在 PHP 7 下运行时产生正确的后果。本模块还蕴含了最新的 PHP 7.x 个性。在本模块完结时,您将具备为您的网站和企业提供高效应用程序所需的工具和技能。 模块2,学习 PHP 7 高性能,该模块是 PHP 7 的疾速入门,这将进步您的生产力和编码技能。所波及的概念将使您作为一个PHP程序员,进步你的应用程序的性能规范。咱们将向您介绍 PHP 7 中的新个性,而后介绍 PHP 7 中面向对象编程(OOP)的概念。接下来,咱们将说明如何进步 PHP 7 应用程序的性能和数据库性能。通过这个模块,您将可能应用模块中探讨的各种基准测试工具来进步程序的性能。最初,模块探讨了 PHP 编程中的一些最佳实际,以帮忙你进步代码的品质。 ...

October 4, 2020 · 1 min · jiezi

关于php:tp6-的验证码与session

明天在用tp6的验证码时候,做登录验证。验证码报错,死活提醒验证码失败。通过一些测试才晓得,tp6的session是默认不开启。须要手动勾销正文。 验证码和session的关系。其实他是吧验证码的内容存到了session中,所以要是用验证码必须开启session。 这是他的Captcha类能够看到他在构造函数先注入了一个session类创立一个session的对象保存起来,在当前的session操作就靠这个对象了。 在他的创立验证码的办法中能够看到,他通过session的对象向session中存入了一个'captcha'的key. 在他对验证码进行验证的时候:先去获取啦一下session中贮存的验证码信息。 这就是为什么在应用tp6的验证码的时候必须开启session,在tp6之前的时代,都是依据你php.ini中是否开启啦session。在tp6他本人封装了session的实现,所以须要你手动开启session。切记!!!

September 30, 2020 · 1 min · jiezi

关于php:laravel之无限级分类实现方法

原文地址:https://www.wjcms.net/archive...写在后面的话有限级分类,根本在所有的网站都有波及,所以是必须要把握的知识点,在网上看很多材料文档,要么不粗疏,要么基本不对,要么达不到料想的指标,其实实现的思路和办法非常简单,明天咱们一起来实现一下。 创立模型控制器数据迁徙文件这里间接应用artisan命令进行创立# -a 其实就是all,创立蕴含模型,控制器(资源),数据迁徙文件(工厂模型、seed)php artisan make:model -a Category运行这条命令,就能够创立好资源控制器。 批改数据迁徙文件首先批改数据迁徙文件xxx_create_categories_table. 关上文件,批改外面的up办法,增加相应字段。 Schema::create('categories', function (Blueprint $table) { $table->id(); $table->string('title', 100)->comment('分类名称'); $table->string('name', 100)->comment('分类标识'); $table->string('description', 255)->nullable()->comment('分类形容'); $table->integer('pid')->default(0)->comment('分类id'); $table->integer('level')->default(1)->comment('分类层级'); $table->integer('sort')->default(0)->comment('排序'); $table->integer('status')->default(1)->comment('状态:0-禁用,1-失常'); $table->timestamps(); }); 执行迁徙命令php artisan migrate嵌套模型实现读取//App\Models\Category.phppublic function categories() { return $this->hasMany(self::class, 'pid', 'id')->with('categories'); }控制器调用//app\Http\controllers\CategooryController.php# use模型use App\Models\Category;public function index() { $categories = Category::with('categories')->where('pid', 0)->get(); return view('category.index', compact('categories')); }增加路由在 routes/web.php,咱们增加以下内容: Route::get('category', 'CategoryController@index');blade模版渲染这里应用递归渲染。 在 resources/views/categories.blade.php 文件: <table class="table table-borderless table-data3"> <thead> <tr> <th>编号</th> <th>分类名称</th> <th>分类标识</th> <th>分类形容</th> <th>创立工夫</th> <th>状态</th> <th>操作</th> </tr> </thead> <tbody> @foreach ($categories as $category) <tr class="tr-shadow"> <td>{{ $category->id }}</td> <td>{{ $category->title }}</td> <td> <span class="block-email">{{ $category->name }}</span> </td> <td class="desc">{{ $category->description }}</td> <td>{{ $category->created_at }}</td> <td> <span class="status--process">{{ $category->status }}</span> </td> <td></td> </tr> <tr class="spacer"></tr> @foreach ($category->categories as $childCategory) @include('category.child_category', ['child_category' => $childCategory]) @endforeach @endforeach </tbody> </table>递归局部加载本身模版child_category.blade.php ...

September 29, 2020 · 1 min · jiezi

关于php:????Hyperf-发布-v2013-版本企业级的-PHP-微服务云原生协程框架

更新内容本周次要新增了一些个性,并修复了一些组件的 ????Bug,持续晋升 Hyperf 的稳定性,公布于 2.0.13 版,倡议用户应用以下命令更新此版本。 composer update "hyperf/*" -o间接拜访 官网 hyperf.io 或 文档 hyperf.wiki 查看更新内容 新增#2445 当应用异样捕捉器 WhoopsExceptionHandler 返回 JSON 格式化的数据时,主动增加异样的 Trace 信息。#2580 新增 grpc-client 组件的 metadata 反对。修复#2559 修复应用 socket-io 连贯 socketio-server 时,因为携带 query 信息,导致事件无奈被触发的问题。#2565 修复生成代理类时,因为存在匿名类,导致代理类在没有父类的状况下应用了 parent::class 而报错的问题。#2578 修复当自定义过程抛错后,事件 AfterProcessHandle 无奈被触发的问题。#2582 修复应用 Redis::multi 且在 defer 中应用了其余 Redis 指令后,导致 Redis 同时被两个协程应用而报错的问题。#2589 修复应用了协程格调服务时,AMQP 消费者无奈失常启动的问题。#2590 修复应用了协程格调服务时,Crontab 无奈失常工作的问题。优化#2561 优化敞开 AMQP 连贯失败时的错误信息。#2584 当服务敞开时,不再删除 Nacos 中对应的服务。对于 HyperfHyperf 是基于 Swoole 4.5+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量罕用的组件,性能较传统基于 PHP-FPM 的框架有质的晋升,提供超高性能的同时,也放弃着极其灵便的可扩展性,规范组件均基于 PSR 规范 实现,基于弱小的依赖注入设计,保障了绝大部分组件或类都是 可替换 与 可复用 的。 ...

September 28, 2020 · 1 min · jiezi

关于php:PHP-求解二叉树-二叉搜索树的最近公共祖先

原文链接: [何晓东 博客](https://bignews2.gitee.io/hxd...) 二叉搜寻树的最近公共先人给定一个二叉搜寻树, 找到该树中两个指定节点的最近公共先人。 百度百科中最近公共先人的定义为:“对于有根树 T 的两个结点 p、q,最近公共先人示意为一个结点 x,满足 x 是 p、q 的先人且 x 的深度尽可能大(一个节点也能够是它本人的先人)。” 例如,给定如下二叉搜寻树:  root = [6,2,8,0,4,7,9,null,null,3,5] 示例 1: 输出: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8输入: 6 解释: 节点 2 和节点 8 的最近公共先人是 6。示例 2: 输出: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4输入: 2解释: 节点 2 和节点 4 的最近公共先人是 2, 因为依据定义最近公共先人节点能够为节点自身。起源:力扣(LeetCode) 链接:https://leetcode-cn.com/probl... 解题思路这题让求二叉搜寻树的最近公共先人,而二叉搜寻树的特点就是左子树的所有节点都小于以后节点,右子树的所有节点都大于以后节点,并且每棵子树都具备上述特点,所以这题就好办了,从更节点开始遍历 如果两个节点值都小于根节点,阐明他们都在根节点的左子树上,咱们往左子树上找如果两个节点值都大于根节点,阐明他们都在根节点的右子树上,咱们往右子树上找如果一个节点值大于根节点,一个节点值小于根节点,阐明他们他们一个在根节点的左子树上一个在根节点的右子树上,那么根节点就是他们的最近公共先人节点。作者:sdwwld 链接:https://leetcode-cn.com/probl... 起源:力扣(LeetCode) 代码 /** * Definition for a binary tree node. * class TreeNode { *     public $val = null; *     public $left = null; *     public $right = null; *     function __construct($value) { $this->val = $value; } * } */ class Solution { /** * @param TreeNode $root * @param TreeNode $p * @param TreeNode $q * @return TreeNode */ function lowestCommonAncestor($root, $p, $q) { //如果根节点和p,q的差相乘是负数,阐明这两个差值要么都是负数要么都是正数,也就是说 //他们必定都位于根节点的同一侧,就持续往下找 while (($root->val - $p->val) * ($root->val - $q->val) > 0) $root = $p->val < $root->val ? $root->left : $root->right; //如果相乘的后果是正数,阐明p和q位于根节点的两侧,如果等于0,阐明至多有一个就是根节点 return $root; }}二叉树的最近公共先人给定一个二叉树, 找到该树中两个指定节点的最近公共先人。 百度百科中最近公共先人的定义为:“对于有根树 T 的两个结点 p、q,最近公共先人示意为一个结点 x,满足 x 是 p、q 的先人且 x 的深度尽可能大(一个节点也能够是它本人的先人)。” 例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4] 示例 1: 输出: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1输入: 3解释: 节点 5 和节点 1 的最近公共先人是节点 3。示例 2: 输出: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4输入: 5解释: 节点 5 和节点 4 的最近公共先人是节点 5。因为依据定义最近公共先人节点能够为节点自身。起源:力扣(LeetCode) 链接:https://leetcode-cn.com/probl... 著作权归领扣网络所有。商业转载请分割官网受权,非商业转载请注明出处。 解题思路(递归) O(n) 当咱们用递归去做这个题时不要被题目误导,应该要明确一点 这个函数的性能有三个:给定两个节点 pp 和 qq 如果 pp 和 qq 都存在,则返回它们的公共先人; ...

September 27, 2020 · 1 min · jiezi

关于php:总结PHP笔记

PHP编写代码目录:PHP常量概念介绍PHP数据类型介绍PHP运算形式介绍PHP流程管制语句PHP循环语句构造PHP函数性能介绍PHP数组与数据结构PHP正则符号信息PHP文件系统治理PHP常量概念介绍常量就是短暂不变的值 define (常量名, 常量值)设置常量,应用 define() 函数,函数语法如下: define ( string $name )

September 27, 2020 · 1 min · jiezi

关于php:Laravel-Vapor1

#### Laravel Vapor 明天浅析Laravel的Vapor是什么货色,并形容其作用? Laravel Vapor 是一个由AWS Lambda反对的无服务器,不须要做多余的操作的部署平台。能够Vapor上来治理你的Laravel infrastructure Laravel的根底建设,你会爱上Vapor的无服务器的可拓展性 和 繁难性。 Vapor有些较显著的重要的特色:1、zero-downtime零停机部署 和 复原数据;2、会为Laravvel主动调整好web/queue的根底构造;3、Redis的治理,包含簇群的治理;4、数据库的治理,包含指定工夫点复原数据,治理等等;5、DNS治理。。。。。 临时先更新到此,后续有工夫在继续更新,欢送留言疑难或点评斧正。关注回复 微信受权登陆 ,获取tp微信受权登陆源码 关注回复 MySQL, 获取MySQL性能优化常识 微微关注,将推“心”的不错教训和常识!

September 27, 2020 · 1 min · jiezi

关于php:WordPress中如何给Woocommerce产品页面添加询盘表单标签页

默认Woocommerce产品页面是没有询盘分割表单的,用收费插件Custom Product Tabs for WooCommerce能够给产品页面增加询盘分割表单标签页。 下图是增加完询盘表单标签页的最终成果,这是我在Astra外贸建站教程中的示例。 原文首发于:https://loyseo.com/how-to-add... 教程思路:用插件Custom Product Tabs for WooCommerce增加一个标签页,其中放入用Ninja forms制作的分割表单的短代码(shortcode),而后在增加产品时退出这个标签页即可,具体操作步骤如下: 1.请装置并激活插件Custom Product Tabs for WooCommerce,相干教程:插件装置教程。 2.在网站后盾找到custom product tabs菜单,进入后点击add tab 3.如下图所示,顺次输出题目、名称,而后切换内容框到text模式,从ninja forms的dashboard页面获取表单的shortcode,黏贴到tab content中,最初点击save tab即可。 4.而后咱们去编辑一个示例的产品,给它增加这个询盘标签页。 进入网站后盾,在all products页面任意选一个产品,点击edit按钮进入编辑 5.在编辑产品页面时,滚动页面到下图所示地位,进入custom tabs标签页,点击add a saved tab 6.而后抉择方才增加的标签页即可。 7.如下图所示,标签页曾经胜利加到这个产品里了,咱们在页面右上方找到update按钮,点它公布产品。 8.而后咱们查看一下这个产品,能看到Enquiry询盘标签页曾经胜利退出了。 emm(。•‸•。)这个插件的免费版只能一个个给产品增加询盘标签页,但咱们能够用复制产品性能省点力量,所以不买付费版也是能够的,既然走收费这条路子,那就贯彻到底吧,如果想便当一些,那不如买个Elementor Pro,可能自定义产品页模板,灵便度更高,当然学习难度也比拟大一些。附:学习Elementor的举荐教程 本文原文由LOYSEO 公布,LOYSEO专一于WordPress、Elementor、外贸建站教程。

September 27, 2020 · 1 min · jiezi

关于php:思否最强腾讯T3级PHP高级架构师视频教程

这次公布一波视频教程福利,适宜1-5年进阶人群,因为0根底的可能会听的比拟吃力!!!感兴趣的间接看视频目录即可: 【Laravel框架专题】Laravel框架的生命周期01Laravel目录解说02Laravel应用程序的初始化03Laravel路由利用04Laravel路由解析05Laravel路由参数06Laravel路由到控制器07Laravel路由分组08Laravel服务加载09Laravel路由校验及申请散发10artisan命令应用11Laravel根底控制器12Laravel资源控制器13Laravel多模块下的路由操作14Laravel控制器解析15Laravel视图操作16Laravel-csrf根底应用17Laravel-csrf生成解析18Laravel-csrf-校验19Laravel框架原理剖析20Laravel-IOC容器21Laravel源码剖析22Laravel源码解析23Laravel组件24Laravel路由解析25【MySQL性能优化专题】Mysql事务利用mysql事务回滚Mysql锁机制Mysql事务通过锁实现隔离级别Mysql事务隔离级别实现MySQL事务RU级别-脏读Mysql事务RR级别-幻读问题MySQL事务隔离级别的实现MySQL事务的生命周期数据库数据索引解析索引数据结构红黑树,二叉树原理红黑树,二叉树优缺点详解B-Tree解析hash索引hash索引原理解析千万级数据表用索引疾速查找千万级数据表解决基于索引B+树精准建设高性能索引建设高性能索引分库分表利用场景分库分表前世今生分库分表原理解析分库分表技术解析分库分表的办法垂直拆分事务解析事务的原理程度拆分程度-hash拆分范畴扩容分库分表常见问题数据库解决并发执行计划[RabbitMQ中间件专题]分布式原理异步阶梯式告诉原理RabbitMQ利用Docker虚拟化、疾速部署(云服务器)宿主机生产者、消费者模式写入数据、创立通道创立队列获取队列当中的音讯监听办法提早队列实现原理事务处理分布式缓存【Redis高并发秒杀、分布式锁、令牌桶限流专题】分布式锁利用抢购高并发原理锁机制原理加锁操作Key解析获取锁机制收回数据申请删除锁lua脚本lua原理客户端阻塞写入lua脚本redis优化分布式事务计划redis秒杀原理解析库存超卖解决方案抢购超卖原理乐观锁机制抢购监听乐观锁测试乐观锁实现redis高并发秒杀限流令牌桶算法利用令牌桶算法原理Redis对象援用退出令牌获取令牌模仿申请投递令牌数执行令牌投递令牌限流速率Swoole定时器【PHP高并发微服务专题】PHP高并发微服务搭建计划微服务分布式架构演进什么是服务发现服务注册原理启动consul服务端服务注册及发现利用治理注册核心Services解析服务获取负载平衡分布式缓存分布式服务集群架构分布式服务治理架构目录还没有完结哦,须要这套视频的能够看>>>>home page下次能够整合一个完整版的PHP进阶架构路线图进去给大家参考!!

September 27, 2020 · 1 min · jiezi