关于php:Thinkphp5与Ajax交互

性能简述单击黄色的“cancel”按钮,批改状态status的值toBeUsed为cancel,并将按钮换成红色的“delete”按钮)   其中,前端用jquery实现部分刷新;后端实现对数据库的操作(批改字段status的值为cancel) 前端button标签的html代码 <button type="button" class="btn-warning" onclick="cancelReservation(this,{$eachreservation.reserveId})"> cancel</button>    html文件中的js代码 <script> function cancelReservation(obj,reserveId){ //----------可疏忽---------- $(obj).prev().text("cancel"); $(obj).removeAttr("class"); $(obj).attr("class","btn-danger"); $(obj).removeAttr("onclick"); $(obj).attr("onclick","deleteReservation(this,{$eachreservation.reserveId})"); $(obj).text("delete"); //----------要害是上面这部分---------- //ajax申请服务器批改订单状态 $.ajax({ //间接写办法则默认是以后控制器下的办法 url:'cancelreservation', //url全称 //"{:url('index/Reservation/cancelreservation')}", type:'post', dataType:'json', data: {reserveId:reserveId,status:'cancel'}, success:function(data){ // alert('cancel succcess'); } }); }</script>     后端 <?php/** * Created by PhpStorm. * Date: 2021/3/20 * Time: 19:37 */namespace app\index\controller;use think\Controller;use think\Request;//记得要引入Request,否则参数Request $request无奈应用class Reservation extends Controller{ //勾销订单 public function cancelreservation(Request $request) { if(empty(session('username'))){ $this->error('login please','index/Login/login'); } //助手函数更新数据表中的数据https://www.kancloud.cn/manual/thinkphp5/135178 db('myorder') ->where('reserveId',$request->param('reserveId')) ->update(['status' => $request->param('status')]); //$request->param外面是ajax传过来的键值对的key return "success"; }}     ...

March 21, 2021 · 1 min · jiezi

关于thinkphp5:Thinkphp5-Call-to-a-member-function-render-on-array

大抵报错Call to a member function render() on array背景Thinkphp5分页 起因查询数据库时,没有应用paginate()指定每页显示多少条记录; 解决错误代码(多了select(),少了paginate())   正确代码   留神如果应用了paginate(),就不要应用select(),否则报错 参考文章tp5分页输入报出错Call to a member function render() on array

March 21, 2021 · 1 min · jiezi

关于php:关于PHP流不得不说的那些事

置信不少PHP开发者或多或少都见过相似于 "php://input" 或者 "php://output" 这样的内容,很多人都晓得这两个的作用一个是接管的 POST 申请中的原始 body 内容,另一个其实和 echo 之类的输入一样是进行输入的。当然,咱们的文章内容不会如此的简略,其实相似这样的 php:// 结尾的协定还有好几种,它们独特称为 PHPIO流协定(PHP输出/输入流协定) 。 这种协定有什么用呢?咱们晓得计算机中失常的协定有 http:// ,这是咱们做web开发最相熟的。还有 file:// 示意文件,ftp:// 示意ftp协定,当然,还有一些不太罕用的 zlib:// 、 data:// 、 rar:// ,等等,这些协定PHP都是反对的,而且这些协定都是约定俗成的并且有相应的文件或流类型反对的协定。通过这些协定咱们的程序能够读取、解析这些协定所对应的相干内容。比如说http协定,服务器、客户端浏览器都是因为反对了雷同的http协定标准,所以才可能通过这个协定来进行传输,而传输的内容是什么呢?正是咱们看到的网页或接口文本。而明天咱们的配角 php:// 协定,其实也有另一个别名是 PHP伪协定 。伪协定的起因其实就是这种协定只是PHP本身所反对的并定义的一种协定,而且也仅仅只是 IO 相干操作的一种协定标准。 好了,废话就说到这里,咱们来一个一个的看看 php:// 相干的内容都有哪些。 stdin 输出流while ($line = fopen('php://stdin', 'r')) { $info = fgets($line); echo $info; if ($info == "exit\n") { break; }}while ($info = fgets(STDIN)) { echo $info; if ($info == "exit\n") { break; }}上述代码有什么用呢?置信做过 C 或者 Java 开发的人会更有感觉,stdin 是获取PHP过程脚本的输出,也就是咱们在应用命令行 php xxx.php 运行PHP脚本文件时,获取命令行输出内容的。上述代码就是应用 while 循环始终监听命令行的输出,当你输出内容后进行打印,如果输出的是 exit 就退出循环也就是完结脚本的运行。 ...

March 20, 2021 · 1 min · jiezi

关于php:Laravel框架Mysql连接多库时事物处理需要指定库

如题 其实这不是Laravel框架的起因,网上有查到java程序,应用Mysql多库进行事物解决,也须要指定库。 Laravel框架我的项目中应用了多个库,将业务分库贮存,Model中指定了连贯的库。 protected $connection = 'mysql_bms'; 代码中应用事务处理 DB::beginTransaction();try{ .... DB::commit();}catch (Exception $e){ DB::rollback();}明天测定测试发现事务处理并不失效。 钻研了好长时间才发现,原来是连贯多库的起因,事务处理须要这样写: DB::connection('mysql_bms')->beginTransaction();try{ .... DB::connection('mysql_bms')->commit();}catch (Exception $e){ DB::connection('mysql_bms')->rollback();}程序中只应用该业务单个库的表,所以指定连贯就能够了,那么程序中混合应用多库的表呢? 网上查到java程序的解决方案,应该也适宜PHP,那就是程序应用的表,连贯多库,每个都要进行事务处理 DB::connection('库1')->beginTransaction();DB::connection('库2')->beginTransaction();try{ .... DB::connection('库1')->commit(); DB::connection('库2')->commit();}catch (Exception $e){ DB::connection('库1')->rollback(); DB::connection('库2')->rollback();}没理论利用,有机会在工作中测验一下。

March 19, 2021 · 1 min · jiezi

关于php:不使用正则进行英文数字等相关字符的规则校验

在一些场景中,比如说注册登录的时候,咱们会对用户名做一些限度,比方只能是数字和字母的组合。个别状况下,咱们会应用正则表达式来实现这样的性能,不过,PHP其实曾经帮咱们筹备发了几个函数来解决这样的状况。 ctype_ 相干函数// 数字和字母,不蕴含浮点数, [A-Za-z0-9]if(ctype_alnum($input)){ echo $input, '是英文数字的组合字符!', PHP_EOL;}// 英文字母, [A-Za-z]if(ctype_alpha($input)){ echo $input, '是英文字母!', PHP_EOL;}// 数字字符,不蕴含浮点数、正数(无符号正整数)if(ctype_digit($input)){ echo $input, '是数字字符!', PHP_EOL;}下面三个函数别离分就的就是数字+字母、纯字母、纯数字的三种字符类型的判断。没错,对于这种判断咱们应用的正是 ctype_ 结尾的这些函数。在这其中,惟一须要留神的是 ctype_digit() 进行数字判断时,返回 true 的状况只能是无符号、无小数点的正整数,也就是说正数和小数也是无奈通过这个函数的判断的。咱们在文章的最初还会看一下 ctype_digit() 和 is_numeric() 有什么区别。 当然,ctype_ 相干的函数不止这三个,还有很多,咱们再来看一组。 // 小写字母if(ctype_lower($input)){ echo $input, '是小写字母字符!', PHP_EOL;}// 大写字母if(ctype_upper($input)){ echo $input, '是大写字母字符!', PHP_EOL;}// 所有可打印字符if(ctype_print($input)){ echo $input, '是可打印字符!', PHP_EOL;}// 所有字符都是可见的,除了空格或者格局管制这些不可见的if(ctype_graph($input)){ echo $input, '是可打印字符,除空白字符!', PHP_EOL;}// 不蕴含空白、字母、数字的可打印字符 英文标点符号类if(ctype_punct($input)){ echo $input, '是不蕴含空白、字母、数字的可打印字符!', PHP_EOL;}ctype_lower() 和 ctype_upper() 是判断字符串中的内容是否全都为小写或大写。记住,满足条件的状况是字符串中所有的内容都必须为大写或小写,有一个字母不是的话那就无奈返回 true 。当然,这两个判断外面也都必须是英文字母,不能有数字、空格之类的内容。 ctype_print() 是判断是否是可打印内容。什么是可打印内容呢?就是 echo 、 print 之类的可能输入并且你能在屏幕上看到的内容。 ...

March 19, 2021 · 1 min · jiezi

关于php:Laravel-Eloquent-ORM-的本地作用域

定义: class User extends Model{ public function scopePopular($query) { return $query->where('votes', '>', 100); } public function scopeActive($query) { return $query->where('active', 1); } public function scopeOfType($query, $type) { return $query->where('type', $type); }}应用: $users = App\User::popular()->active()->ofType('admin')->orderBy('created_at')->get();$users = App\User::popular()->orWhere(function (Builder $query) { $query->active();})->get();# 或者$users = App\User::popular()->orWhere->active()->get();

March 18, 2021 · 1 min · jiezi

关于微信支付:微信商户平台证书文件下载及在-easywechat-中配置

简介微信领取接口中,波及资金回滚的接口会应用到API证书,包含退款、撤销接口。 证书下载门路:微信商户平台(pay.weixin.qq.com)-->账户核心-->账户设置-->API平安 。 蕴含以下三个文件: apiclient_cert.p12:蕴含了私钥信息的证书文件,除PHP外的开发均应用此证书文件。windows上能够间接双击导入零碎,导入过程中会提醒输出证书明码,证书明码默认为您的商户ID(如:10010000)。apiclient_cert.pem:从apiclient_cert.p12中导出证书局部的文件,在PHP环境中应用。apiclient_key.pem:从apiclient_key.pem中导出密钥局部的文件,在PHP环境中应用。API证书平安证书文件不能放在web服务器虚拟目录,应放在有拜访权限管制的目录中,避免被别人下载;倡议将证书文件名改为简单且不容易猜想的文件名;商户服务器要做好病毒和木马防护工作,不被非法侵入者窃取证书文件。laravel-wechat中配置WECHAT_PAYMENT_CERT_PATH=/mnt/website/server-end/test/alzhe/apiclient_cert.pemWECHAT_PAYMENT_KEY_PATH=/mnt/website/server-end/test/alzhe/apiclient_key.pem/* * 微信领取 */'payment' => [ 'default' => [ 'sandbox' => env('WECHAT_PAYMENT_SANDBOX', false), 'app_id' => env('WECHAT_PAYMENT_APPID', ''), 'mch_id' => env('WECHAT_PAYMENT_MCH_ID', 'your-mch-id'), 'key' => env('WECHAT_PAYMENT_KEY', 'key-for-signature'), 'cert_path' => env('WECHAT_PAYMENT_CERT_PATH', 'path/to/cert/apiclient_cert.pem'), // XXX: 绝对路径!!!! 'key_path' => env('WECHAT_PAYMENT_KEY_PATH', 'path/to/cert/apiclient_key.pem'), // XXX: 绝对路径!!!! 'notify_url' => 'http://example.com/payments/wechat-notify', // 默认领取后果告诉地址 ], // ...],

March 18, 2021 · 1 min · jiezi

关于php:Laravel-的分页

$per_page = $request->input("per_page", 20);$users = DB::table('users')->paginate(15);# 或者$users = App\User::where('votes', '>', 100)->paginate($per_page);foreach($users as $user){}{ "total": 50, "per_page": 15, "current_page": 1, "last_page": 4, "first_page_url": "http://laravel.app?page=1", "last_page_url": "http://laravel.app?page=4", "next_page_url": "http://laravel.app?page=2", "prev_page_url": null, "path": "http://laravel.app", "from": 1, "to": 15, "data":[ { // 后果对象集 }, { // 后果对象集 } ]}

March 18, 2021 · 1 min · jiezi

关于protobuf:php-使用-protobuf

本文承接上文,带来去protobuf的应用过程 背景:跟公司C++大佬应用protobuf协定进行通信 在跟大佬沟通过程中遇到的最大的问题是相互之间不理解数据格式等纳闷,在这里也是遍及下数据的一个传输过程和字节流等内容,讲的有些零零碎碎,还请包涵 举个例子来说下一个数据格式的问题,在C++中一个整型数据可能是有符号长整型,无符号长整型。在此之外,数据还分16位和32位的区别。 咱们晓得,一个字节占8位,绝对于二进制来说,就是多少位是几个字节 上面进入正题说下protobuf的相干问题 protobuf分为三局部,第一局部是音讯内容长度(head),第二局部是音讯内容类型(type),第三局部是音讯体(body) 因为protobuf传入过去的是二进制的包,所以在php外面须要应用pack(),unpack()这两个函数进行解包,再将数据传到protobuf的解包函数中 举个例子说: A向B发了一个protobuf包,A定义的这个包的第一局部(head)也就是音讯体(body)的长度是4字节也就是32位的有符号长整型,第二局部(type)是2字节也就是16位的有符号短整型,而后第三局部是音讯体(body)那对于php来讲,就须要先对这个包进行解析,也就是解包在php外面,对于加包/解包而言,就是应用pack(),unpack()这两个函数unpack($format,$args)有两个参数,第一个参数是解包的参数,第二个参数是二进制字节流这里参考了这个大佬的文章对二进制包进行了相干格局的解析,具体对于这两个函数的应用移步大佬https://segmentfault.com/a/1190000008305573依照下面的例子就是应用unpack()进行解包,第一个4字节32位的有符号长整型对应到unpack的参数外面是I,即unpack('Ihead',$str)我这里在I前面定义了一个head来承受解析进去的值,在PHP外面打印进去的是一个数组[ 'head' => xxxx,]第二个2字节也就是16位的有符号短整型对应到unpack的参数外面是s,即unpack('Ihead/stype',$str)在这里打印进去的值是[ 'head' => xxxx, 'type' => xxxx,]因为咱们获得是第二个2字节外面的值,所以必须把第一个4字节也带上,或者能够应用substr()把两头的2字节进来来应用unpack也行第三局部的值应用substr取出来即可,因为后面的是6字节的head和type,所以第三局部的body就能够间接应用substr()取出即可substr(6,str)接下来将取出来的值放入protobuf的解析函数外面即可进行正确的读写

March 18, 2021 · 1 min · jiezi

关于php:tp5源码分析第三步设计模式反射机制

设计模式1.单例模式单例模式首先要满足三个条件:1.领有一个构造函数,并且为private 2.领有一个动态成员变量用来放弃类的实例 3.领有一个拜访这个实例的静态方法。单例模式一个类只有一个实例,并提供一个拜访它的全局拜访入口。单例模式是在你想管制实例数目,节俭系统资源的时候应用。例如以下场景中: 1、一个党只能有一个书记。 2、Windows 是多过程多线程的,在操作一个文件的时候,就不可避免地呈现多个过程或线程同时操作一个文件的景象,所以所有文件的解决必须通过惟一的实例来进行。 3、一些设施管理器经常设计为单例模式,比方一个电脑有两台打印机,在输入的时候就要解决不能两台打印机打印同一个文件。长处: 1、在内存里只有一个实例,缩小了内存的开销,尤其是频繁的创立和销毁实例(比方治理学院首页页面缓存)。 2、防止对资源的多重占用(比方写文件操作)。咱们在extend目录下创立一个Single.php文件,以下是Single的内容。咱们在index.php中创立一个getSingle办法这时咱们发现,无论咱们调用多少次Single,new只执行一次。当$instance不存在的时候,就会new一个实例,当存在的时候就间接返回,最多执行一次new。tp5框架用的单例模式在Container.php中,在thinkphp\library\think目录下。 2.注册树模式注册树模式通过将对象实例注册到一颗全局的对象树上,须要的时候从对象树上采摘下来应用。 单例模式解决的是如何在整个我的项目中创立惟一对象实例的问题,工厂模式解决的是如何不通过new建设实例对象的办法。 那么注册树模式想解决什么问题呢? 在思考这个问题前,咱们还是有必要思考下前两种模式目前面临的局限。 首先,单例模式创立惟一对象的过程自身还有一种判断,即判断对象是否存在。存在则返回对象,不存在则创建对象并返回。 每次创立实例对象都要存在这么一层判断。 工厂模式更多思考的是扩大保护的问题。 总的来说,单例模式和工厂模式能够产生更加正当的对象。怎么不便调用这些对象呢?而且在我的项目内如此建设的对象如同散兵游勇一样,不便兼顾治理安顿啊。因 而,注册树模式应运而生。不论你是通过单例模式还是工厂模式还是二者联合生成的对象,都通通给我“插到”注册树上。我用某个对象的时候,间接从注册树上取 一下就好。这和咱们应用全局变量一样的不便实用。 而且注册树模式还为其余模式提供了一种十分好的想法。 接下来咱们进行注册树模式的实战解说,首先咱们在extend目录下创立一个TestRegister.php文件。在这个类外面咱们须要创立个注册树池子,而后创立几个办法,set()办法是把咱们的参数挂载在池子里,有两个参数,一个是$key,一个是$object。set办法的逻辑就是把$object填充到$objects[$key]中去。 get办法须要传入一个$key参数,咱们须要判断$objects[$key]中是否存在,如果不存在,就填入;如果存在就返回。 _unset办法同样传入$key参数,而后把$objects[$key]清空。这就是一个简略的注册树模式的代码。残缺代码是这样的:而后咱们进行应用层逻辑编写,同样在extend目录下创立一个A类,轻易输入点内容。而后咱们在index.php外面创立一个办法,实例化A类,把A类挂在注册池外面。 如果咱们有多个相似于A的类,咱们就能够通过下面register办法一样去把它们挂在连接池外面。 依赖注入依赖注入次要用来缩小代码间的耦合 无效拆散对象和它所需的内部资源,接下来咱们通过代码来对它进行了解。首先咱们在extend目录下创立一个di目录,di目录里创立一个Person类,而后创立一个buy办法。接着再创立一个Car类,在外面创立一个pay办法,而后返回价格。在buy办法外面调用Car类外面的pay办法。而后咱们在入口文件外面创立一个办法,而后调用Person类的buy办法。这样就能够把Car类外面的pay办法调用了。这就是一个简略的依赖注入例子了。其中Person类依赖于Car类,而后Car类注入到Person类中,因为person去买货色,不肯定要买Car,还有其余物品,这时就要把买的物品注入到Person类中去。这个时候问题来了,如果咱们buy的货色是其余物品,而不是Car,那咱们就要对代码进行批改了。批改如下:首先把Person类外面的buy办法批改,之前咱们写的是指定的Car,这个时候咱们就要把指定的Car换成须要购买的物品,代码如下,间接传入对象,而后通过传入的对象进行调用。在入口文件的办法中,咱们间接创立一个须要用到的实例,而后传给Person的办法。这里我new了一个Car类,如果咱们须要的不是Car类,而是其余的类,那咱们就把Car换成须要的类。 反射机制反射机制是在php5.0之后的版本减少的一个个性,这个个性给咱们提供了一个弱小的API,容许咱们在php运行环境中去拜访和应用类、办法、属性、参数和正文,它的性能是十分弱小的,常常用于高扩大的php框架,主动加载插件、生成文档。比如说咱们进行生成php外面的正文等,就是通过php里的反射机制进行的,甚至能够用来扩大php语言。反射机制外面有许多办法,咱们能够依据文档去查看各种办法的用处,文档链接:php反射机制链接。在咱们应用反射机制的时候,首先要对类进行实例化,而后实例化类的反射机制,接下来进行调用这些办法。 容器类简略实战接下来咱们对下面的常识进行综合性的实际,创立一个简略的容器类。咱们进行操作的文件有以下几个文件,首先是容器类Container,而后是Person类和Car类,最初是应用层index.php入口文件。首先是容器类Container代码: <?phpnamespace di;class Container{ /* * 存放数据的容器 * */ public $instances = []; /* * 容器中的对象实例 * */ protected static $instance; private function __construct() { } /* * 获取以后容器的实例(单例) * * */ public static function getInstance(){ if (is_null(static::$instance)){ static::$instance = new static; } return static::$instance; } public function set($key,$value){ $this->instances[$key] = $value; } /* * 获取容器外面的实例 会用到反射机制 * */ public function get($key){ if(!empty($this->instances[$key])) { $key = $this->instances[$key]; } $reflect = new ReflectionClass($key); //获取类的构造函数 $c = $reflect->getConstructor(); if (!$c){ return new $key; } $params = $c->getParameters();// dump($params);exit(); if (empty($params)){ return new $key; }else{ foreach ($params as $param){ $class = $param->getClass(); if (!$class){ }else{ $args[] = $this->get($class->name); } } } return $reflect->newInstanceArgs($args); }}而后是Person代码 ...

March 18, 2021 · 1 min · jiezi

关于javascript:报表和仪表板生成器Stimulsoft-新版本发布了

[Stimulsoft Ultimate]是用于创立报表和仪表板的通用工具集。该产品包含用于WinForms、ASP.NET、.NET Core、JavaScript、WPF、PHP、Java和其余环境的残缺工具集。 无需比拟产品性能,Stimulsoft Ultimate蕴含了共9种产品! 包含Windows Forms,ASP.NET,.NET Core,JavaScript,WPF,PHP,Java等平台。 咱们很快乐地发表公布了新版本的Stimulsoft Reports和Stimulsoft Dashboards 2021.2,现已能够下载。在此版本中,咱们增加了新产品-Stimulsoft Reports.Blazor,新组件Math Formulas,新数据适配器Azure Blob Storage,将仪表板导出为HTML格局,反对PDF中的HTML标签以及许多其余改良。 [慧都网可收费下载Stimulsoft Ultimate v2020.5.2最新版] **对Blazor的反对** 从2021.2版本开始,咱们将引入Blazor平台的报告工具。它是一个跨平台软件,旨在应用Blazor框架集成到应用程序中。咱们的组件反对Razor Pages技术。它们可能同时在服务器端(Blazor服务器)和客户端(Blazor WebAssembly)。您只须要一个Web浏览器。该报告作者是Stimulsoft Reports.Web的一部分。 ** 数学公式 ** 在新版本中,您能够应用非凡的数学公式组件在报告中插入数学公式。所有数学公式都在非凡编辑器中按组排列,其中每个组都能够在独自的选项卡上找到。另外,您能够应用LaTeX语法指定公式。 ** 新的数据适配器-Azure SQL和Azure Blob存储 ** 在此新版本中,咱们增加了新的适配器以从诸如Azure SQL和Azure Blob Storage之类的服务中获取数据。您可能会在独自的Azure上找到它们在“新数据源”窗口中。依据从这些服务取得的数据,您能够创立报告和仪表板。 ** 仪表板定位 ** 从此版本开始,您能够定义查看时仪表板的行为。以前,您能够通过高度和宽度将仪表板拉伸到查看器的整个区域。当初您能够仅将其扩大为整个观看者整个区域的宽度,高度和宽度,或者基本不拉伸它。要指定仪表板的行为,请关上“仪表板设置”窗口并设置“内容对齐”参数的值。双击工作区或从仪表板上下文菜单中选择“设计”命令以调用仪表板设置。 ** 将仪表板导出为HTML ** 在此版本中,咱们增加了将仪表板及其元素转换为HTML文件的性能。在查看器中关上仪表板,转到预览,而后从工具栏上的“保留”菜单或针对特定元素的相似菜单中选择HTML命令。之后,仪表板或其元素将转换为HTML文件。新的变量性能在此版本中,咱们显着优化和改良了报表变量的性能。您能够在全球化字符串中自定义变量元素的全球化。 编辑。并且在启用或从用户申请选项的状况下创立或编辑变量时,能够在查看器中指定此变量的值的排序。此外,能够通过变量的键值和签名来进行排序。此外,在报告中,您能够应用以下模板-VariableName.Label援用变量值的签名。 数字签名证书 在2021.2版本中,当将报告转换为PDF时,咱们间接从导出设置菜单中简化了数字签名证书的抉择。单击“数字签名”字段中的“浏览”按钮,而后抉择一个证书。 仪表板的新性能-总计百分比 咱们增加了新性能仪表板元素的度量类型的总计百分比。您能够应用新性能来显示以后值与该数据字段的值之和的分数。要显示百分比,请将百分比格局利用于应用“总计百分比”性能解决值的字段。 ** 反对PDF中的HTML标签 ** 咱们曾经改良了将报告和仪表板导出到JS和.NET Core组件的PDF文件的算法。以前,HTML标签曾经过解决并转换为PDF文件图像。当初,导出报告和仪表板时,PDF文件中反对HTML标记。 将仪表板导出到SVG 此外,咱们还增加了将仪表板及其元素导出到Dashboards.JS的SVG文件的性能。查看仪表板时,从工具栏上的“保留”菜单或特定我的项目的相似菜单中选择“图像”命令。之后,仪表板或其元素将转换为SVG文件。 ** 将报告导出到PowerPoint ** ...

March 18, 2021 · 1 min · jiezi

关于php:JkdYaf-基于-YAF-SWOOLE-高性能API框架

JKDYAF基于 YAF + SWOOLE 高性能APi框架 我的项目架构Linux + Nginx + PHP7 + Mysql + Swoole + Redis + Yaf + Yac必须php 7.xmysqlyafyacswoole 5.4.xredis为什么要写这个我的项目? 我最开始用laravel写接口,但家喻户晓laravel框架是一个十分重的,性能更是没得说。 必定有人会问,既然谋求性能,为什么不必当初很火的Golang来写,性能杠杠的。其实我最开始也是想用Golang来写的,然而自己对Golang并不相熟,工夫老本太高。 之所以抉择YAF,无可非议就是因为快,简略。并且作为鸟哥的头等粉丝,必定会抉择YAF。 最开始我也是寻找网上的开源我的项目,但并没有找到一个是我称心的。不是没有用上swoole,就是不反对多模块,都有的就是封装了太多货色。配置1. 批改php.ini配置extension=yaf.so[yaf] yaf.environ=productyaf.cache_config=1yaf.use_namespace=1yaf.library="/path/JkdYafLibrary/" //全局类库的目录门路 extension=yac.so[yac];是否开启yac,1示意开启, 0示意敞开yac.enable=1 ;4M能够失去32768个key, 32M能够失去262144个keyyac.keys_memory_size=4M;申请的最大value内存yac.values_memory_size = 64M ;是否压缩数据ssyac.compress_threshold = '-1' ;敞开在cli下应用yacyac.enable_cli = 12. 我的项目app.ini,批改数据库mysql与redis的配置#数据库配置mysql[db]db.host = "x.x.x.x"db.port = xxxxdb.dbname = "xx"db.username = "xx"db.password = "xxx"db.charset = "utf8mb4"#redis配置[redis]redis.host = "x.x.x.x"redis.port = xxxredis.password = null3. 我的项目批改jkdyaf.ini配置ip = "0.0.0.0"port = 9501启动php bin/JkdYaf.php php bin/JkdYaf.php -d //守护过程nginx 配置server { listen xx; //端口 server_name x.x.x.x; //IP或者域名 index index.html index.htm index.php; root /path/JkdYaf/public/; //我的项目门路 location = /favicon.ico { return 404; expires 30d; log_not_found off; access_log off; } location / { if (!-e $request_filename){ proxy_pass http://127.0.0.1:9501; //必须与我的项目conf下的JkdYaf.ini对应 } } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 1h; }}后续将会持续增加罕用性能mysql连接池redis连接池定时工作yaconfyar队列github地址: https://github.com/crytjy/JkdYafgitee地址: https://gitee.com/jkdcry/JkdYaf ...

March 18, 2021 · 1 min · jiezi

关于php:彻底搞明白PHP的中引用的概念

之前咱们其实曾经有过几篇文章讲过援用方面的问题,这次咱们来全面的梳理一下援用在PHP到底是怎么回事,它和C中的指针有什么不同,在应用的时候要留神些什么。 什么是援用?在 PHP 中援用意味着用不同的名字拜访同一个变量内容。它不是C的指针,保留的并不是内存地址,无奈进行指针运算。援用只是符号表的别名。就像 Unix 零碎中的硬链接, Windows 零碎中的快捷方式。 下面是官网手册中的原文,怎么说呢,援用其实和咱们印象中的C外面的指针并不是雷同的概念。指针是针对实在内存的操作,援用是针对指向这个内存的符号表的操作。还是从操作系统的快捷方式来说,快捷方式是能够删的,这就是PHP的援用。而C不仅删了快捷方式,还把原文件也给删了,这就是C的指针操作。 // 援用不是指针$a = 1;$b = &$a;echo $a, '===', $b, PHP_EOL;unset($b);echo $a, '===', $b, PHP_EOL;下面的代码是在PHP中,咱们把$b变量指向$a,作为$a的援用变量。而后删除$b,对$a没有任何影响。 #include <stdio.h>#include <stdlib.h>int main(){ // C 中的指针和援用 int a = 1; int* b = &a; printf("%i\n", a); // 1 free(b); // free b printf("%i\n", a); //get error: *** error for object 0x7fff6350da08: pointer being freed was not allocated return 0;}而C中的援用指针就不行了,咱们把b变量删掉后,再打印a变量就间接报错了。 尽管说PHP的底层也是C写得,但咱们都晓得C中的指针是出了名的变态,没有肯定的功底非常容易出错。所以PHP的开发者没有裸露C的原始指针能力,而是采纳了和Java之类的相似的援用能力。这也是古代语言的个性,不须要咱们过多的关注过于底层的能力,而将更多的工夫放在业务实现上。 援用在数组和对象中的应用如果具备援用的数组被拷贝,其值不会解除援用。对于数组传值给函数也是如此。 $arr1 = ["a", "b"];$t1 = &$arr1[1];$arr2 = $arr1;$arr2[1] = "c";var_dump($arr1);// array(2) {// [0]=>// string(1) "a"// [1]=>// &string(1) "c"// }$arr1 = ["a", "b"];$t1 = &$arr1[1];unset($t1); // unset 掉援用$arr2 = $arr1;$arr2[1] = "c";var_dump($arr1);// array(2) {// [0]=>// string(1) "a"// [1]=>// string(1) "b"// }这个其实挺有意思的,咱们比照这两个例子能够看出一个问题,$t变量指向$arr[1]的援用。$arr2间接=这个$arr1,没有应用援用,而后$arr2批改了$arr2[1]的内容,$arr1相应的内容也产生了扭转,如果unset掉$t变量,则$arr1相应的内容就不会产生扭转。对此,我在文档中找到了上面的解释: ...

March 18, 2021 · 2 min · jiezi

关于docker:设置PHPPHPFPM和NGINX以在Docker上进行本地开发

pascallandau.com 家对于博客BIGQUERY片段集体财务设置PHP,PHP-FPM和NGINX以在Docker上进行本地开发Windows 10下Docker上PHP入门。帕斯卡·兰道(Pascal Landau)发表于2018-07-08 22:00:00 您可能从新来的孩子那里听到了一个叫做“ Docker”的音讯?您是一名PHP开发人员,并且违心参加其中,然而您没有工夫钻研它吗?而后,本教程适宜您!到最初,您应该晓得: 如何在Windows 10计算机上“本地”设置Docker如何从命令行构建和运行容器如何登录容器并浏览它们以获取信息什么是Dockerfile以及如何应用它容器如何相互交谈如何docker-compose将所有货色很好地交融在一起留神:在本教程中,我不仅会走上高兴的路。这意味着我将深入研究与docker并不齐全相干的某些事物(例如,如何找出php-fpm的配置文件位于何处),但这些常识是我了解的重要内容,因为它们使您可能解决当前本人解决问题。 然而,如果您工夫不多,还能够间接跳到tl; dr。 Docker PHP教程的已公布局部设置PHP,PHP-FPM和NGINX以在Docker上进行本地开发 (2018-07-08)应用Xdebug设置PhpStorm以在Docker上进行本地开发 (2018-08-06)为PHP我的项目构建Docker设置 (2019-05-20)这是Docker上(可能)多局部系列的第一局部。第二局部介绍了如何在Docker容器中设置PHP,以便在应用XDebug时与PHPStorm良好配合。 目录介绍 前提条件为什么要应用Docker?从无业游民过渡设置Docker设置PHP cli容器 在PHP容器中装置Xdebug应用Dockerfile长久保留映像更改应用php-fpm和nginx设置Web堆栈 设置nginx设置php-fpm 装置xdebug连贯nginx和php-fpm放在一起:意识docker-composetl;博士介绍前提条件我假如您曾经为Windows装置了Git bash。如果不是,请在执行此操作之前,请参阅设置软件:Git和Git Bash。 为什么要应用Docker?我不会具体介绍Docker是什么以及为什么要应用它,因为 其余 人 曾经 对此进行了宽泛探讨。 对于我来说,我的次要起因是 流浪汉中的符号链接无奈失常工作随着工夫的流逝,虚拟机变得肿且难以治理团队中的设置波及很多工作我想学习Docker很长时间了,因为您据说了很多通常,Docker有点像虚拟机,因而它容许咱们在本人抉择的操作系统(例如Windows)中进行开发,但能够在与生产环境雷同的环境中(例如,在Linux服务器上)运行代码。归功于其外围原理,它使服务拆散变得非常容易(例如,为数据库装备专用服务器),这同样也是生产中应该产生的事件。 从无业游民过渡在Windows上,您能够应用Docker Toolbox (实质上是具备Docker安装程序的VM),也能够应用基于Hyper-V的Windows Docker。本教程仅探讨后者。 请留神:可怜的是,除了Docker(在Windows上)之外,咱们再也没有其余神灵。本机Docker客户端要求激活Hyper-V,这又将导致Virtualbox不再工作。因而,咱们将无奈同时应用Vagrant和Docker。这实际上是我花了很长时间才开始应用Docker的次要起因。 设置Docker首先,下载实用于Windows的Docker (须要Microsoft Windows 10 Professional或Enterprise 64位)。我在本教程中应用的版本是18.03.1-ce-win65。在装置过程中,请不要勾选“应用Windows容器而不是Linux容器”选项,因为咱们打算在linux容器上进行开发(您当前能够随时对其进行更改)。 装置实现后,咱们须要登记Windows并再次登录。Docker应该主动启动。如果没有,应该在桌面上搁置一个“ Docker for Windows”图标。如果尚未激活Hyper-V,则Docker将立刻催促您这样做。 如果您批准,则将激活Hyper-V和容器性能,并启动重新启动。请参阅在Windows 10上装置Hyper-V 以再次将其停用。 留神:VirtualBox之后将进行工作!从VirtualBox界面或通过启动我的一台以前的机器vagrant up失败,并显示谬误音讯 VT-x不可用(VERR_VMX_NO_VMX) 重新启动后,Docker将主动启动,并呈现一个欢送屏幕。 咱们能够疏忽它(敞开窗口)。此外,新图标将增加到系统托盘中。右键单击将显示上下文菜单。 关上选项卡“ Shared Devices”,而后在您要与Docker容器共享的主机上勾选硬盘。 留神:稍后,咱们依然须要为理论的容器定义显式的门路映射,然而必须在此处提供该门路所属的硬盘驱动器。单击“利用”后,将提醒您输出凭据 接下来,关上选项卡“高级”。实际上,您不用更改任何设置,然而,如果您(像我一样)没有C:/设置为最大分区,则可能须要更改“磁盘映像地位”。我把我放在C:Hyper-VVirtual Hard DisksMobyLinuxVM.vhdx。Docker可能须要破费几分钟来解决更改。 Docker“物理地”将容器映像存储在该地位。 祝贺,您的计算机上现已设置了Docker???? ...

March 18, 2021 · 14 min · jiezi

关于protobuf:php安装protobuf

本文采纳的是windows下装置的vagrantbox虚拟机 应用vagrant进行连贯 镜像环境是centos-release-7-9.2009.1.el7.centos.x86_64 1.先去官网下载protobuf文件https://github.com/protocolbu... 抉择一个php语言进行下载![上传中...]() 抉择哪一个都能够,我这里抉择的是tar.gz结尾的 2.将包放入虚拟机内 3.解压tar zxvf protobuf-2.6.1.tar.gz 4.进入解压进去的文件夹内进行装置 比方我这里是解压的2.6.1的包,我解压进去的文件夹就是protobuf-2.6.1 cd protobuf-2.6.1/./configure --prefix=/usr/local/protobufmake && make installexport PATH=/usr/local/protobuf/bin/protoc5.装置完后查看是否装置胜利,呈现如下界面是胜利标识。如果不是,看报错起因,再去针对起因重新安装 protoc --version 6.装置PHP扩大 PHP扩大有两种装置形式 1.解压装置 1.去PHP的PECL网站下载扩大 http://pecl.php.net/package/protobuf 2.将扩大包放入虚拟机 3.解压扩大包 4.进入文件夹,执行装置命令 phpize ./configure --with-php-config=/usr/local/php/bin/php-config make && make install 5.编辑本机php.ini文件 找不到地位的可通过如下命令找到文件 php --ini![image.png](/img/bVcQznH) 6.进入编辑模式,减少如下一行到文件开端 extension=protobuf.so 7.通过以下命令查看是否装置胜利 ![image.png](/img/bVcQznW)2.命令装置 1.间接执行以下命令即可 pecl install protobuf 2.从下面解压装置的第5步持续往下装置扩大至此,装置实现

March 17, 2021 · 1 min · jiezi

关于php:Leetcode-PHP题解D134-14-Longest-Common-Prefix

D134 14. Longest Common Prefix题目链接14. Longest Common Prefix 题目剖析给定一个含有多个单词的数组,返回其中最长公共前缀。 就是说,把所有单词中独特的前几个字母返回。 解题思路咱们须要比照每个单词的同一个地位的字母。如果不一样就完结。如果遇到某一个单词对应地位没有字母时也完结。 尽管说要最长公共前缀,但最长也只能和给定数组中的最短单词一样长。 那么无论从哪个单词开始比都是一样的。 最终代码<?phpclass Solution { /** * @param String[] $strs * @return String */ function longestCommonPrefix($strs) { $first = array_shift($strs); $first = str_split($first); $length = count($first); $prefix = ''; for($i=0;$i<=$length;$i++){ foreach($strs as $str){ if(!isset($str[$i])){ break 2; } if($str[$i] != $first[$i]){ break 2; } } $prefix .=$first[$i]; } return $prefix; }}若感觉本文章对你有用,欢送用爱发电赞助。

March 17, 2021 · 1 min · jiezi

关于php:PHP-再上热搜Swoole-创始人投出反对票质疑-PHP-协程最新提案

3月8日,PHP 社区发动了将 Fiber RFC 增加到 PHP 的投票,这一行动引起了开发者畛域的强烈探讨。 Fiber 作为有栈协程的尝试,对 PHP 的标准化提供了一些新的可能性。依照打算,投票将于 3 月 22 日截止,目前投票的数据状况(截止至3月17日12:00)为 41 票同意、12 票拥护,依据规定,Fiber 很大可能会通过投票从而被增加到 PHP(取得 2/3 的赞成票即可通过)。 但这件事件在开发者畛域引起强烈探讨的导火索,是两位投出了反对票 KOL —— PHP 创始人 Rasmus Lerdorf 和 Swoole 创始人韩天峰@matyhtf。 特地是 Swoole 的创始人韩天峰@matyhtf,作为“利益相干人士”,这一张反对票被解读出了意味深长的含意。 Swoole 与 Fiber 的关系在探讨这张反对票之前,咱们要先来理解一下 Fiber 和 Swoole 两个产品。 依据 Fiber RFC 中的形容,Fiber 次要用于为异步 I/O 实现协程,提供了独立栈调配、函数调用的暂停和复原功,它将作为扩大集成到 PHP 中。 而 Swoole 是一个 PHP 协程框架,为 PHP 提供协程、高性能网络编程反对,并提供了多种通信协议的网络服务器和客户端模块,能够不便疾速地实现 TCP/UDP 服务、高性能 Web、WebSocket 服务、物联网、实时通信、游戏、微服务等,使 PHP 不再局限于传统的 Web 畛域。 ...

March 17, 2021 · 1 min · jiezi

关于php:你的PHP代码好骚啊

$a = 3;$b = 5;if ($a = 3 || $b = 7) { $a++; $b++;}var_dump($a);var_dump($b);等效知识点1: ||的优先级比=高知识点2: 递增/递加运算符不影响布尔值。递加 NULL 值也没有成果,然而递增 NULL 的后果是1 $a = 3;$b = 5;if ( $a = (3 || $b = 7)) { $a++; $b++;}var_dump($a);//(bool)truevar_dump($b);//(int)6

March 16, 2021 · 1 min · jiezi

关于php:你的PHP代码好骚哦

$a = 3;if ($a = 5) { $a++;}var_dump($a); 改良数字放后面 5 == $a如果少写 = 间接报错 $a = 3;if ( 5 == $a ) { $a++;}var_dump($a);

March 16, 2021 · 1 min · jiezi

关于php:Tp5框架源码分析第二步配置文件详解

配置文件品种1.常规配置 外围框架内置的配置文件(thinkphp/convention.php),无需更改2.利用配置 每个利用的全局配置文件(我的项目根目录下的config目录下的文件).3.模块配置 (1)每个模块的配置文件(雷同的配置参数会笼罩利用配置),有局部配置参数模块 是有效的,因为已(2)比方index模块=》 index/config/database.php4.动静配置 次要指在控制器或行为中进行(动静)更改配置,该配置形式只在当次申请无效,因 为不会保留到配置中去。这种配置倡议少用。其中模块配置优先级高于利用配置。 PHP底层ArrayAccess类巧用剖析offsetExists 查看偏移地位是否存在offsetGet 获取一个偏移地位的值offsetSet 设置一个偏移地位的值offsetUnset 删除一个偏移地位的值当咱们应用ArrayAccess的时候咱们必须去实现以上四个办法。接下来咱们来简略实战一下:首先咱们再extend目录下创立一个ObjArray的类文件,而后咱们让这个类实现ArrayAccess接口。然而当咱们实现这个接口的时候,咱们就要把下面四个办法都要去实现了,不然是无奈实现这个接口的。而后咱们在index.php控制器里进行调用,构建一个obj办法,而后在外面调用ObjArray类,当咱们间接打印title的key的时候,你会发现它执行的是offsetGet办法,因为在ObjArray外面曾经定义了title的值。当从新定义一个属性之后,会先执行offsetSet办法,而后执行offsetGet办法,这是须要先在ObjArray中先创立一个属性,而后再获取到这个属性。 Config外围类库1.加载配置文件:load()----loadFile():(1)php yaml格式文件解决 (2)parse解决,又分为不同的文件类型:ini json xml 和设计模式----工厂模式 (3)set2.set3.get4.ArrayAccess:offsetExists offsetGet offsetSet offsetUnsetconfig外面有很多属性和办法,这里就不一一介绍了,能够关上config文件去看一下。咱们接下来从加载配置文件load()说,那什么时候会执行load办法呢,让我一一阐明。在入口文件外面执行的是run()办法,而后在run办法外面会进行初始化init(),在init中,它会加载初始化文件、行为扩大文件、公共文件、中间件,注册服务的容器对象实例和读取配置文件,在读取配置文件的时候,就会调用load()。load办法中的$file是传入的文件,$name是文件的前缀。A:判断$file是否是文件,如果是文件,把它赋值给$filename,如果不是,执行B。B:把$file加上前缀和后缀,而后判断是否是文件,而后赋值给$filename.C:判断文件$filename是否存在,存在的话,调用LoadFile();D:如果$filename不存在,进行判断yaconf配置是否存在此文件,而后创立这个文件。LoadFile($filename,$name)办法首先转换大小写,而后提取文件后缀,接着进行判断是不是php文件,如果是的话,加载$file文件,而后返回set函数,include $file返回的是一个数组。如果不是php文件,判断是不是yaml文件和yaml_parse_file办法是否存在,而后返回set函数,同样yaml_parse_file返回的也是一个数组。对于yaml和set函数,在前面我会具体解说。如果yaml和php都不反对的话,就会走到parse,这个在下面加载配置文件的中央有解释。parse()parse办法的逻辑是这样的,首先判断$type是不是空,如果是空的话,把$config的后缀赋值给$type。而后执行Loader中的factory办法,这是一个工厂模式,它传入的命名空间是think\config\driver,那么它会定位到thinkpgp\library\think\config\driver目录下,它就对应到ini、json和xml文件。而后咱们看factory办法A:进行的是一个三元运算,如果$name存在\\,就返回$name,否则就把$name进行首字母大写解决后增加namespace前面。最终返回的是think\config\driver\Ini;B:判断$name 的类是否存在,如果不存在抛出异样,也就是C,如果存在进入Container容器进行解决,调用incoleClass办法。最终返回的是类的实例。接下来咱们要解说一下set,在讲set之前,咱们说一下Ini。它这里是对配置文件进行解决,最初返回的是一个数组,配置信息的数组。set()set办法传入的是一个数组$name,所以就不进行第一步操作,间接进行第二步,判断是否是数组。而后判断$value是否是空,它传入的是文件,而后执行下一步,判断config[$value]是否是空,当执行第一次的时候,它是空的。而后把$name赋值给$value,而后把它填入到config[$value]中去。当config[value]存在的时候,就把config中和$name反复的去掉,而后赋值给$result,放到内存里。get()办法详解首先判断$name是不是空,或者$name是不是带"."符号,而后把$this->prefix用"."把$name连接起来赋值给$name。$this->prefix的值是App就相当于$name = App.xxx。 接下来判断$name是不是空的,如果是空的就返回在set()办法里存入内存的config。而后判断$name是不是App.,如果是的话,就把前面低点去掉,而后把app传到pull办法外面。pull()办法首先把$name转化为小写,而后判断有没有yaconf,有的话就进行getYaconfName解决$name,而后判断Yaconf中是否存在$yaconfName,存在就进行get解决后赋值给$config,最初进行三元运算,判断是否存在config[$name],存在就把它和$config去重合并,不存在就返回$config,而后判断返回的是否存在。最初返回判断$this->config[$name]是否存在的运算。 在get办法前面的逻辑,如果下面的逻辑不走的话,$name传入是cache,那么此时$name为APP.cache。判断yaconf是否存在,存在就返回Yaconf数据,而后判断$yaconfName是否存在,如果存在就返回Yaconf的配置。最初对$name分隔变成数组,把$name[0]转化为小写。而后把$this->config赋值给$config。

March 16, 2021 · 1 min · jiezi

关于php:PHP7连接Oracle环境搭建及测试代码

1、须要Java库环境:1)instantclient-basic-linux 以及 instantclient-sdk-linux解压到雷同目录即可 // 特地留神百度搜寻出的第一个Oracle中文官网地址就是个坑,无奈实现下载https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html2)编译装置oci8,能够间接通过pecl装置:oci8官网装置领导 pecl install oci8-2.2.0 // 留神php7须要的版本为2.2, php8须要的版本为3.0// 装置过程中须要输出instantclient目录,输出格局如下:instantclient,/path/to/instantclient_19_8,19.8// 装置实现后记得增加oci8.so到php.ini文件extension=oci8.so3)装置pdo_oci反对 // 这个须要从源码装置,依据你本地装置的php版本,去php官网下载对应的源码([github](https://github.com/php/php-src))cd ext/pdo_oci./configure --with-pdo-oci=instantclient,/data1/oracle/instantclient_19_8,19.8// 这个过程可能会遇到短少一些库,装置对应的库即可extension=pdo-oci.so4)PDO连贯测试代码 <?php$tns = "(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))) (CONNECT_DATA =(SERVICE_NAME = databasename) ))";$db_username = "username";$db_password = "password";$db = "oci:dbname=";try { $conn = new PDO($db.$tns.';charset=UTF8',$db_username,$db_password);} catch(PDOException $e){ echo ($e->getMessage());}$sql="SELECT * FROM test";$ret = $conn->query($sql);// 打印谬误print_r($conn->errorInfo());5)连贯Oracle查问中文呈现乱码 // 连贯时减少指定字符集即可new PDO($db.$tns.';charset=UTF8',$db_username,$db_password);

March 16, 2021 · 1 min · jiezi

关于php:PHP中使用DOMDocument来处理HTMLXML文档

其实从PHP5开始,PHP就为咱们提供了一个弱小的解析和生成XML相干操作的类,也就是咱们明天要讲的 DOMDocument 类。不过我预计大部分人在爬取网页时还是会喜爱用正则去解析网页内容,学了明天的这个类下回就能够尝试下应用这个PHP自带的形式来进行解析剖析了。 解析HTML// 解析 HTML$baidu = file_get_contents('https://www.baidu.com');$doc = new DOMDocument();@$doc->loadHTML($baidu);// 百度输入框$inputSearch = $doc->getElementById('kw');var_dump($inputSearch);// object(DOMElement)#2 // ....echo $inputSearch->getAttribute('name'), PHP_EOL; // wd// 获取所有图片的链接$allImageLinks = [];$imgs = $doc->getElementsByTagName('img');foreach($imgs as $img){ $allImageLinks[] = $img->getAttribute('src');}print_r($allImageLinks);// Array// (// [0] => //www.baidu.com/img/baidu_jgylogo3.gif// [1] => //www.baidu.com/img/bd_logo.png// [2] => http://s1.bdstatic.com/r/www/cache/static/global/img/gs_237f015b.gif// )// 利用 parse_url 剖析链接foreach($allImageLinks as $link){ print_r(parse_url($link));}// Array// (// [host] => www.baidu.com// [path] => /img/baidu_jgylogo3.gif// )// Array// (// [host] => www.baidu.com// [path] => /img/bd_logo.png// )// Array// (// [scheme] => http// [host] => s1.bdstatic.com// [path] => /r/www/cache/static/global/img/gs_237f015b.gif// )是不是感觉好清晰,好有面向对象的感觉。就像第一次应用 ORM库 来进行数据库操作一样的感觉。咱们一段一段来看。 ...

March 16, 2021 · 2 min · jiezi

关于php:什么是-N1-问题以及如何解决

N+1 是ORM(对象关系映射)世界中的一个问题。 在介绍什么是N+1问题之前,首先思考一个问题: 假如当初有一个用户表和一个余额表,这两个表通过user_id进行关联。当初有一个需要是查问年龄大于18岁的用户,以及用户各自的余额。 这个问题并不难,但对于老手而言,可能经常会犯的一个谬误就是在循环中进行查问。 $users = User::where("age", ">", 18)->select();foreach($users as $user){ $balance = User::getFieldByUserId($user->user_id, "balance"); $user['balance'] = $balance;}这样做是十分蹩脚的,数据量小还少,在数据量较大的状况下,是十分耗费数据库性能的。 通过Mysql 查问日志,能够看到查问用户表是一次,因为有四个合乎该条件的用户,查问用户表关联的余额表是四次。 N+1问题就是这样产生的:查问主表是一次,查问出N 条记录,依据这N 条记录,查问关联的副(从)表,共须要N 次。所以,应该叫1+N 问题更适合一些。 其实,如果略微理解一点SQL,基本不必这么麻烦,间接应用JOIN 一次就搞定了。 有时候是不是感觉ORM 也挺碍事的。 对于这类问题,ORM 其实为咱们提供了相应的计划,那就是应用with。 with$users = User::where("age", ">", 18) ->with("hasBalance") ->select();hasBalance 是什么呢? 它是在User模型中定义的一个办法: class User extends Model{ // ... public function hasBalance() { return $this->hasOne(Balance::class, "user_id", "user_id"); }}通过这个办法让User 模型与Balance 模型进行一对一关联。 当初再来看一下Mysql 的查问日志: 能够很分明的看到,总查问次数由原来的1+N 变成了当初的1+1。 总结N+1 问题是什么?会造成什么影响?应该如何解决? 执行一次查问获取N 条主数据后,因为关联引起的执行N 次查问从数据带来了不必要的查问开销能够通过框架 ORM 自带的with 去解决

March 15, 2021 · 1 min · jiezi

关于php:在swoole中制作一款仿制laravel的框架

在swoole中制作一款仿造laravel的框架首先须要确定一下思路:我心愿基于swoole的扩大开发的代码在run起来的时候,在接管到ws或是tcp等音讯时,主动路由到某个类上,同时类能够实现加载类的依赖注入性能。目前市面上占据支流的一款框架Laravel,其中有一个依赖注入的性能十分的便捷。个别在通常的框架中拉取Class是这样做的: class a { public $bClassInstance; public function __construct(Class b) { $classInstance = new b(); } public function doSth() { return $this->bClassInstance->xxx(); }}$b = new b();$a = new a($b)$a->doSth();而在Laravel中则能够省略一些实例化的步骤, 间接通过类型束缚的语法在办法的形参上指定某类的命名空间就主动实例化该类进来了。 class a { public function doSth(b $b) { return $b->xxx(); }}想要实现这一点,必须要理解php的反射机制。反射是一个比拟冷门的类,他能够做到:应用namespace实例化一个类、调用类的办法等,利用这一点,能够结构一个主动装箱的类。 <?php/*** * 依赖注入容器,若要执行依赖注入,请确保类蕴含构造函数! */namespace App\Server;class Container{ public $config; public $reflection; public function __construct($namespace) { try { $this->reflection = new \ReflectionClass($namespace); } catch (Exception $e) { echo $namespace; } } public function builderController($fn, $server, $frame, $userMessage) { //从route中失去的control名称 $this->reflection->getMethod($fn)->invoke($this->autoBuilder(), $server, $frame, $userMessage); } public function builderTask($fn, $server, $userMessage) { $this->reflection->getMethod($fn)->invoke($this->autoBuilder(), $server, $userMessage); } public function autoBuilder() { #对构造函数赋值 return $this->batchInstantiation($this->getPrototypeController($this->reflection)#取得字串 ); } protected final function getPrototypeController(\ReflectionClass $object) { $prototype = false; //批量从反射类中获取原型字串 foreach ($object->getConstructor()->getParameters() as $parameter) { $prototype[] = $parameter->getClass()->name; } return $prototype ?: []; } protected final function batchInstantiation(array $prototypeArr) { foreach ($prototypeArr as $item) { $container = new container($item); $insArr[] = $container->autoBuilder();//进行递归注入 } return empty($prototypeArr) ? $this->reflection->newInstance() : $this->reflection->newInstanceArgs($insArr); }}有了这个繁难的装箱类后,能够着手实现类的路由性能,咱们首先创立composer.json,键入如下内容。 ...

March 15, 2021 · 2 min · jiezi

关于php:ubuntu安装event遇到的问题

留神:装置event之前先装置socket扩大 首先我应用命令: sudo apt install update && sudo apt install php7.4-event而后我在官网文档中看到,依照提醒去php扩大网咱们下载一个最新版本的压缩包,并且去扩大的首页看看,而后往下滑,点开装置阐明看看,能够看到装置教程而后先依据第一种试试你会发现报错了,去网上查了以下,我感觉是这个装置形式过期了,有些语法和当初php版本不兼容,所以咱们抉择第二种将压缩包解压,而后进入解压后的文件夹,一步一步依据简称操作,最初在php.ini中退出extension=event.so,重启php7.4-fpm,页面输入echo phpinfo(),发现曾经呈现了然而我并没有这么顺利,刚开始就卡住了,我发现我没有phpize,间接在终端输入 phpize,就提醒我要执行命令 sudo apt install php7.4-dev,我执行后,又出问题了,依据提醒,前两个要装置然而因为一些起因没装置胜利,所以我就用apt去一个一个装置,然而并没有胜利,网上查的一些材料,首先装置aptitude工具 sudo apt-get install aptitude再利用aptitude来装置libssl-dev与libpcre2-dev,要留神的是,执行命令后要看清楚提醒在操作这两个问题解决后还有一个问题解决办法:间接用革除命令将这个革除掉,这个命令会把一些扩大也给删掉最初执行 sudo apt install php7.4-dev就能够胜利了,胜利后将方才卸载调的扩大在重新安装一下,比方:sudo apt install php7.4-gd接下来咱们装置教程装置event扩大就行记住make执行,再执行sudo make install最初的最初,功败垂成

March 15, 2021 · 1 min · jiezi

关于php:在PHP中如何为匿名函数指定this

在之前的文章中,咱们曾经学习过匿名函数的应用,没有看过的小伙伴能够进入传送门先去理解下闭包匿名函数的用法,传送:还不晓得PHP有闭包?那你真OUT了。 对于闭包匿名函数,在JS中有个很典型的问题就是要给它绑定一个 this 作用域。其实这个问题在PHP中也是存在的,比方上面这段代码: $func = function($say){ echo $this->name, ':', $say, PHP_EOL;};$func('good'); // Fatal error: Uncaught Error: Using $this when not in object context 在这个匿名函数中,咱们应用了 \$this->name 来获取以后作用域下的 $name 属性,可是,这个 $this 是谁呢?咱们并没有定义它,所以这里会间接报错。错误信息是:应用了 $this 然而没有对象上下文,也就是说没有指定 $this 援用的作用域。 bindTo() 办法绑定 $this好吧,那么咱们就给它一个作用域,和 JS 一样,应用一个 bindTo() 办法即可。 $func1 = $func->bindTo($lily, 'Lily');// $func1 = $func->bindTo($lily, Lily::class);// $func1 = $func->bindTo($lily, $lily);$func1('cool');这回就能够失常输入了。 bindTo() 办法是复制一个以后的闭包对象,而后给它绑定 $this 作用域和类作用域。其中, $lily 参数是一个 object $newthis 参数,也就是给这个复制进去的匿名函数指定 $this 。而第二个参数 'Lily' 则是绑定一个新的 类作用域 ,它代表一个类型、决定在这个匿名函数中可能调用哪些 公有 和 受爱护 的办法,上例中给出的三种形式都能够用来定义这个参数。如果不给这个参数,那么咱们就不能拜访这个 private 的 $name 属性了: ...

March 15, 2021 · 1 min · jiezi

关于swoole:推荐一个基于swoole开发高性能rpc框架

简介swrpc是一个基于swoole开发的高性能rpc包,swrpc提供了注册发现,链路追踪,中间件等等性能,能够很容易集成到第三方框架,如laravel,yii等等。https://github.com/wuzhc/swrpc 性能反对多过程模式或协程模式反对同步,异步调用反对自定义中间件反对服务端按类提供对外服务反对链路追踪反对注册服务发现反对客户端负载平衡,蕴含随机,权重两种模式反对自定义日志,包协定,序列化形式等等装置php composer.phar require "wuzhc/swprc:~1.0.1" -vvv疾速体验假如咱们User和School两个模块,为了取得用户学校名称,咱们须要在User模块发动rpc申请调用School模块的服务。 School模块<?phpuse Swrpc\LogicService;class SchoolService extends LogicService { public function getUserSchool($userID) { $name = $userID == 123 ? '火星' : '水星'; return $name.'学校'; } }School模块将作为rpc服务端,对外提供服务,启动如下: <?phpuse Swrpc\Server;$basePath = dirname(dirname(__FILE__));require_once $basePath . "/vendor/autoload.php";$options = [ 'enable_coroutine' => true, 'pid_file' => __DIR__ . '/swrpc.pid',];$server = new Server('School_Module', '127.0.0.1', 9501, 1, $options);$server->addService(SchoolService::class); $server->start();将SchoolService增加到server,server会自动检索类中所有可用的public办法。 User模块User模块作为客户端,调用School模块服务如下 <?phpuse Swrpc\Request;use Swrpc\LogicService;use Swrpc\Client;class UserService extends LogicService{ public function getUserSchoolName() { $userID = 123; $module = 'School_Module'; //申请指标模块名称,须要和服务端定义的统一 $client = Client::create($module, '127.0.0.1', 9501); return $client->send(Request::create('SchoolService_getUserSchool', [$userID])); }}//调用echo UserService::factory()->getUserSchoolName();多过程和协程模式多过程或协程模式须要和swoole配置统一,具体参考swoole配置 ...

March 15, 2021 · 2 min · jiezi

关于php:Laravel版本与PHP版本的对应关系及安全修复时间

Laravel版本PHP版本LA平安修复5.5(LTS)7.0.02020 年 8 月 30 日5.67.1.32019 年 2 月 7 日5.77.1.32019 年 9 月 4 日5.87.1.32020 年 2 月 26 日6.x(LTS)7.2.52022 年 9 月 3 日7.x7.2.52021 年 3 月 3 日8.x7.32021 年 9 月 8 日

March 14, 2021 · 1 min · jiezi

关于php:Tp5框架源码分析第一步在框架中新增自定义类

接下来就是在tp5框架上进行批改,新增一个自定义类。 public同级目录新增自定义类首先在public同级目录创立一个test目录,而后在test目录下创立一个ali目录,在ali目录下创立一个Send.php文件,内容如下:而后在index.php中调用这时会报错这是因为咱们新创建的目录没有主动加载进框架中,这时候咱们须要把新创建的目录主动加载一下,在register办法中退出主动加载目录,就能够了。 composer下新增自定义类当在composer目录下创立自定义类,咱们想调用这个类的时候,这时候咱们须要在autoload_static.php中进行主动加载,在$prefixLengthsPsr4和$prefixDirsPsr4中退出你创立的自定义的类,和这两个数组格局一样就能够了。 以上是创立自定义类的援用办法。

March 13, 2021 · 1 min · jiezi

关于php:一起搞懂PHP的错误和异常三

对于谬误与异样的最初一篇文章,咱们来进行一些总结。 PHP中谬误和异样的区别通过后面两篇文章的学习,咱们来间接将谬误和异样摆上来进行比照,看看他们的区别与分割: 谬误的呈现通常是语法或编译运行时谬误,是咱们要防止的。而异样个别与业务逻辑无关,基本上是人为抛出,须要下层来解决谬误有告诉、正告类不会中断程序运行,有严重错误会让程序立刻停止运行。停止运行的程序没有别的形式让程序持续运行。异样能够通过try...catch捕捉,捕捉后的异样能够持续运行,不捕捉的异样间接导致程序停止运行谬误的提醒与php.ini中的配置无关,线上尽量不要显示谬误。谬误也尽量不要带线上。线上的谬误记录到日志中,开发的谬误显示则尽量关上不便开发人员及时调试。PHP7看待谬误的变动PHP7中从新定义了一些谬误的解决形式,让大部分谬误能够进行捕捉。而且减少了一个 Throwable 接口,它能够捕捉大部分的谬误和所有的异样。 也就是说,很多谬误能够通过try...catch进行捕捉了。而无奈捕捉的基本上是正告类的谬误,这些谬误能够通过 set_exception_handler() 进行注册解决。 Error 类不是继承自 Exception 类,所以想全局捕捉的话最好还是应用 Throwable 来进行捕捉,不论是 Error 还是 Exception 都实现了这个接口。 try { test();} catch (Throwable $e) { print_r($e);}echo '未定义test()', PHP_EOL;try { new PDO();} catch (ArgumentCountError $e) { print_r($e);}echo '没给PDO参数', PHP_EOL;function test1() : int{ return 'test';}try { test1();} catch (TypeError $e) { print_r($e);}echo '返回值类型不正确', PHP_EOL;下面的例子中咱们捕捉了在PHP5中被定义为谬误的异样。如果不应用try...catch进行捕捉的话,它们在PHP7中仍然会被当做谬误来看待。咱们来看看 Throwable 上面都有哪些新减少的谬误异样解决类。 Throwable Error ArithmeticError DivisionByZeroErrorAssertionErrorCompileError ParseErrorTypeError ArgumentCountErrorException ...另外咱们还能够通过全局注册来对异样进行全局解决,也就是下面所说的 set_exception_handler() 办法。留神,应用这个全局注册异样解决后,出现异常前面的代码将不执行了。相当于进行了截断,这样的话只能记录一个异样日志。 set_exception_handler(function ($ex) { echo 'set_exception_handler:', PHP_EOL; print_r($ex);});test();echo 'Not Execute...'; // 不会输入了像是除0这种谬误,通过测试发现 DivisionByZeroError 类还是无奈捕捉,这样的谬误如果想捕捉,咱们能够应用 set_error_handler() 获取异样后再抛出谬误。 ...

March 13, 2021 · 1 min · jiezi

关于swoole:Swoole-v464-版本发布Bug-修复版本

v4.6.4 版本次要是一个 Bug 修复版本,没有向下不兼容改变。 新增了 Swoole\Coroutine\Http\get 、Swoole\Coroutine\Http\post 和 Swoole\Coroutine\Http\request 函数,这个操作为了不便 Coroutine\Http\Client 的应用 use function Swoole\Coroutine\go;use function Swoole\Coroutine\run;use function Swoole\Coroutine\Http\get;use function Swoole\Coroutine\Http\post;use function Swoole\Coroutine\Http\request;run(function () { go(function () { $data = get('http://httpbin.org/get?hello=world'); $body = json_decode($data->getBody()); assert($body->headers->Host === 'httpbin.org'); assert($body->args->hello === 'world'); }); go(function () { $random_data = base64_encode(random_bytes(128)); $data = post('http://httpbin.org/post?hello=world', ['random_data' => $random_data]); $body = json_decode($data->getBody()); assert($body->headers->Host === 'httpbin.org'); assert($body->args->hello === 'world'); assert($body->form->random_data === $random_data); });});更新日志上面是残缺的更新日志: 新增 API新增 Coroutine\Http::request, Coroutine\Http::post, Coroutine\Http::get 函数 (swoole/library#97) (@matyhtf)加强反对 ARM 64 构建 (#4057) (@devnexen)反对在 Swoole TCP 服务器中设置 open_http_protocol (#4063) (@matyhtf)反对 ssl 客户端只设置 certificate (91704ac) (@matyhtf)反对 FreeBSD 的 tcp_defer_accept 选项 (#4049) (@devnexen)修复修复应用 Coroutine\Http\Client 时短少代理受权的问题 (edc0552) (@matyhtf)修复 Swoole\Table 的内存调配问题 (3e7770f) (@matyhtf)修复 Coroutine\Http2\Client 并发连贯时的 crash (630536d) (@matyhtf)修复 DTLS 的 enable_ssl_encrypt 问题 (842733b) (@matyhtf)修复 Coroutine\Barrier 内存透露(swoole/library#94) (@Appla) (@FMiS)修复由 CURLOPT_PORT 和 CURLOPT_URL 程序引起的偏移谬误 (swoole/library#96) (@sy-records)修复Table::get($key, $field)当字段类型为 float 时的谬误 (08ea20c) (@matyhtf)修复 Swoole\Table 内存透露 (d78ca8c) (@matyhtf) ...

March 12, 2021 · 1 min · jiezi

关于php:一起搞懂PHP的错误和异常二

上回文章中咱们讲到了谬误是编译和语法运行时会呈现的,它们与逻辑无关,是程序员在码代码时不应该呈现的,也就是说,这些谬误应该是尽量避免带到线上环境的,他们不能通过try...catch捕捉到。而异样则正好相同。 什么是异样?异样,指的是程序运行中呈现的不合乎预期的状况,通常容许它产生,并交由相应的异样解决来进行解决。当然,你也能够抉择疏忽掉异样的解决,然而就像严重错误一样,代码马上会终止运行。异样属于业务逻辑上的谬误,基本上是咱们人为的。 还是先通过一个简略的代码看下异样的抛出和捕捉: function test(){ throw new Exception('This is test Error...');}try { test();} catch (Exception $e) { print_r($e);}咱们通过 throw 来抛出异样,而后在调用办法时将办法包裹在 try...catch 块中来捕捉抛出的异样。这就是异样最根底的构造。 从这里咱们能够看出,异样根本都是通过咱们手动进行抛出的,让内部来进行解决。在PHP外部少数也是在类中会进行异样的抛出,这就是面向对象的错误处理思维了。比如说PDO类: try { // $pdo = new PDO(); // Fatal error: Uncaught ArgumentCountError: PDO::__construct() expects at least 1 parameter, 0 given $pdo = new PDO('');} catch (PDOException $e) { print_r($e); // invalid data source name}留神下面那行正文的代码,没有传参数是谬误,是无奈捕捉的。而传了的参数不对,就是异样了,在PDO类的源码中发现参数不对进行了抛出。交给下层代码也就是咱们这些调用方来进行捕捉。 接下来,咱们看下自定义的异样类和finally语句块的应用。 自定义的异样类都会去继承 Exception 类,这个类能够看做是所有异样的基类。它的构造如下: class Exception{ protected $message = 'Unknown exception'; // 异样信息 private $string; // __toString cache protected $code = 0; // 用户自定义异样代码 protected $file; // 产生异样的文件名 protected $line; // 产生异样的代码行号 private $trace; // backtrace private $previous; // previous exception if nested exception public function __construct($message = null, $code = 0, Exception $previous = null); final private function __clone(); // 不能被复制,如果clone异样类将间接产生致命谬误 final public function getMessage(); // 返回异样信息 final public function getCode(); // 返回异样代码 final public function getFile(); // 返回产生异样的文件名 final public function getLine(); // 返回产生异样的代码行号 final public function getTrace(); // backtrace() 数组 final public function getPrevious(); // 之前的 exception final public function getTraceAsString(); // 已格成化成字符串的 getTrace() 信息 // Overrideable public function __toString(); // 可输入的字符串}通过上述类定义,咱们能够看出,咱们能重写 构造函数 和 __toString() 办法,也能应用一些受爱护的属性。那么咱们就来定义一个自定义的异样类吧。 ...

March 12, 2021 · 2 min · jiezi

关于php:基于聚合数据的身份证实名认证API接口调用示例PHP版

本文转自SDK社区:https://www.sdk.cn/details/djgylbOGwQoybxAN1Z一、申请接口 通过https://www.juhe.cn/docs/api/id/103自助申请开明接口,获取API申请KEY。 二、用示例代码PHP //如需申请加密接口,加密形式请参考 https://www.sdk.cn/details/d5... $apiurl="http://op.juhe.cn/idcard/query";//申请地址$key = "";//32位的KEY$realname = "";//实在姓名$idcard="";//身份证号码$params=compact('key','realname','idcard');//组合申请参数$content=juhecurl($apiurl,$params);//获取接口返回内容json字符串$result = json_decode($content,true);//解析成数组if($result){if($result['error_code']=='0'){ if($result['result']['res'] == '1'){ echo "身份证号码和实在姓名统一"; }else{ echo "身份证号码和实在姓名不统一"; } #print_r($result);}else{ echo $result['error_code'].":".$result['reason'];}}else{echo "申请失败";} //网络申请办法function juhecurl($url,$params=false,$ispost=0){ $httpInfo = array(); $ch = curl_init(); curl_setopt( $ch, CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1 ); curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT , 3); curl_setopt( $ch, CURLOPT_TIMEOUT , 8); curl_setopt( $ch, CURLOPT_RETURNTRANSFER , true ); if ($params) { if (is_array($params)) { $paramsString = http_build_query($params); } else { $paramsString = $params; } } else { $paramsString = ""; } if( $ispost ) { curl_setopt( $ch , CURLOPT_POST , true ); curl_setopt( $ch , CURLOPT_POSTFIELDS , $paramsString); curl_setopt( $ch , CURLOPT_URL , $url ); } else { if($paramsString ){ curl_setopt( $ch , CURLOPT_URL , $url.'?'.$paramsString); }else{ curl_setopt( $ch , CURLOPT_URL , $url); } } $response = curl_exec( $ch ); if ($response === FALSE) { //echo "cURL Error: " . curl_error($ch); return false; } $httpCode = curl_getinfo( $ch , CURLINFO_HTTP_CODE ); $httpInfo = array_merge( $httpInfo , curl_getinfo( $ch ) ); curl_close( $ch ); return $response; }

March 11, 2021 · 1 min · jiezi

关于php:全国彩票开奖结果查询PHP版

一、简略阐明应用聚合数据提供的收费全国彩票开奖后果查问接口服务,目前反对双色球、大乐透、七乐彩、七星彩、福彩3D、排列3、排列5,数据来源于网络公开,开奖后果获取可能会有肯定的延时。官网接口文档地址:https://www.juhe.cn/docs/api/id/300,注册申请即可取得接口申请Key。 二、PHP调用代码参考Lottery.class.php /*** Class Lottery*/class Lottery {//接口提交地址private static $submitUrl = 'http://apis.juhe.cn/lottery';//申请的彩票接口申请Keyprivate static $appkey = '**********';/** * 获取反对彩票列表 */public static function getLotteryTypes(){ $urlPath = '/types'; $params = [ 'key' => self::$appkey ]; $paramsString = http_build_query($params); $requestUrl = self::$submitUrl.$urlPath; $content = self::juheCurl($requestUrl, $paramsString); $result = json_decode($content, true); if ($result) { return $result; } else { return false; }}/** * 获取彩票某一期开奖后果,默认最新一期 * @param $lotteryId 彩票ID * @param string $lotteryNo 彩票期数,默认最新一期 * @return bool|mixed */public static function getLotteryRes($lotteryId, $lotteryNo = ""){ $urlPath = '/query'; $params = [ 'key' => self::$appkey, 'lottery_id' => $lotteryId, 'lottery_no' => $lotteryNo ]; $paramsString = http_build_query($params); $requestUrl = self::$submitUrl.$urlPath; $content = self::juheCurl($requestUrl, $paramsString); $result = json_decode($content, true); if ($result) { return $result; } else { return false; }}/** * 获取历史开奖后果 * @param $lotteryId 彩票ID * @param int $pageSize 每页返回条数 * @param int $page 当前页数 */public static function getLotteryHistroyRes($lotteryId, $pageSize = 10, $page = 1){ $urlPath = '/history'; $params = [ 'key' => self::$appkey, 'lottery_id' => $lotteryId, 'page_size' => $pageSize, 'page' => $page, ]; $paramsString = http_build_query($params); $requestUrl = self::$submitUrl.$urlPath; $content = self::juheCurl($requestUrl, $paramsString); $result = json_decode($content, true); if ($result) { return $result; } else { return false; }}/** * 中奖计算器/判断号码是否中奖 * @param $lotteryId 彩票ID * @param $lotteryRes 投注号码 * @param string $lotteryNo 投注期号,默认最新一期 * @return bool|mixed */public static function getBonus($lotteryId, $lotteryRes, $lotteryNo=''){ $urlPath = '/bonus'; $params = [ 'key' => self::$appkey, 'lottery_id' => $lotteryId, 'lottery_res' => $lotteryRes, 'lottery_no' => $lotteryNo, ]; $paramsString = http_build_query($params); $requestUrl = self::$submitUrl.$urlPath; $content = self::juheCurl($requestUrl, $paramsString); $result = json_decode($content, true); if ($result) { return $result; } else { return false; }}/** * 发动接口网络申请 * @param $url * @param bool $params * @param int $ispost * @return bool|mixed */public static function juheCurl($url, $params = false, $ispost = 0){ $httpInfo = array(); $ch = curl_init(); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22'); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($ch, CURLOPT_TIMEOUT, 12); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); if ($ispost) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $params); curl_setopt($ch, CURLOPT_URL, $url); } else { if ($params) { curl_setopt($ch, CURLOPT_URL, $url.'?'.$params); } else { curl_setopt($ch, CURLOPT_URL, $url); } } $response = curl_exec($ch); if ($response === FALSE) { return false; } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $httpInfo = array_merge($httpInfo, curl_getinfo($ch)); curl_close($ch); return $response;}}index.php ...

March 11, 2021 · 2 min · jiezi

关于php:php和js不转义字符

php 和 js 有时候会帮咱们主动转义字符,有的时候这很不便,然而有的时候咱们并不需要本义,在这里记录一下不转义字符的办法 1.php stripslashes()<?phpecho stripslashes("Hello World!");?>2. js在这里我是采纳的一个正则表达式替换转义字符的办法。 let preDeviceUrl = "&123";preDeviceUrl.replace(/&amp;/g,"&");因为 "&"字符会本义成 "&" ,所有咱们就给替换回原来的,g的话是全副都替换,否则只替换一次。应该有更简略不便的办法,然而这个解决了我当初的问题,所以记录分享一下。

March 11, 2021 · 1 min · jiezi

关于php:一起搞懂PHP的错误和异常一

在PHP的学习过程中,咱们会接触到两个概念,一个是谬误,一个是异样。啥玩意?他们不是一个货色嘛?如果接触过Java、C#之类的纯面向对象语言的同学,可能对异样是没有什么问题,毕竟所有的问题都能够try...catch来解决。然而像PHP这种从面向过程倒退到面向对象的语言来说,谬误和异样就是两个齐全不同的货色了。 咱们将用一系列的文章来彻底的搞懂PHP中的谬误和异样到底是怎么回事,有哪些解决这些谬误和异样的机制,咱们应该如何看待它们。 什么是谬误?谬误,个别是由PHP自身的因素所导致的问题,谬误的语法、环境的配置不当等都会引起谬误。谬误和php.ini文件当中的error_reporting参数有间接的关系。置信大家都配过这个参数。个别会把它配置为 E_ALL & ~E_NOTICE 。这是什么意思呢?咱们先来看看PHP中有哪些谬误类型: Fatal Error:致命谬误(脚本终止运行) E_ERROR // 致命的运行谬误,谬误无奈复原,暂停执行脚本E_CORE_ERROR // PHP启动时初始化过程中的致命谬误E_COMPILE_ERROR // 编译时致命性错,就像由Zend脚本引擎生成了一个E_ERRORE_USER_ERROR // 自定义谬误音讯。像用PHP函数trigger_error(谬误类型设置为:E_USER_ERROR)Parse Error:编译时解析谬误,语法错误(脚本终止运行) E_PARSE //编译时的语法解析谬误Warning Error:正告谬误(仅给出提示信息,脚本不终止运行) E_WARNING // 运行时正告 (非致命谬误)。E_CORE_WARNING // PHP初始化启动过程中产生的正告 (非致命谬误) 。E_COMPILE_WARNING // 编译正告E_USER_WARNING // 用户产生的正告信息Notice Error:告诉谬误(仅给出告诉信息,脚本不终止运行) E_NOTICE // 运行时告诉。示意脚本遇到可能会体现为谬误的状况.E_USER_NOTICE // 用户产生的告诉信息。在配置文件中的 E_ALL & ~E_NOTICE 就是显示所有谬误但告诉谬误类谬误除外的意思。当然,咱们在代码中也能够手动的扭转这种错误信息的告诉。 error_reporting(E_ALL);通过这行代码,咱们就让以后文件代码中的谬误全副显示进去了。Notice 和 Warning 类型的谬误是不会中断代码运行的,他们是告诉和报警,并不是致命的谬误。而其余类型的谬误则会中断代码的执行。 $a = 100 / 0; // Warning: Division by zeroecho $f; // Notice: Undefined variable: f test(); // Fatal error: Uncaught Error: Call to undefined function test()echo 1;上述代码中别离是Warning的除0谬误正告和echo $f;的未定义变量提醒,这两行代码都是能够在报错后能够持续向下运行的。而未定义的办法则是Fatal级别的致命谬误了。所以最初那个1也不会输入了。 ...

March 11, 2021 · 1 min · jiezi

关于php:学习PHP生成器的使用

什么是生成器?听着高大上的名字,感觉像是发明什么货色的一个性能,实际上,生成器是一个用于迭代的迭代器。它提供了一种更容易的形式来实现简略的对象迭代,相比拟定义类实现Iterator接口的形式,性能开销和复杂性大大降低。 说了半天不如间接看看代码更直观。 function test1(){ for ($i = 0; $i < 3; $i++) { yield $i + 1; } yield 1000; yield 1001;}foreach (test1() as $t) { echo $t, PHP_EOL;}// 1// 2// 3// 1000// 1001就是这么简略的一段代码。首先,生成器必须在办法中并应用 yield 关键字;其次,每一个 yield 能够看作是一次 return ;最初,内部循环时,一次循环取一个 yield 的返回值。在这个例子,循环三次返回了1、2、3这三个数字。而后在循环内部又写了两行 yield 别离输入了1000和1001。因而,内部的 foreach 一共循环输入了五次。 很神奇吧,明明是一个办法,为什么可能循环它而且还是很奇怪的一种返回循环体的格局。咱们间接打印这个 test() 办法看看打印的是什么: // 是一个生成器对象var_dump(test1());// Generator Object// (// )当应用了 yield 进行内容返回后,返回的是一个 Generator 对象。这个对象就叫作生成器对象,它不能间接被 new 实例化,只能通过生成器函数这种形式返回。这个类蕴含 current() 、 key() 等办法,而且最次要的这个类实现了 Iterator 接口,所以,它就是一个非凡的迭代器类。 Generator implements Iterator { /* 办法 */ public current ( void ) : mixed public key ( void ) : mixed public next ( void ) : void public rewind ( void ) : void public send ( mixed $value ) : mixed public throw ( Exception $exception ) : void public valid ( void ) : bool public __wakeup ( void ) : void}生成器有什么用?搞了半天不就是个迭代器嘛?搞这么麻烦干嘛,间接用迭代器或者在办法中间接返回一个数组不就好了吗?没错,失常状况下真的没有这么麻烦,然而如果是在数据量特地大的状况下,这个生成器就能施展它的弱小威力了。生成器最最弱小的局部就在于,它不须要一个数组或者任何的数据结构来保留这一系列数据。每次迭代都是代码执行到 yield 时动静返回的。因而,生成器可能极大的节约内存。 ...

March 10, 2021 · 3 min · jiezi

关于php:PHP-跨页传递失败如何解决转

这篇文章次要介绍了PHP SESSION跨页面传递失败解决方案,文中通过示例代码介绍的十分具体,对大家的学习或者工作具备肯定的参考学习价值,须要的敌人能够参考下 明天想用一个session来实现用户登录判断,也算是对之前session的探索,查了下材料session的运行机制如下: session是服务器端的一种会话机制,当客户端的申请服务器创立一个session时,服务器会先检测该申请外面是否蕴含一个惟一的 sessionID,如果是,阐明服务器曾经为该用户创立过session,只有依照该sesionID检索出该用户的session供用户应用,如果没 有sessionID,服务器会为该用户新建一个带有惟一示意服sessionID的session。创立实现后,该sessionID会被服务器返回给 客户端,保留到客户端本地。 个别保留该session ID的机制是Cookie,然而因为Cookies能够被人为禁止,这就得保障Cookies被禁止之后,仍旧能够通过session进行会话,个别是通过url重写进行,表 现模式为www.fckfs.com ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,另一种是作为查问 字符串附加在URL前面,表现形式为http://..... /xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 这两种形式对于用户来说是没有区别的,只是服务器在解析的时候解决的形式不同,采纳第一种形式也有利于把session id的信息和失常程序参数辨别开来。 为了在整个交互过程中始终保持状态,就必须在每个客户端可能申请的门路前面都蕴含这个session id。 另外是对于session生效的误区: 在议论session机制的时候,经常听到这样一种误会“只有敞开浏览器,session就隐没了”。其实能够设想一下会员卡的例子,除非顾客被动 对店家提出销卡,否则店家相对不会轻易删除顾客的材料。 对session来说也是一样的,除非程序告诉服务器删除一个session,否则服务器会始终保留,程序个别都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会被动在敞开之前告诉服务器它将要敞开,因而服务器基本不会有机会晓得浏览器曾经敞开,之所以会有这种错觉,是大部分session机制都应用会话cookie来保留session id,而敞开浏览器后这个 session id就隐没了,再次连贯服务器时也就无奈找到原来的session。如果服务器设置的cookie被保留到硬盘上,或者应用某种伎俩改写浏览器收回的 HTTP申请头,把原来的session id发送给服务器,则再次关上浏览器依然可能找到原来的session。 恰好是因为敞开浏览器不会导致session被删除,迫使服务器为seesion设置了一个生效工夫,当间隔客户端上一次应用session的工夫超过这个生效工夫时,服务器就能够认为客户端曾经进行了流动,才会把session删除以节俭存储空间。 好了,废话说了一大堆,说session失落的解决办法吧: 1、session_start();应该尽量搁置到页面的顶部; 2、如果php.ini外面没有配置 session Autostart的话,每次会话之前,都得手动开启session:session_start(); 3、session是php外面的超全局变量,跟$_GET,$_POST,$_SERVER一样,所以应用的时候必须大写:$_SESSION['username']=$username; 4、跨页面传递示例:a.php页面传递$_SESSION['username']到b.php: a.php: session_start(); $username=$_POST['username']; $_SESSION['username']=$username; ?> b.php: session_start(); echo $_SESSION['username']; ?> 转自 脚本之家

March 10, 2021 · 1 min · jiezi

关于php:解决在Apple-Silicon-M1安装php-MongoDB扩展失败

本文是 https://stackoverflow.com/que... 的中文翻译版 在MacBook Pro上曾经装置了php7.4 $php -vPHP 7.4.15 (cli) (built: Feb 26 2021 09:28:23) ( NTS )Copyright (c) The PHP GroupZend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.15, Copyright (c), by Zend Technologies尝试通过以下命令来装置MongoDB扩大 $sudo pecl install mongodb然而装置失败了 mp/pear/temp/mongodb/src/contrib/ -DHAVE_CONFIG_H -g -O2 -c /private/tmp/pear/temp/mongodb/php_phongo.c -fno-common -DPIC -o .libs/php_phongo.oIn file included from /private/tmp/pear/temp/mongodb/php_phongo.c:29:In file included from /opt/homebrew/Cellar/php@7.4/7.4.15_1/include/php/ext/spl/spl_iterators.h:24:/opt/homebrew/Cellar/php@7.4/7.4.15_1/include/php/ext/pcre/php_pcre.h:25:10: fatal error: 'pcre2.h' file not found#include "pcre2.h" ^~~~~~~~~1 error generated.make: *** [php_phongo.lo] Error 1ERROR: `make' failed还尝试了 ...

March 9, 2021 · 2 min · jiezi

关于php:Websocket很美很强悍请驾驭它

讲到HTTPS就不得不说http,理解更多请参考文章《了解HTTP协定》 HTTP即超文本传输协定(Hypertext Transfer Protocol)是一个客户端/服务器的模型,构建在TCP/IP之上。Hypertext超文本就是HTML,网络上数据有文字、图片、视频、音频等,把这些不同类型的数据依照主观需要有序串联起来,就要用到HTML,这些数据在网络上跑来跑去就要用到http。 简略了解就是,html负责组织内容,http负责传递这些内容。然而,http也有本人的有余,就是不平安。 http协定不平安的根本原因有三: 一、数据没有加密: HTTP自身传递的是明文,不会加密这些信息,只有攻击者可能获取这些明文,用户的隐衷就齐全裸露了。HTTP是基于TCP/IP的,TCP/IP的特点也决定了HTTP数据很容易被截获,网络传输过程中,路由策略决定HTTP数据会通过很多节点设施,节点很轻松就能截获明文数据,因为数据没有加密,很容易了解其含意。 二、无奈验证身份 在HTTP利用中,客户端和服务器并不能确认对方的身份,在HTTP规范中,没有校验对端身份的规范。对于服务器来说,它接管的HTTP申请格局只有正确,就发送响应信息。对于客户端来说同样如此,它连贯的是www.kantianshu.cn机,但因为有两头节点的存在,最终连贯的可能是www.yocansoft.com主机,但对于客户端来说,它无奈校验服务器的身份。 三、数据易篡改 HTTP数据在传输过程中,会通过很多节点,这些节点都能够批改原始数据,而对于客户端和服务器来说,没有任何技术来确保接管的数据就是发送者发送的原始数据。 http让数据传输变得非常容易,负责了WEB服务器传输数据到客户端传输数据。http的不平安属性是能够解决的,就是应用https。 https介绍 HTTPS(全称:httpover ssl,Hyper Text Transfer Protocol over Secure Socket Layer),HTTPS简略来说就是http+ssl,基于安全套接字层的超文本传输协定。它是以平安为指标的HTTP通道,简略讲就是HTTP的平安版。即在HTTP下退出了SSL子层,HTTPS的平安根底是SSL。 SSL会应用各种对称加密算法、非对称加密算法来加密传送数据。 http变更为https,已是大势所趋。WEB利用中,没有SSL证书,就会被浏览器认定为不平安的网站。有些浏览器会禁止间接拜访网站,会跳进去一条红色正告,先恶心你一下,比方谷歌浏览器。有些平台利用会间接回绝应用http,微信小程序开发,ios零碎上的app开发等等。

March 9, 2021 · 1 min · jiezi

关于php:彻底搞明白PHP的中引用的概念

之前咱们其实曾经有过几篇文章讲过援用方面的问题,这次咱们来全面的梳理一下援用在PHP到底是怎么回事,它和C中的指针有什么不同,在应用的时候要留神些什么。 什么是援用?在 PHP 中援用意味着用不同的名字拜访同一个变量内容。它不是C的指针,保留的并不是内存地址,无奈进行指针运算。援用只是符号表的别名。就像 Unix 零碎中的硬链接, Windows 零碎中的快捷方式。 下面是官网手册中的原文,怎么说呢,援用其实和咱们印象中的C外面的指针并不是雷同的概念。指针是针对实在内存的操作,援用是针对指向这个内存的符号表的操作。还是从操作系统的快捷方式来说,快捷方式是能够删的,这就是PHP的援用。而C不仅删了快捷方式,还把原文件也给删了,这就是C的指针操作。 // 援用不是指针$a = 1;$b = &$a;echo $a, '===', $b, PHP_EOL;unset($b);echo $a, '===', $b, PHP_EOL;下面的代码是在PHP中,咱们把$b变量指向$a,作为$a的援用变量。而后删除$b,对$a没有任何影响。 #include <stdio.h>#include <stdlib.h>int main(){ // C 中的指针和援用 int a = 1; int* b = &a; printf("%i\n", a); // 1 free(b); // free b printf("%i\n", a); //get error: *** error for object 0x7fff6350da08: pointer being freed was not allocated return 0;}而C中的援用指针就不行了,咱们把b变量删掉后,再打印a变量就间接报错了。 尽管说PHP的底层也是C写得,但咱们都晓得C中的指针是出了名的变态,没有肯定的功底非常容易出错。所以PHP的开发者没有裸露C的原始指针能力,而是采纳了和Java之类的相似的援用能力。这也是古代语言的个性,不须要咱们过多的关注过于底层的能力,而将更多的工夫放在业务实现上。 援用在数组和对象中的应用如果具备援用的数组被拷贝,其值不会解除援用。对于数组传值给函数也是如此。 $arr1 = ["a", "b"];$t1 = &$arr1[1];$arr2 = $arr1;$arr2[1] = "c";var_dump($arr1);// array(2) {// [0]=>// string(1) "a"// [1]=>// &string(1) "c"// }$arr1 = ["a", "b"];$t1 = &$arr1[1];unset($t1); // unset 掉援用$arr2 = $arr1;$arr2[1] = "c";var_dump($arr1);// array(2) {// [0]=>// string(1) "a"// [1]=>// string(1) "b"// }这个其实挺有意思的,咱们比照这两个例子能够看出一个问题,$t变量指向$arr[1]的援用。$arr2间接=这个$arr1,没有应用援用,而后$arr2批改了$arr2[1]的内容,$arr1相应的内容也产生了扭转,如果unset掉$t变量,则$arr1相应的内容就不会产生扭转。对此,我在文档中找到了上面的解释: ...

March 9, 2021 · 2 min · jiezi

关于php:Macbook-m1-Big-Sur-安装php71-xdebug-折腾记

想当然的进来就是一行 $sudo pecl install xdebugpecl/xdebug requires PHP (version >= 7.2.0, version <= 8.0.99), installed version is 7.1.33No valid packages foundinstall failed查阅了一下xdebug的下载页,默认装置的xdebug3曾经不反对php7.1了。php7.1只配装置xdebug2,依据在下载页查到的最初一个反对php7.1的版本是2.9.8 $sudo pecl install xdebug-2.9.8 downloading xdebug-2.9.8.tgz ...Starting to download xdebug-2.9.8.tgz (245,293 bytes)...................................................done: 245,293 bytesBuild process completed successfullyInstalling '/opt/homebrew/Cellar/php@7.1/7.1.33/pecl/20160303/xdebug.so'install ok: channel://pecl.php.net/xdebug-2.9.8Extension xdebug enabled in php.ini检查一下是否装置胜利 $php -vPHP 7.1.33 (cli) (built: Dec 25 2020 07:27:59) ( NTS )Copyright (c) 1997-2018 The PHP GroupZend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies with Xdebug v2.9.8, Copyright (c) 2002-2020, by Derick Rethans with Zend OPcache v7.1.33, Copyright (c) 1999-2018, by Zend Technologies $php -m | grep debugxdebugXdebug

March 8, 2021 · 1 min · jiezi

关于php:关于Laravel框架中Guard的底层实现

1. 什么是Guard在Laravel/Lumen框架中,用户的登录/注册的认证根本都曾经封装好了,开箱即用。而登录/注册认证的外围就是: 用户的注册信息存入数据库(注销)从数据库中读取数据和用户输出的比照(认证)上述两步是登录/注册的根本,能够看到都会波及到数据库的操作,这两步框架底层曾经帮咱们做好了,而且思考到了很多状况,比方用户认证的数据表不是user表而是admin_user,认证字段是phone而不是email,等等一些问题都是Guard所要解决的,通过Guard能够指定应用哪个数据表什么字段等,Guard能非常灵活的构建一套本人的认证体系。 艰深地讲,就是这样:Guard就像是小区的门卫大叔,冷酷无情,不认人只认注销信息。进小区之前大叔须要先查看你的身份,验证不通过大叔就不让你进去。如果是走路/骑车进去,大叔1须要查看你的门禁卡,他拿出记录了小区所有业主门禁卡信息的本子查看你这个门禁卡信息有没有在这个本子上;如果你开车进去,大叔2就从记录了所有业主车牌号的本子中查看你的车牌号,所以新业次要小区了须要告知门卫大叔们你的门禁卡信息或者车牌号,要不然大叔2不让你进。如果是物业管理员要进小区,门卫大叔3也只认注销信息,管理员出示他的管理员门禁卡,门卫大叔就会查看记录了管理员门禁卡信息的本子。 下面讲的对应了框架中的多用户认证: 走路/骑车的人 -> 门禁卡开车的人 -> 车牌号物业管理员 -> 门禁卡门禁卡和车牌号都是不同的认证形式,而门卫大叔查看的本子就对应了不同数据库中的用户信息,这样讲是不是更容易了解了。 Lumen/Laravel中以中间件(Middleware)的形式提供了非常灵活的认证,通过简略的配置就能够切换多个认证。 注:本文所应用的是:Laravel 7.292. Guard工作流程说了这么多,附上一张手工制作的流程图: 从图中能够看到,一个Guard会波及到三个局部,别离是: Guard实现自身User Provider用户提供者,指定哪个数据表以什么形式获取(eloquent/database)Authenticatable接口规定那些货色能够被认证,就是实现它的接口嘛2. 从配置说起深刻底层代码之前,先从配置文件讲起。认证的配置次要在/config/auth.php中,外面能够定义各种认证的门卫大叔(guard): // /config/auth.php'guards' => [ 'user' => [ 'driver' => 'session', 'provider' => 'users', ], 'admin' => [ 'driver' => 'token', 'provider' => 'admin_users', ],],'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class,// 'table' => 'user' ], 'admin_users' => [ 'driver' => 'eloquent', 'model' => App\Models\AdminUser::class, ],],配置中定义了两个门卫user和admin,driver字段设置门卫的认证零碎,默认提供两种sessesion和token,provider定义的就是下面说的本子,保留所有的认证用户,provider上面的drive定义认证用户如何获取,有两种形式database和eloquent形式,个别都是用第二种,model定义eloquent形式应用的数据模型,如果driver是database,就要设置table指定数据库表。如果没有代码中没有指定用哪个门卫,就会应用默认的门卫大爷: ...

March 8, 2021 · 5 min · jiezi

关于php:PHPMQTT-v132-版本发布优化-MQTT5-相关支持

增加 toArray 办法在上个版本中为 getContents 办法减少了一个 getArray 参数来用于客户端回复对端 ACK,此版本中减少了 toArray 办法进行获取: use Simps\MQTT\Message;use Simps\MQTT\Protocol\ProtocolInterface;$message = new Message\Publish();$message->setProtocolLevel(ProtocolInterface::MQTT_PROTOCOL_LEVEL_5_0) ->setTopic('simps/mqtt/message') ->setQos(ProtocolInterface::MQTT_QOS_1) ->setDup(ProtocolInterface::MQTT_DUP_0) ->setRetain(ProtocolInterface::MQTT_RETAIN_0) ->setMessage('this is content') ->setMessageId(1) ->setProperties(['message_expiry_interval' => 100]);$array1 = $message->getContents(true);$array2 = $message->toArray();assert($array1 === $array2);两者的后果雷同。 优化 getProtocolLevelMQTT5 协定中减少了一个 Properties 属性,而 MQTT3.x 中是没有的,之前的版本如果是 MQTT5 协定的话须要手动调用setProtocolLevel来设置协定等级,此版本中就减少优化:判断是否设置了Properties 属性,如果设置了但协定等级不是 MQTT5 则主动设置为 MQTT5 Messageuse Simps\MQTT\Message;use Simps\MQTT\Protocol\ProtocolInterface;$message = new Message\Publish();$message->setTopic('simps/mqtt/message') ->setQos(ProtocolInterface::MQTT_QOS_1) ->setDup(ProtocolInterface::MQTT_DUP_0) ->setRetain(ProtocolInterface::MQTT_RETAIN_0) ->setMessage('this is content') ->setMessageId(1);assert($message->isMQTT5() === false);assert($message->getProtocolLevel() === ProtocolInterface::MQTT_PROTOCOL_LEVEL_3_1_1);$message->setProperties(['message_expiry_interval' => 100]);assert($message->isMQTT5() === true);assert($message->getProtocolLevel() === ProtocolInterface::MQTT_PROTOCOL_LEVEL_5_0);$message->setProtocolLevel(ProtocolInterface::MQTT_PROTOCOL_LEVEL_3_1);assert($message->isMQTT5() === true);assert($message->getProtocolLevel() === ProtocolInterface::MQTT_PROTOCOL_LEVEL_5_0);Configuse Simps\MQTT\Client;use Simps\MQTT\Config\ClientConfig;use Simps\MQTT\Protocol\ProtocolInterface;$config = new ClientConfig();$config->setClientId(Client::genClientID()) ->setKeepAlive(10) ->setDelay(3000) ->setMaxAttempts(5) ->setProperties([ 'session_expiry_interval' => 100, ]) ->setSwooleConfig([ 'open_mqtt_protocol' => true, 'package_max_length' => 2 * 1024 * 1024, ]);assert($config->isMQTT5() === true);assert($config->getProtocolLevel() === ProtocolInterface::MQTT_PROTOCOL_LEVEL_5_0);更新日志加强增加 toArray 办法 (b3fd28a)更新属性默认值 (9c63510)增加遗嘱音讯 Message 类 (#45)增加 Auth Message 类 (36f6a9d)减少 DUP、SESSION_PRESENT 和 RETAIN 的常量 (fe5c418)优化 getProtocolLevel (a329202)减少 isMQTT5 测试和应用常量代替硬编码(b9d4365)修复修改 ReasonCode 中错字 (481994f5)对于 PHPMQTT实用于 PHP 的 MQTT 协定解析和协程客户端反对 MQTT 协定 3.1、3.1.1 和 5.0 版本,反对 QoS 0、QoS 1、QoS 2首个反对 MQTT v5.0 协定的 PHP library文档:https://mqtt.simps.io GitHub:https://github.com/simps/mqtt Gitee:https://gitee.com/phpiot/mqtt ...

March 8, 2021 · 1 min · jiezi

关于php:Web-安全-之-Insecure-deserialization

Insecure deserialization在本节中,咱们将介绍什么是不平安的反序列化,并形容它是如何使网站蒙受高危害性攻打的。咱们将重点介绍典型的场景,并演示一些 PHP、Ruby 和 Java 反序列化的具体示例。最初也会介绍一些防止不平安的反序列化破绽的办法。 利用不平安的反序列化通常比拟艰难。然而,它有时比你设想的要简略得多。如果您不相熟反序列化,那么本节将蕴含一些重要的背景信息,您应该首先相熟这些信息。如果您曾经理解反序列化的基础知识,那么能够间接跳到学习如何利用它。 什么是序列化序列化是将简单的数据结构(如对象及其字段)转换为“更扁平”的格局的过程,该格局的数据能够作为字节流序列发送和接管。序列化的数据让以下过程更简略: 将简单数据写入过程间内存、文件或数据库发送简单数据,例如,通过网络或API调用,在应用程序的不同组件之间传递简单数据要害的是,当序列化一个对象时,其状态也将放弃不变。换句话说,对象的属性及其赋值都会被保留。 序列化 vs 反序列化反序列化是将字节流还原为与原始对象完全相同的正本的过程。而后,网站的逻辑就能够与这个反序列化的对象进行交互,就像与任何其余对象进行交互一样。 许多编程语言提供对序列化的本地反对。具体如何序列化对象取决于具体语言。一些语言将对象序列化为二进制格局,而另一些语言则会序列化为具备不同水平的可读性的字符串格局。请留神,原始对象的所有属性都存储在序列化数据流中,包含所有公有字段。为了避免字段被序列化,必须在类申明中将其显式标记为"transient" 。 请留神,当应用不同的编程语言时,序列化可能被称为 marshalling(Ruby)或 pickling(Python),这些术语与“序列化”同义。 什么是不平安的反序列化不平安的反序列化是指用户可管制的数据被网站反序列化。这会使攻击者可能操纵序列化的对象,以便将无害数据传递到利用程序代码中。 甚至能够用齐全不同类的对象替换序列化对象。令人担忧的是,网站上任何可用的类的对象都将被反序列化和实例化,而不论这个类是不是预期的类。因而,不平安的反序列化有时被称为 "object injection" 对象注入破绽。 一个意外类的对象可能会导致异样。不过,在此之前,侵害可能曾经造成。许多基于反序列化的攻打在反序列化完结之前就曾经实现。这意味着能够攻打反序列化的过程自身,即便网站的性能不间接与歹意对象交互。因而,其逻辑基于强类型语言的网站也容易受到这些技术的攻打。 不平安的反序列化破绽是如何呈现的不平安的反序列化呈现通常是因为人们广泛不足对用户可控数据进行反序列化的危险水平的理解。现实状况下,基本不应该对用户输出进行反序列化。 有些网站所有者认为他们很平安,因为其会对反序列化的数据进行某种模式的附加查看。然而,这种办法通常是有效的,因为简直不可能验证或预料到所有可能产生的状况。这些查看在基本上也是有缺点的,因为它们依赖于在数据被反序列化后对其进行查看,在许多状况下,这对于避免攻打来说曾经太晚了。 破绽产生也可能是因为反序列化的对象通常被认为是可信的。特地是在应用二进制序列化格局的语言时,开发人员可能会认为用户无奈无效地读取或操作数据。然而,只管这可能须要更多致力,但攻击者利用二进制序列化对象的可能性与利用基于字符串的格局的可能性是一样的。 因为古代网站中存在大量依赖项,因而基于反序列化的攻打也成为可能。一个站点可能应用许多不同的库,每个库也都有本人的依赖项,这就产生了一个难以平安治理的存在大量类和办法的池子。因为攻击者能够创立这些类中的任何一个实例,因而很难预测能够对歹意数据调用哪些办法。如果攻击者可能将一长串意外的办法调用链接在一起,并将数据传递到与初始源齐全无关的接收器中,则尤其如此。因而,简直不可能预测到歹意数据的流动并梗塞每个潜在的破绽。 简而言之,平安地反序列化不受信赖的输出是不可能的。 不平安的反序列化会造成什么影响不平安的反序列化的影响可能十分重大,因为它提供了一个切入点,从而导致攻击面大幅减少。它容许攻击者以无害的形式重用现有的利用程序代码,从而导致许多其余破绽,比方近程代码执行. 即便在无奈执行近程代码的状况下,不平安的反序列化也可能导致权限晋升、拜访任意文件和拒绝服务攻打。 如何利用不平安的反序列化破绽下文会有具体阐明。 如何避免不平安的反序列化破绽一般来说,除非相对必要,否则应该防止用户输出的反序列化。在许多状况下,进攻其潜在的高危破绽的难度超过了其带来的益处。 如果的确须要反序列化来自不受信赖的源的数据,请采取弱小的措施以确保数据未被篡改。例如,您能够实现一个数字签名来检查数据的完整性。然而,请记住,任何查看都必须在开始反序列化之前进行。否则,查看就没什么用途了。 如果可能,您应该防止应用通用的反序列化性能。这些办法的序列化数据蕴含了原始对象的所有属性,以及可能蕴含敏感信息的公有字段。相同,你应该创立本人特定类的序列化办法,以管制公开字段。 最初,请记住,该破绽是用户输出的反序列化,而不是随后解决数据的工具链的存在。不要依赖于试图打消测试过程中辨认的工具链,因为跨库依赖的存在,这是不切实际的。在任何给定的工夫,公开记录的内存损坏破绽也意味着应用程序可能会受到攻打。 利用 insecure deserialization 破绽在本节中,咱们将通过 PHP、Ruby 和 Java 反序列化的示例来教你如何利用一些常见破绽场景。咱们心愿证实利用不平安的反序列化实际上比许多人认为的要容易得多。如果你可能应用事后构建的工具链,那么即便在黑盒测试期间也是如此。 咱们还将领导你创立基于反序列化高危破绽的攻打。只管这些通常须要拜访源代码,然而一旦了解了基本概念,它们也比你设想的更容易学习。咱们将探讨以下主题: 如何辨认不平安的反序列化批改网站所需的序列化对象将歹意数据传递到危险的网站性能中注入任意对象类型链式办法调用以控制数据流入危险的接收器中手动创立本人的高级的破绽利用PHAR 反序列化留神:只管许多试验和示例都基于PHP,但大多数开发技术对其余语言也同样无效。 如何辨认不平安的反序列化辨认不平安的反序列化相对来说比较简单,无论你应用白盒测试还是黑盒测试。 在审核过程中,你应该查看网站所有传入数据,并尝试辨认出任何相似于序列化的数据。如果你晓得不同语言应用的格局,则能够绝对容易地辨认序列化的数据。在本节中,咱们将展现 PHP 和 Java 序列化的示例。一旦确定了序列化的数据,就能够测试是否可能管制它。 PHP 序列化格局PHP 应用了一种简直可读的字符串格局,字母示意数据类型,数字示意每个局部的长度。例如,假如一个 User 对象具备以下属性: $user->name = "carlos";$user->isLoggedIn = true;序列化之后,此对象可能如下所示: O:4:"User":2:{s:4:"name":s:6:"carlos"; s:10:"isLoggedIn":b:1;}其含意是: O:4:"User" - 一个对象,类名是 4 个字符的 "User"2 - 对象有 2 个属性s:4:"name" - 第一个属性的键是 4 个字符的字符串 "name"s:6:"carlos" - 第一个属性的值是 6个字符的字符串 "carlos"s:10:"isLoggedIn" - 第二个属性的键是 10 个字符的字符串 "isLoggedIn"b:1 - 第二个属性的值是布尔值 truePHP 序列化的本地办法是 serialize() 和 unserialize() 。如果你有源代码的拜访权限,则应该首先在所有地位查找 unserialize() 并进行进一步考察。 ...

March 8, 2021 · 3 min · jiezi

关于php:变着花样来接参PHP中接收外部参数的方式

对于PHP这样一个web语言来说,接参是十分重要的一个能力。毕竟从前端表单或异步申请传递上来的数据都要获取到能力进行失常的交互展现。当然,这也是所有可能进行web开发的语言的必备能力。明天咱们就来看看PHP各种各样的接参模式。 首先,咱们要筹备一个动态页面,就像上面这个一样,它提供了一个表单,同时url里还带有一个GET参数: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title></head><body> <form action="?show=1" method="post"> 姓名:<input type="text" name="name"/><br /> 电话:<input type="text" name="tel"/><br/> 地址(省):<input type="text" name="address.prov"/><br/> 地址(市):<input type="text" name="address city"/><br/> 趣味1:<input type="text" name="interest[]"/><br/> 趣味2:<input type="text" name="interest[]"/><br/> 趣味3:<input type="text" name="interest[]"/><br/> 学历1:<input type="text" name="edu[one]"/><br/> 学历2:<input type="text" name="edu[two]"/><br/> <input type="submit" value="提交" > </form></body></html>失常的$_GET、$_POST形式// 失常的GET、POST echo $_GET['show'], '<br/>'; // 1 echo $_POST['name'], '<br/>'; // 提交的内容这是最根底的也是最间接的接参形式,GET参数通过 $_GET 获取,POST参数通过 $_POST 获取,相互都不烦扰。 失常的$_REQUEST形式 // 应用REQUEST echo $_REQUEST['show'], '<br/>'; // 1 echo $_REQUEST['tel'], '<br/>'; // 提交的内容$_REQUEST 则是获取所有申请中的参数,不包含上传文件。也就是说,它蕴含了 $_GET 、 $_POST 以及 $_COOKIE(须要配置,默认不蕴含) 这三个接参变量中的所有内容。这里须要留神的一点是,PHP5.3当前, $_REQUEST 承受的参数变量内容由 php.ini 文件中的 request_order 指定,默认状况下这个配置参数的值是 GP 也就是 GET 和 POST ,并没有 COOKIE ,想要 COOKIE 的话须要批改这里增加一个C就能够了。 ...

March 8, 2021 · 2 min · jiezi

关于php:手撸-Laravel-MVC

前沿明天咱们来看看PHP的Laravel 框架,看看它的弱小 第一步咱们来尝试下手动构建Laravel MVC 首先构建下咱们的 composer.json 文件 { "require" :{ "illuminate/routing" : "*", "illuminate/events" : "*", "illuminate/database" : "*", "illuminate/view" : "*" }, "autoload" : { "psr-4" : { "App\\" : "app/" } }}能够看到咱们应用了最根底的几个包,外面蕴含有路由、事件、数据库、视图等组件。 依据Laravel目录构造,还增加了PSR-4的主动加载标准,实现了命令空间到目录的映射 第二步创立入口文件 index.php 增加如下内容 //调用主动加载函数文件,增加主动加载函数require __DIR__ . '/../vendor/autoload.php';//实例化服务容器$app = new \Illuminate\Container\Container();//注册事件,路由服务提供者with(new \Illuminate\Events\EventServiceProvider($app))->register();with(new \Illuminate\Routing\RoutingServiceProvider($app))->register();//加载路由require __DIR__ . '/../app/Http/routes.php';//实例化申请 并散发解决申请$request = \Illuminate\Http\Request::createFromGlobals();$response = $app['router']->dispatch($request);//返回申请响应$response->send();这里咱们能够看到 Laravel 最外围的容器,服务容器用于服务注册和解析,也就是说向服务容器注册可能实现某些性能的实例或回调函数,当须要应用该性能时从服务容器中获取相应的实例来实现。 第三步拜访数据库, 咱们要在 config目录下增加配置文件 database.php 而后在入口增加如下内容 //启动Eloquent ORM的模块并进行相干配置use Illuminate\Database\Capsule\Manager;$manager = new Manager();$manager->addConnection(require '../config/database.php');//Eloquent ORM的模块启动$manager->bootEloquent();因为咱们应用 Eloquent ORM 所以须要应用到数据库治理类。 Eloquent ORM 操作数据库比较简单,分两个步骤,一是创立模型类、二是通过模型类的办法操作数据库。 ...

March 7, 2021 · 1 min · jiezi

关于php:php常用类库工具组件2

symfony/http-foundationgithubhttps://github.com/symfony/http-foundation参考 https://symfony.com/doc/curre...nesbot/carbongithubhttps://github.com/briannesbitt/CarbonAn API extension for DateTime that supports 281 different languages. 更加不便敌对的对日期和工夫进行解决

March 7, 2021 · 1 min · jiezi

关于php:use关键字在PHP中的几种用法

在学习了和应用了这么多年的PHP之后,您晓得use这个关键字在PHP中都有哪些用法吗?明天咱们就来看一下它的三种常见用法。 1. 用于命名空间的别名援用// 命名空间include 'namespace/file1.php';use FILE1\objectA;use FILE1\objectA as objectB;echo FILE1\CONST_A, PHP_EOL; // 2$oA = new objectA();$oA->test(); // FILE1\ObjectA$oB = new objectB();$oB->test(); // FILE1\ObjectA这个想必在日常的工程化开发中会十分常见。毕竟当初的框架都是应用了命名空间的,不论做什么都离不开各种类依赖的调用,在各种控制器文件的上方都会有大量的use xxx\xxx\xxx;语句。 2. 用于trait个性能力的引入// traittrait A{ function testTrait(){ echo 'This is Trait A!', PHP_EOL; }}class B { use A;}$b = new B();$b->testTrait();即便在最近这两年,仍然还是见过齐全没有用过trait的PHP程序员,不要诧异,这是实在存在的。想想还有那么多我的项目都还在用TP3也就不奇怪了。trait个性还是十分不便的一品种性能扩大模式,其实咱们能够看作是将这个use放在了类中就成为了trait的援用定义了。 3. 匿名函数传参// 匿名函数传参$a = 1;$b = 2;// function test($fn) use ($a) // arse error: syntax error, unexpected 'use' (T_USE), expecting '{' function test($fn){ global $b; echo 'test:', $a, '---', $b, PHP_EOL; // test:---2 $fn(3);}test(function ($c) use ($a) { echo $a, '---', $b, '---', $c, PHP_EOL;});// 1------3这个就有点意思了吧,办法中要调用内部的变量是须要global的,在这里咱们间接通过use()也是能够将变量传递过来的。而且这个仅限于在匿名函数中应用。 ...

March 6, 2021 · 1 min · jiezi

关于php:PHPGolang-商品秒杀功能

框架:laravel秒杀组成部分:商品、秒杀场次、Redis、模仿秒杀秒杀过程:一、实现商品、秒杀场次、秒杀场次和商品关联的CRUD;二、定时将秒杀场次、商品、库存等信息提前写入redis;三、配置Redis长久化;四、实现秒杀下单逻辑;五、定时删除秒杀的过期信息并开释库存;六、应用golang并发编程模仿秒杀。 PS:整个流程中,波及异步并发的中央:定时存储数据到redis、秒杀生成订单、查问以后秒杀商品 一、各种表的CRUD 主商品表 CREATE TABLE `goods` ( `id` int(12) unsigned NOT NULL AUTO_INCREMENT COMMENT 'pk', `item_no` varchar(64) NOT NULL COMMENT '货号', `name` varchar(255) NOT NULL COMMENT '商品名称', `pic_path` varchar(255) DEFAULT NULL COMMENT '商品首图门路 yzy=>2018-11-19', `shops_id` int(12) unsigned NOT NULL COMMENT '店铺id', `market_price` decimal(11,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '市场价格', `shop_price` decimal(11,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '门店价', `warn_stock` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '预警库存', `goods_stock` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '总库存', `unit` char(10) NOT NULL COMMENT '单位', `tip` text COMMENT '促销信息', `is_sale` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '1=>上架 2=》不上架', `is_best` tinyint(1) unsigned NOT NULL DEFAULT '2' COMMENT '1=>精品 2=>非精品', `is_hot` tinyint(1) unsigned NOT NULL DEFAULT '2' COMMENT '1=>热销2=>非热销', `is_new` tinyint(1) unsigned NOT NULL DEFAULT '2' COMMENT '1=>新品 2=>非新品', `is_recom` tinyint(1) unsigned NOT NULL DEFAULT '2' COMMENT '1=>举荐 2=>不举荐', `is_vip` tinyint(1) NOT NULL COMMENT '是否为vip商品,1=》VIP 2=》一般', `goods_cats_id_one` int(11) unsigned NOT NULL COMMENT '商品分类一级id', `goods_cats_id_two` int(11) unsigned NOT NULL COMMENT '商品分类二级id', `goods_cats_id_three` int(11) unsigned NOT NULL COMMENT '商品分类三级id', `goods_describe` longtext NOT NULL COMMENT '形容内容 注:lxs=>调整字段名,类型为longtext', `brokerage` decimal(8,2) NOT NULL DEFAULT '0.00' COMMENT '举荐积分率(佣金),单位:%', `brokerage_rules` json DEFAULT NULL COMMENT '举荐积分(佣金)调配规定,单位:%,例如:{10,20,30} 第一个代表第一层', `status` char(3) NOT NULL DEFAULT '100' COMMENT '100=>未审核 200=>审核通过 400=>审核未通过', `sale_num` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '总销量', `sale_time` time DEFAULT NULL COMMENT '上架工夫', `visit_num` int(11) unsigned DEFAULT '0' COMMENT '拜访次数', `appraise_num` int(11) unsigned DEFAULT NULL COMMENT '评估总数', `key_words` varchar(255) DEFAULT NULL COMMENT 'SEO关键词', `remark` varchar(1024) DEFAULT NULL COMMENT '备注,个别写审核未通过起因', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创立工夫', `updated_at` timestamp NULL DEFAULT NULL COMMENT '更新工夫', `deleted_at` timestamp NULL DEFAULT NULL COMMENT '删除工夫', PRIMARY KEY (`id`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;子商品表 ...

March 5, 2021 · 3 min · jiezi

关于php:35年的PHPer-应该具备

又到了,金三银四,换工作季。我呢没准变换工作,倒是上网翻了翻招聘信息,因为我做PHP,就看了下当下3-5年的招聘需要,发现这些招聘信息都有如下要求: 3-5年PHP须要具备: TCP/UDP协定, socket 通信,纯熟应用workman,swoole,swoft等rpc框架精通PHP,相熟golang语言,相熟html,css,javascript,会nodejs,vue优先。mysql, 以及SQL优化,相熟索引利用和优化,独立设计数据库、数据表,nosql,mongodb, redis,memcache缓存。相熟后端缓存技术、理解缓存应用场景,高并发、高性能服务零碎设计教训及能力,相熟大规模集群零碎的开发罕用Linux,shell命令编写,相熟云、容器应用精通LNMP架构,相熟http 协定,RestFul API开发,相熟tp,laravel,yii支流框架。纯熟应用svn,git,Hg版本管理工具,良好的书写习惯,正文,设计模式,编写高质量的,整洁简略,可维护性的代码,遵循公司研发标准,产品技术文档的整顿剖析和疾速排查定位解决线上问题,保障系统性能的稳定性,优化现有零碎,晋升运作性能主导/参加我的项目的架构设计、技术选型、架构原型实现以及服务端外围模块的开发,与各技术人员严密单干,实现工作工作有集体博客,集体开源我的项目,有集体独立实现我的项目。乐于继续学习,乐观开朗,抗压性强,良好的沟通能力和单干精力,自我驱动力强,有强烈的事业心和责任感大家能够看看本人是否达到了支流的用人规范,如果你是超出预期,那么你能够抉择跳得更高。3-5年工夫,足够把一个学生造就成一个合格的打工人了。能够看到企业还是把PHPer当作多面手对待,心愿还会能会一些其余语言。3-5年的phper,企业还心愿有肯定的带团能力,由此可见phper的成熟期是较短的。 我同时对比了3-5年的NodeJS,Python、Java、Golang就任要求,PHP岗位对技术之外的要求是最多的,这样会,还要那样会,而且范畴还广。我本人也感觉phper的成熟工夫是较短的,对技术高下的评判次要是对高性能、高并发的设计,这个时候php写的漂不丑陋不重要,会不会用第三方工具(Redis,ES),了不理解限流、队列、削峰、缓存这些原理就尤为重要。所以到这个份上,就别死磕PHP了,多看看周边。 我又查了下5-10年的PHP岗位,数据很少。有的,我看了下任职要求,只有一句话要求了PHP。好到里,我就想从整个职业路线上谈谈,如果你关注过我的博客,会发现,我公布些golang相干的技术博客了。如果你还是保持——PHP是这世界上最好的语言,你能够把这篇文章敞开了。原本我还是安安心心写PHP,捣鼓捣鼓Swoole,感觉会用Swoole,能玩转PHP协程就很牛皮。这除了自嗨,然并卵。 之前比拟喜爱看些他人的博客,php100从断更到敞开。其余综合博客平台,PHP的文章更新占比也很少,这么说吧,有些培训机构都不开班了。我感觉最近php的热度是有所降落的。所以,大家思考换工作好好思考下将来5年,10年你筹备干什么。同时,别死磕语言,多积攒算法、计算机底层、架构方面的常识,这些不随你换语言而过期的。

March 5, 2021 · 1 min · jiezi

关于php:PHP中命名空间是怎样的存在三

这是与命名空间无关的最初一篇。最初还是两个比较简单的内容,是对于命名空间和全局相干的一些类、函数、常量的应用比照。当然,最初咱们还会总结一下命名空间的名称解析规定做为这三篇系列文章的完结。 全局空间当文件中定义了命名空间,也就是namesapce指定了以后的命名空间后,在调用全局类、函数、常量时,须要增加一个“\”,也就是齐全限定拜访符号来表明这个类、函数、常量是全局的那个,而不是以后命名空间中的。特地是以后命名空间中蕴含与全局类、函数、常量同名的内容时。 namespace FILE6;function show(){ echo strtoupper('aaa'), PHP_EOL; // 调用本人的 echo \strtoupper('aaa'), PHP_EOL; // 调用全局的}function strtoupper($str){ return __NAMESPACE__ . ':' . \strtoupper($str);}在这个FILE6命名空间中,咱们定义了一个strtoupper()办法。之间说过,命名空间就是为了解决同名问题而呈现的,这个办法和全局php自带的那个办法是完全相同的名称的。所以,在调用的时候咱们须要调用的是哪个办法。那么如果以后命名空间中没有定义这个办法呢?别急,接下来的内容就是讲这个问题。 后备全局函数/常量从上个例子中,咱们就能够看出全局齐全限定拜访符的作用,当没有应用全局符时,strtoupper()办法会先调用以后命名空间下的办法。那么后备的作用就是如果以后命名空间中没有找到时,会去全局找相干的函数。在文档中的定义是这样的: 当 PHP 遇到一个非限定的类、函数或常量名称时,它应用不同的优先策略来解析该名称。类名称总是解析到以后命名空间中的名称。因而在拜访零碎外部或不蕴含在命名空间中的类名称时,必须应用齐全限定名称。对于函数和常量来说,如果以后命名空间中不存在该函数或常量,PHP 会退而应用全局空间中的函数或常量。 意思也就是说,函数和常量,会有后备去全局查找的能力。然而类不行!!如果要应用全局类,肯定要加全局齐全限定符。咱们通过一个例子来看: namespace FILE7;// 类必须应用齐全限定的全局空间$o1 = new \stdClass();// $o2 = new stdClass(); // Fatal error: Uncaught Error: Class 'FILE7\stdClass' not found// 办法会先在本命名空间查找,如果没找到会去全局找function strlen($str){ return __NAMESPACE__ . ':' . (\strlen($str) - 1);}echo strlen('abc'), PHP_EOL; // FILE7:2 ,以后命名空间echo \strlen('abc'), PHP_EOL; // 3 , 全局echo strtoupper('abc'), PHP_EOL; // ABC, 全局// 常量也是有后备能力的const E_ERROR = 22; echo E_ERROR, PHP_EOL; // 22, 以后命名空间echo \E_ERROR, PHP_EOL; // 1, 全局echo INI_ALL, PHP_EOL; // 7, 全局名称解析规定对齐全限定名称的函数,类和常量的调用在编译时解析。例如 new \A\B 解析为类 A\B。所有的非限定名称和限定名称(非齐全限定名称)依据以后的导入规定在编译时进行转换。例如,如果命名空间 A\B\C 被导入为 C,那么对 C\D\e() 的调用就会被转换为 A\B\C\D\e()。在命名空间外部,所有的没有依据导入规定转换的限定名称均会在其后面加上以后的命名空间名称。例如,在命名空间 A\B 外部调用 C\D\e(),则 C\D\e() 会被转换为 A\B\C\D\e() 。非限定类名依据以后的导入规定在编译时转换(用全名代替短的导入名称)。例如,如果命名空间 A\B\C 导入为C,则 new C() 被转换为 new A\B\C() 。在命名空间外部(例如A\B),对非限定名称的函数调用是在运行时解析的。例如对函数 foo() 的调用是这样解析的: ...

March 5, 2021 · 1 min · jiezi

关于php:PHP中命名空间是怎样的存在二

明天带来的仍然是命名空间相干的内容,自身命名空间就是PHP中十分重要的一个个性。所以对于它的各种操作和应用还是非常复杂的,光应用形式就有很多种,咱们一个一个的来看。 子命名空间命名空间自身就像目录一样,所以命名空间当然也是能够定义子命名空间的,真的就和操作系统的各种目录层级是齐全一样的。咱们通过简略的例子来看看。首先还是创立三个php文件,其中3-2和3-2-1是应用的雷同的二级命名空间,3-2-1在FILE32的根底上持续向下扩大了第三级的命名空间FILE321。他们都是MyProject命名空间的子命名空间。 // file3-1.phpnamespace MyProject\FILE31;function testA31(){ echo 'FILE31\testA()', PHP_EOL;}// file3-2.phpnamespace MyProject\FILE32;const CONST_A32 = "file3-2";function testA32(){ echo 'FILE32\testA()', PHP_EOL;}class objectA32{ function test(){ echo 'FILE32\ObjectA', PHP_EOL; }}// file3-2-1.phpnamespace MyProject\FILE32\FILE321;function testA321(){ echo 'FILE321\testA()', PHP_EOL;}接下来的应用就很简略了,和应用一级命名空间一样,间接应用use进行导入就能够了。 // 子命名空间require 'namespace/file3-1.php';require 'namespace/file3-2.php';require 'namespace/file3-2-1.php';use MyProject\FILE31;use MyProject\FILE32;use MyProject\FILE32\FILE321;FILE31\testA31(); // FILE31\testA()FILE32\testA32(); // FILE32\testA()FILE32\FILE321\testA321(); // FILE321\testA()FILE321\testA321(); // FILE321\testA()同一文件中定义多个命名空间PHP是容许在一个文件中定义多个命名空间的,然而并不举荐这么做,因为这样可能会带来各种未知的凌乱。在这里,咱们只有理解到能够这样应用就行了,在日常的开发中还是尽量要防止。 // file4.phpnamespace FILE41;function testA41(){ echo 'FILE41\testA()', PHP_EOL;}namespace FILE42;function testA42(){ echo 'FILE42\testA()', PHP_EOL;}在应用中当然也和其余命名空间的应用没什么两样,间接use应用即可。 // 一个文件中多个命名空间require 'namespace/file4.php';use FILE41, FILE42;FILE41\testA41(); // FILE41\testA()FILE42\testA42(); // FILE42\testA()非限定名称、限定名称、齐全限定名称不要被术语吓到,这三个术语其实十分好了解。 非限定名称,名称中不蕴含命名空间分隔符的标识符,例如 Foo 。限定名称,名称中含有命名空间分隔符的标识符,例如 Foo\Bar 。名称中蕴含命名空间分隔符,并以命名空间分隔符开始的标识符,例如 \Foo\Bar。 namespace\Foo 也是一个齐全限定名称。间接用例子来说就十分清晰了。 ...

March 4, 2021 · 1 min · jiezi

关于php:PHP实现chrome请求数据转换为接口使用的json数据

为什么要写转换程序最近在做旧版程序迁徙,旧的架构为惯例的MVC模式,新版架构全副改成restful架构。 因为改版数据是统一的,然而申请构造不统一,新版的申请全副以json模式提交,为了不便测试,之前始终都是间接在浏览器关上开发者工具,而后把申请内容复制过去,而后手动改成json模式,因为之前数据量比拟少,临时未发现测试时候不不便的状况,然而明天遇到了数据比拟多的状况,于是我想,为啥不写一段转换程序呢? 自身来说,程序的初衷应该是进步工作效率,这也是我之前短少反思的中央,因而写下这篇文章做个记录。 代码废话不多说,间接上代码,有啥有余的中央,后续有工夫再做钻研。 <?php// 文件路经$f = './t.data';$content = file_get_contents($f);$rows = explode("\n", $content);$data = [];foreach ($rows as $row) { // 宰割key和value $rowInfo = explode(':', $row); $keyInfo = array_shift($rowInfo); $value = trim(implode(':', $rowInfo)); $keyArray = getCharArray($keyInfo); $keyItem = ''; $keys = []; foreach ($keyArray as $char) { if ($char == '[') { $keys[] = $keyItem; $keyItem = ''; } elseif ($char == ']') { continue; } else { $keyItem .= $char; } } $keys[] = $keyItem; // 驼峰转下划线 $keys = array_map(function ($item) { return strtolower(preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $item)); }, $keys); $firstKey = array_shift($keys); if (empty($keys)) { $data[$firstKey] = $value; } else { if (!isset($data[$firstKey])) { $data[$firstKey] = []; } $item = &$data[$firstKey]; while (!empty($keys)) { $currentKey = array_shift($keys); if (!isset($item[$currentKey])) { $item[$currentKey] = []; } $item = &$item[$currentKey]; } $item = $value; unset($item); }}echo json_encode($data, JSON_UNESCAPED_UNICODE);/** * 字符串转字符数组 * * @param string $string * * @return array */function getCharArray(string $string){ $strlen = mb_strlen($string); $i = 0; $charArray = []; while ($i < $strlen) { $charArray[] = mb_substr($string, $i, 1); $i++; } return $charArray;}示例文件: ...

March 3, 2021 · 2 min · jiezi

关于php:PHPMQTT-v131-版本发布MQTT-协议解析-协程客户端

上个版本公布的知乎文章中有用户评论,遇到了握手失败的状况,分割了我之后进行了测试,我这里的确没问题,不过我删除了一段代码: $will = [ 'topic' => '', 'qos' => 0, 'retain' => 0, 'message' => '',];$client->connect(true, $will);改为了间接进行connect $client->connect();因为应用的是 MQTT3,所以没有 MQTT5 中的 code 属性,须要通过抓包才能够获取到谬误起因。 这里换为 MQTT5 之后就能够间接获取到谬误起因,如以下代码就能够获取到谬误起因 use Simps\MQTT\Client;use Simps\MQTT\Config\ClientConfig;use Simps\MQTT\Hex\ReasonCode;use function Swoole\Coroutine\run;run(function () { $config = new ClientConfig(); $config->setUserName('') ->setPassword('') ->setClientId(Client::genClientID()) ->setKeepAlive(10) ->setProtocolLevel(5) ->setDelay(3000) // 3s ->setMaxAttempts(5) ->setSwooleConfig([ 'open_mqtt_protocol' => true, 'package_max_length' => 2 * 1024 * 1024, ]); $client = new Client('broker.emqx.io', 1883, $config); $will = [ 'topic' => '', 'qos' => 0, 'retain' => 0, 'message' => 'byebye', ]; $res = $client->connect(true, $will); var_dump($res, ReasonCode::getReasonPhrase($res['code']));});将 code 换为起因,就能够获取到谬误起因为:Topic Name invalid ...

March 3, 2021 · 1 min · jiezi

关于php:php项目下nginx的配置

mac中应用brew装置的软件包都寄存在/usr/local/cellar目录下软件的配置文件寄存在/usr/local/etc目录下,须要在该目录下进行配置文件的批改我的项目服务器的寄存目录:/usr/local/var,在该文件夹下寄存我的项目文件以及日志文件启动php: 形式一:间接在/usr/local/cellar/php版本/sbin目录下应用./php-fpm启动形式二:在/usr/local/cellar/php版本/sbin目录下应用nohup ./php-fpm > a.log & 启动,这种启动形式启动后在后盾运行,并且会打印日志到a.log文件nginx配置: 配置日志文件: 在http下放开log_format该项批改access\_log、error\_log目录为/usr/local/var/log/nginx下对应的log文件门路批改location对应的root目录为我的项目下的public目录,两处放开fastcgi_pass、fastcgi_index、fastcgi_param和include四项在server中的location下增加如下配置 if (!-e $request_filename) { rewrite ^/index.php(.*)$ /index.php?s=$1 last; rewrite ^(.*)$ /index.php?s=$1 last; break; }留神:if后边必须有一个空格,否则不失效nginx服务命令: * 启动:nginx* 敞开:nginx -s stop* 重启:nginx -s reloadnginx配置启动后存在的问题: 找不到log文件:这种问题很显著是log文件遗记配置或者门路配置的不正确,须要对error_log和access_log批改配置,log文件寄存在/usr/local/var/log/nginx目录下应用localhost:8080/a.php拜访a.php文件时显示找不到该文件,这个谬误可能由三种起因造成: 起因一:没有启动php服务,须要开启php,参照上边的两种启动形式起因二:如果php服务曾经开启,仍然显示找不到文件,则须要批改nginx配置,在nginx.conf文件中批改fastcgi_param SCRIPT_FILENAME/scripts$fastcgi_script_name;替换成 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;~~~~起因三:没有拜访权限,应用chmod 777 我的项目文件目录设置文件夹的拜访权限重启nginx查看是否能够失常拜访

March 3, 2021 · 1 min · jiezi

关于php:PHP中命名空间是怎样的存在一

命名空间其实早在PHP5.3就曾经呈现了。不过大部分同学可能在各种框架的应用中才会接触到命名空间的内容,当然,现代化的开发也都离不开这些可能疾速产出的框架。这次咱们不从框架的角度,仅从简略的代码角度来解析一下命名空间的概念和应用。 首先,咱们要定义命名空间是个什么货色。 其实就像操作系统的目录一样,命名空间就是为了解决相似于操作系统中同一个文件夹不能有雷同的文件名一样的问题。假如咱们只有一个文件,一个目录,那么在这个目录中,是不能有两个完全相同的文件的。如果有这样名称完全相同的文件,那么操作系统也不晓得咱们到底应该关上的是哪一个文件。同理,在一个PHP文件中,咱们也不能起雷同名称的函数或者类名,PHP也不晓得咱们到底要调用的是哪一个函数或者类。 了解了上述内容之后,再来看命名空间的语法,其实十分像咱们的目录的定义。 namespace A\B\C;这个命名空间的定义就是指出了以后命名空间是A\B\C。就像是C:\A\B\C这样一个文件夹一样。光说不练假把式,间接上代码来看看: // file1.phpnamespace FILE1;const CONST_A = 2;function testA(){ echo 'FILE1\testA()', PHP_EOL;}class objectA{ function test(){ echo 'FILE1\ObjectA', PHP_EOL; }}// file2.phpnamespace FILE2;const CONST_A = 3;function testA(){ echo 'FILE2\testA()', PHP_EOL;}class objectA{ function test(){ echo 'FILE2\ObjectA', PHP_EOL; }}咱们在namespace目录下创立了这两个php文件,函数和类名都是一样的,但定义了不同的命名空间,一个是FILE1,一个是FILE2。 namespace A;include 'namespace/file1.php';include 'namespace/file2.php';use FILE1, FILE2;use FILE1\objectA as objectB;const CONST_A = 1;function testA(){ echo 'A\testA()', PHP_EOL;}class objectA{ function test(){ echo 'A\ObjectA', PHP_EOL; }}// 以后命名空间echo CONST_A, PHP_EOL; // 1testA(); // A\testA()$oA = new objectA();$oA->test(); // A\ObjectA// FILE1echo FILE1\CONST_A, PHP_EOL; // 2FILE1\testA(); // FILE1\testA()$oA = new FILE1\objectA();$oA->test(); // FILE1\ObjectA$oB = new objectB();$oB->test(); // FILE1\ObjectA// FILE2echo FILE2\CONST_A, PHP_EOL; // 3FILE2\testA(); // FILE2\testA()$oA = new FILE2\objectA();$oA->test(); // FILE2\ObjectA在测试代码中,咱们又定义了以后的命名空间为A。并include了file1.php和file2.php。并在这个文件中同时也定义了与file1.php和file2.php中雷同的函数和类名。接下来咱们顺次调用这些动态变量、函数和类。 ...

March 3, 2021 · 1 min · jiezi

关于php:构建一套适合微服务的高可用架构

随着近几年微服务与云计算的飞速发展,机器由物理机逐渐变为了虚拟机,应用服务由宏大的单体利用逐步变为了若干个微服务联结组成的利用集群,更新迭代的速度成倍上涨,传统的部署模式已无奈满足开发日常更新需要,须要一套适宜微服务的治理架构。 技术栈及文档 资源调度框架 MESOS 利用编排平台 Marathon nginx 动静批改 upstream dyups nginx 动静批改 upstream upsync 应用Mesos 进行机器资源管理 首先,是机器资源的治理。在微服务的架构中,原有的单体服务被拆分成了一个个独立单元的应用程序,这些服务体量较小,能够独立运行在配置较小的机器上。为了故障隔离,咱们会尽可能的把这些服务部署在不同的虚拟机上,这样机器的数量会成倍增加。对于运维来说,每个新服务部署时,须要先查看现有机器的残余资源是否满足新服务的需要,有时可能因为评估不精确造成来回扩容、迁徙,或者资源节约。 开始时,咱们的架构可能时这样的 为了解决下面的问题,能够应用 MESOS ( 布式资源管理框架),它能够 让咱们像用一台电脑(一个资源池)一样应用整个数据中心。mesos 部署时分为 master 和 agent 两个角色,当然,你能够在同一台机器启动它们。 装置Mesos 前须要装置zookeeper,mesos 应用zk 实现高可用和选举,包含一个 master leader 和 几个备份 master 防止宕机。 Mesos master  负责管理各个Framework和Slave,并将Slave上的资源非配给各个Framework。Mesos agent   负责管理本节点上的各个Mesos Task,为各个Executor分配资源 (低版本为 mesos-slave)。 $ cat > /tmp/bintray-mesos-el.repo <<EOF bintray-mesos-el - packages by mesos from Bintray[bintray-mesos-el]name=bintray-mesos-elbaseurl=https://dl.bintray.com/apache...gpgcheck=0repo_gpgcheck=0enabled=1EOF $ sudo mv /tmp/bintray-mesos-el.repo /etc/yum.repos.d/bintray-mesos-el.repo $ sudo yum update $ sudo yum install mesos $ tree /etc/mesos-master/etc/mesos-master/|-- hostname|-- ip|-- log_dir|-- quorum   # quorum > (number of masters)/2`-- work_dir $ tree /etc/mesos-agent/etc/mesos-agent/|-- containerizers  # 容器类型,默认 mesos,能够增加 docker,如: mesos,docker|-- hostname|-- ip|-- log_dir|-- master           # master 地址,格局为 host:port 或 zk://host1:port1,host2:port2,.../path 或 file:///path/to/file|-- resources       # 设置总资源大小,能够设置小些来预留更多机器资源`-- work_dir $ cat /etc/mesos/zk  # 设置 mesos 在zk 中的存储目录zk://192.168.100.9:2181,192.168.100.110:2181,192.168.100.234:2181/mesos $ systemctl start mesos-master$ systemctl start mesos-slave 当mesos服务启动后,agent 会向master 节点汇报机器资源,包含CPU、内存、磁盘等。 当咱们要公布一个服务时,只须要设置这个服务的CPU、内存、磁盘参数, mesos master 会主动帮咱们抉择有足够资源的机器去运行,如下图 咱们将微服务的启动都交给 Mesos 治理,这样咱们只须要关注整体资源即可。MESOS 提 供了UI界面,能够间接拜访 mesos master 的5050 端口,查看集群资源应用状况。 总体应用状况 及 Agent 节点应用状况 ...

March 1, 2021 · 1 min · jiezi

关于php:使用jemalloc优化MysqlPHP内存占用

原文链接:https://tlanyan.me/use-jemall...本站托管在自购的CN2 GIA VPS服务器上,内存只有2G,偶然会呈现内存缓和而导致系统把Redis、Mysql等内存小户kill掉的状况。减少swap 能够解决这个问题,但swap性能比内存差太多,因而想到应用jemalloc优化内存占用。 jemalloc介绍jemalloc是facebook推出的内存分配器,目前在firefox、facebook服务器、android 5.0 等服务中大量应用。 jemalloc最大的劣势是其弱小的多核/多线程调配能力,在内存足够大时, CPU的外围数量越多,程序线程数越多,jemalloc的调配速度越快。依据测试数据,在高并发时性能优于Google推出的tcmalloc和Glibc的ptmalloc。 除了性能高,jemalloc还升高了内存碎片化,能更好的利用内存。 应用jemalloc优化Mysql、PHP内存占用Redis默认应用了jemalloc,redis-cli info memory有如下输入: ... mem_not_counted_for_evict:0 mem_replication_backlog:0 mem_clients_slaves:0 mem_clients_normal:0 mem_aof_buffer:0 mem_allocator:jemalloc-5.1.0 active_defrag_running:0 lazyfree_pending_objects:0 Mariadb/mysql、PHP等则默认应用零碎自带的ptmalloc,因而能够替换成jemalloc取得更好的内存使用率。 首先装置jemalloc: CentOS零碎 yum install -y jemalloc # Ubuntu/Debian零碎 apt install -y libjemalloc2装置实现后,CentOS零碎在/usr/bin目录下会有jemalloc.sh文件。能够通过jemalloc.sh 后续命令执行命令,例如jemalloc.sh node app.js,从而用上jemalloc调配和治理内存。 对于Ubuntu/Debian零碎,或者CentOS零碎上以systemctl启动的服务,须要通过如下形式用上jemalloc: 设置LD_PRELOAD环境变量:export LD_PRELOAD=libjemalloc.so门路:$LD_PRELOAD,而后再运行命令/应用systemctl重启服务。其中CentOS零碎下libjemalloc.so的门路是/usr/lib64/libjemalloc.so.2,Ubuntu/Debian的门路是/usr/lib/x86_64-linux-gnu/libjemalloc.so.2。聪慧如你,应该能想到把export语句搁置到.bashrc文件中,以便后续都失效;设置零碎全局应用,办法是新建/etc/ld.so.preload文件,把libjemalloc.so门路写入文件,而后重启Mariadb、PHP-FPM等服务。本站采取第二种形式,配置好/etc/ld.so.preload后重启Mariadb、PHP-FPM,可通过上面的命令查看是否用上了jemalloc: lsof -Pn -p $(pidof mariadbd) | grep jemalloc,配置正确的话会有jemalloc.so的输入;cat /proc/$(pidof mariadbd)/smaps | grep jemalloc,和上述命令有相似的输入。查看PHP-FPM的形式同理。 总结本文简要介绍了应用jemalloc优化Mysql、PHP内存占用的办法和操作步骤,并给出查看过程是否用上jemalloc的命令,达到优化内存占用的目标。 通过上述配置,内存优化能有多少呢?说实话对于小内存服务器改良并不大,只是聊胜于无罢了。 参考Enabling jemalloc on Percona Server for MySQL 5.7 and 8.0 SeriesHow to use Node.js with Jemalloc?CentOS 7零碎减少swap几个查看Redis内存信息的命令

March 1, 2021 · 1 min · jiezi

关于php:PHP的闭包

前沿明天咱们来聊聊PHP5.3引入的闭包个性 定义闭包是指在创立时封装四周的状态的函数。即使闭包所在的环境不存在了,闭包中封装的状态仍然存在。 有人可能会问闭包和匿名函数有什么区别。 其实实践上讲,闭包和匿名函数是不同概念。不过PHP将其视为雷同的概念。所以,提到闭包时,指的也是匿名函数。 闭包和匿名函数其实是伪装成函数的对象,如果审查PHP闭包或匿名函数,会发现它们是Closure类的实例。 创立闭包来看个例子 //创立闭包$test = function($name) { return "hello $name\n";};echo $test('hpinke');//输入 hello hpinke简略的来说就是创立了一个闭包对象,而后将其赋值给$test变量。闭包和一般的PHP函数很像:应用的句法雷同,也承受参数,而且能返回值。 咱们通常把PHP 闭包当做函数和办法的回调应用。很多PHP函数都会用到回调函数 比方array_map $resultArr = array_map(function($num) { return $num*3;}, [1,2,3,4]);print_r($resultArr);//输出 3 6 9 12 在没有引入闭包之前,只能独自创立具名函数,而后应用名称引入那个函数。 附加状态在PHP中,必须手动调用闭包对象的bindTo()办法或者应用use关键字,把状态附加到PHP闭包上。 一、应用use关键字 function testPerson($name) { return function ($domain) use ($name) { echo "$domain --- $name"; };}$name = testPerson('hpinke');echo $name('hello world');//输入 hello world --- hpinke函数testPerson() 有个名为$name的参数,这个函数返回一个闭包对象,而且这个闭包封装了$name 参数,即使返回的闭包对象跳出了testPerson() 函数的作用域,它也会记住$name 参数的值,因为$name变量仍在闭包中。 二、应用bindTo关键字 PHP 闭包是对象。与任何其余PHP对象相似,每个闭包实例都能够应用 $this 关键字获取闭包的外部状态。 咱们能够应用bindTo这个办法把 Closure对象的外部状态绑定到其余对象上。 //动静的给一个对象 增加办法class Test { private $num = 1;}$f = function() { return $this->num + 1;};$test1 = $f->bindTo(new Test, 'Test');echo $test1(); //输入 2咱们拜访的$num是公有变量,所以作用域指定对象,或者类名。 ...

March 1, 2021 · 1 min · jiezi

关于php:记一次PHP的Invalid-binding-type问题

首先阐明下环境问题,新旧服务器的迁徙。代码在老服务器运行没有任何问题。环境都是PHP7.3,后果新的服务器上流量导过去当前,就报出了如下问题: FastCGI sent in stderr: "PHP message: PHP Fatal error: Invalid binding type in /base.inc.php on line 221这个base.inc.php的第221行是什么东东呢? 221 }额,这就有点诡异了。正文掉相干的办法后,报错信息又顺延到下一个花括号的结尾处了。这就神奇了。于是去百度谷歌了半天,并没有什么有用的材料,惟一一个提到的内容是说从新编译一下PHP。 https://stackoverflow.com/questions/3960323/why-dont-php-attributes-allow-functions 好吧,咱们就从新编译,可是编译完了一旦导流过去,马上就又挂掉。PHP-FPM失常运行,但不是所有的都会出问题,于是测试拜访的时候是有的能够有的报错的。再深刻比照发现,新服务器为了未来的扩大咱们装置了swoole扩大。可能问题就出在这里,马上删掉swoole扩大,问题解决。 在swoole官网也并没有找到相干的信息。预估可能是代码中或者在PHP-FPM的配置中有和swoole不兼容的中央。所以在运行的过程中没有流量的时候失常测试不会有影响,但流量较大的状况下就会产生这种谬误。有的时候很多代码看似运行没故障,但真正的问题往往还是要在大流量高并发的场景下能力体现进去。 =========== 各自媒体平台均可搜寻【硬核项目经理】

March 1, 2021 · 1 min · jiezi

关于php:有这个开源项目你也可以打造自己的知识付费平台了

 大家好,我是为宽广程序员兄弟操碎了心的小编,每天举荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节俭开发效率,实现不加班不熬夜不掉头发,是我的指标! 明天的我的项目来自一位读者的投稿, 本期配角是一款开源在线教育点播零碎——MeEdu,技术栈是PHP+MySQL,基于Laravel框架开发。 在这个自媒体时代,人人都是自媒体,人人都是发言人,只有一部手机,你就能做自媒体。MeEdu应运而生,MeEdu为中小型企业以及自媒体人而生,挑战全网z低成本,为创业者助力。 在这个自媒体大潮中,能怀才不遇的只是多数,大部分从业者根本黯然开场,当然作为程序员的咱们,本篇文章并不是教你如何自做自媒体,而是思考能不能通过技术做一个铲子,去服务这些自媒体创业者。 好了,不废话了,间接进入正题。 MeEdu个性代码开源:MeEdu遵循MIT开源协定,装置当前,永恒应用,无需领取应用费用插件自在选配:无年付套餐,无捆绑生产,插件服务自在选配多端反对:反对PC,H5,小程序,安卓,IOS等 环境要求ComposerPHP >= 7.2MySql >= 5.6Zip PHP ExtensionOpenSSL PHP ExtensionPDOMysql PHP ExtensionMbstring PHP ExtensionTokenizer PHP ExtensionXML PHP ExtensionFileinfo PHP Extension性能概览视频点播视频在线播放(PC,H5,Andorid,IOS,小程序)/试看课程评论(审核)/视频评论(审核)阿里云点播存储腾讯云点播存储视频文件URL地址播放播放器性能快进开关倍速播放播放器封面播放统计视频试看跑马灯(防录屏)免费模式课程购买视频购买全站VIP会员用户零碎手机号短信(阿里云短信,云片短信)注册/登录/找回明码企鹅扫码登录/Github登录站内音讯我的课程/我的视频/我的珍藏/我的订单/批改明码/观看记录我的积分我的邀请码/邀请余额提现/邀请处分/一级抽成用户协定/用户隐衷协定订单零碎课程订单/视频订单/VIP会员订单邀请码(优惠码)抵扣支付宝PC领取/企鹅扫码PC领取/支付宝H5领取/手动打款领取其它性能零碎缓存(晋升零碎性能)图片CDN(阿里云OSS,七牛云)友情链接首页幻灯片推广链接(用于第三方平台推广渠道统计)网站布告首页导航后盾管理系统用户治理/增加/编辑/详细信息查看/订阅课程/订阅VIP/观看记录/积分操作等等订单治理/过滤查看/具体数据/改为已领取等等数据统计/课程观看数据/每日订单领取/每日订单数量等等课程管理/视频治理/分类管理/评论治理等等系统配置/后盾管理员治理/管理员权限配置等等拓展性能在线电子书在线直播图文免费模块单页模块学习门路兑换码课程有效期随机拍照问答在线考试与练习大小班团购秒杀阿里云HLS视频加密腾讯云HLS视频加密企鹅扫码登录/受权登录立春模板(领取H5,小程序,安卓,IOS等平台)截图前台 后盾 结尾 本期就分享到这里,我是小编南风吹,专一分享好玩乏味、离奇、实用的开源我的项目及开发者工具、学习资源!心愿能与大家独特学习交换,欢送关注我的公众号【Github导航站】。

February 27, 2021 · 1 min · jiezi

关于php:PHP实现网页截图

如何应用PHP实现网页截图PHP实现网页截图是一个在日常开发中不常见的需要,然而如果实现还是十分有意思的。目前业界有很多成熟的计划,上面我举荐应用一个很稳固的第三方服务来间接实现,该服务有如下特点: 反对多线路反对登录截图反对UA变换反对Cookie注入 实现登录截图反对自定义宽高反对网页滚动截图反对设定截图前的延迟时间首先咱们关上 它的首页 https://www.screenshotmaster.com/ 注册一个账号,而后你会在用户核心获取到一个惟一的Token,保留好这个Token 不要透露! 上面来看看它反对的参数: 您能够返回API文档页面查看更多的参数。 应用PHP调用截屏巨匠的接口获取截图: //参数$token = 'YOUR_API_TOKEN';$url = urlencode('https://www.baidu.com');$width = 1200;$height = 800;$full_page = 1;// 结构URL$query = "https://www.screenshotmaster.com/api/v1/screenshot";$query .= "?token=$token&url=$url&width=$width&height=$height&full_page=$full_page";// 调用API$image = file_get_contents($query);// 保留截图file_put_contents('./screenshot.png', $image);而后?没有而后了,就这么简略!Enjoy Yourself!

February 26, 2021 · 1 min · jiezi

关于php:Clickhouse架构及应用

内容纲要: 背景;Clickhouse介绍;Clickhouse架构及性能;Clickhouse在好将来的实际;建设与布局;参考文献。背景在日志核心倒退晚期,日志检索剖析次要基于elasticsearch进行,随着日志核心接入的业务越来越多,数据量也逐步增长,基于日志进行剖析和监控告警的需要变得越来越简单,很难用elasticsearch来满足,所以须要依据需要场景来抉择适合数据库。咱们须要的: 数据量会很大,因而须要分布式;反对实时写入,反对疾速计算,在较短时间内能实现计算;弱小的sql能力,实时指标sql化;人力无限,运维须要简略;高效的压缩比存储,服务器无限,能够用更少的服务器存储更多的数据;基于以上特点,咱们抉择了Clickhouse,接下来会介绍Clickhouse的特点、零碎架构以及应用状况。 Clickhouse介绍1、Clickhouse特点=============== 图2-1 Clickhouse特点图 能够看到,Clickhouse的特点恰是咱们所须要的。接下来具体的介绍一下外围个性: 1)齐备的DBMS性能: ClickHouse领有齐备的治理性能,所以它称得上是一个DBMS ( Database Management System,数据库管理系统 ),而不仅是一个数据库。 作为一个DBMS,它具备了一些基本功能,如: DDL ( 数据定义语言 ):能够动静地创立、批改或删除数据库、表和视图,而无须重启服务;DML ( 数据操作语言 ):能够动静查问、插入、批改或删除数据;权限管制:能够依照用户粒度设置数据库或者表的操作权限,保障数据的安全性;数据备份与复原:提供了数据备份导出与导入复原机制,满足生产环境的要求;分布式治理:提供集群模式,可能主动治理多个数据库节点。2) 列式存储与数据压缩 列式存储和数据压缩,对于一款高性能数据库来说是必不可少的个性。想让查问变得更快,最简略且无效的办法是缩小数据扫描范畴和数据传输时的大小,而列式存储和数据压缩就能够帮忙咱们实现上述两点。因为Clickhouse是真正意义上的列式存储,每一列都在不同的文件下,所以该文件数据类型统一,能够更无效的压缩。 3) 向量化执行引擎 向量化执行以列存为前提,次要思维是每次从磁盘上读取一批列,这些列以数组模式组织。每次next都通过for循环解决列数组。这么做能够大幅缩小next的调用次数。相应的CPU的利用率失去了进步,另外数据被组织在一起。 能够进一步利用CPU硬件的个性,如SIMD,将所有数据加载到CPU的缓存当中去,进步缓存命中率,晋升效率。在列存储与向量化执行引擎的双重优化下,查问执行的速度会有一个十分微小的飞跃。 4) 关系模型与SQL查问 ClickHouse是一个关系型数据库。它简直能够反对近百分之九十的sql作为查问语句,比方group by,order by等。 5) 多样化的表引擎 ClickHouse和mysql一样,也将存储局部进行了形象,把存储引擎作为一层独立的接口。所以说Clickhouse实现了很多种表引擎,比方mergetree,log,memory等类型的引擎,每一种表引擎都有着各自的特点,用户能够依据理论业务场景的要求,抉择适合的表引擎应用。 6) 多线程与分布式ClickHouse简直具备现代化高性能数据库的所有典型特色,对于能够晋升性能的伎俩堪称是一一用尽,对于多线程和分布式这类被宽泛应用的技术,天然更是不在话下。 7) 多主架构 HDFS、Spark、HBase和Elasticsearch这类分布式系统,都采纳了Master-Slave主从架构,由一个管控节点作为Leader兼顾全局。而ClickHouse则因为它的集群架构和其余数据库不同,这种架构使得它是一个多主架构。 8) 在线查问 ClickHouse采纳了LSM树结构,所以使得Clickhouse的插入量能够很大。同时,Clickhouse的外部优化,使得在简单查问的场景下,它也可能做到极快响应,且毋庸对数据进行任何预处理加工。达到了实时数仓的成果 9) 数据分片与分布式查问 Clickhouse领有分布式能力,天然反对数据分片,数据分片是将数据进行横向切分,这是一种在面对海量数据的场景下,解决存储和查问瓶颈的无效伎俩。ClickHouse并不像其余分布式系统那样,领有高度自动化的分片性能。ClickHouse提供了本地表 ( Local Table ) 与分布式表 ( Distributed Table ) 的概念。一张本地表等同于一份数据的分片。而分布式表自身不存储任何数据,它是本地表的拜访代理,其作用相似分库中间件。借助分布式表,可能代理拜访多个数据分片,从而实现分布式查问。 2、Clickhouse常见利用场景电信行业用于存储数据和统计数据应用;新浪微博用于用户行为数据记录和剖析工作;用于广告网络和RTB,电子商务的用户行为剖析;日志剖析;检测和遥感信息的开掘;商业智能;网络游戏以及物联网的数据处理和价值数据分析;最大的利用来自于Yandex的统计分析服务Yandex.Metri ca。Clickhouse架构及性能Clickhouse的集群架构是和其余的数据集群有肯定的区别,他的集群能力是表级别的,而咱们熟知的大数据体系,比方hadoop系列的集群都是服务级别的。例如,一个hdfs集群,所有文件都会切片、备份;而Clickhouse集群中,建表时也能够本人决定用不必,也就是说其实Clickhouse单节点就能存活。可能有其余的大数据教训的人对这种设计会有点奇怪,前面会从单机架构到集群架构,具体的去介绍。 ======================================================================================================================================================================================================= 1、Clickhouse单机架构设计官网介绍Clickhouse架构的材料比拟匮乏,根据已有的教训联合内部材料,依据本人的了解还原Clickhouse的架构如下: 图3-1 clickhouse单机架构图 1)Parser与Interpreter Parser和Interpreter是十分重要的两组接口:Parser分析器是将sql语句已递归的形式造成AST语法树的模式,并且不同类型的sql都会调用不同的parse实现类。而Interpreter解释器则负责解释AST,并进一步创立查问的执行管道。Interpreter解释器的作用就像Service服务层一样,起到串联整个查问过程的作用,它会依据解释器的类型,聚合它所须要的资源。首先它会解析AST对象;而后执行"业务逻辑" ( 例如分支判断、设置参数、调用接口等 );最终返回IBlock对象,以线程的模式建设起一个查问执行管道。 2)表引擎 表引擎是ClickHouse的一个显著个性,上文也有提到,clickhouse有很多种表引擎。不同的表引擎由不同的子类实现。表引擎是应用IStorage接口的,该接口定义了DDL ( 如ALTER、RENAME、OPTIMIZE和DROP等 ) 、read和write办法,它们别离负责数据的定义、查问与写入。 ...

February 26, 2021 · 1 min · jiezi

关于php:在windows使用docker环境搭建hyperf微服务

在windows应用docker环境搭建hyperf微服务创立hyperf我的项目环境docker run -d --name hyperfrpc -v d/dataproject/hyperfrpc:/hyperf-skeleton -p 9501:9501 -it --entrypoint /bin/sh hyperf/hyperf:7.4-alpine-v3.11-swoole参数解释: -d 示意在后盾运行 --name 示意给容器取个名字 -v 示意挂载到本机的目录 -p 示意映射到主机的端口,冒号前的是本机,前面是docker容器端口 -it 终端 --entrypoint 通过这个来笼罩dockerfile里定义的entrypoint 镜像容器运行后,而后进入容器中,在容器内装置 Composer #下载composer.phar文件wget https://github.com/composer/composer/releases/download/1.8.6/composer.phar#给composer.phar文件加可执行权限chmod u+x composer.phar#挪动该文件到/usr/local/bin/composermv composer.phar /usr/local/bin/composer将 Composer 镜像设置为阿里云镜像,减速国内下载速度composer config -g repo.packagist composer https://mirrors.aliyun.com/composer通过 Composer 装置 hyperf/hyperf-skeleton 我的项目composer create-project hyperf/hyperf-skeleton进入装置好的 Hyperf 我的项目目录,linux目录cd hyperf-skeleton测试 Hyperf环境是否胜利php bin/hyperf.php start在powshell关上一个clidocker exec -it hyperfrpc /bin/bash进行测试curl 127.0.0.1:9501看到输入{"method":"GET","message":"Hello Hyperf."}环境胜利在hyperf-skeleton目录下创立消费者和提供者删除刚刚创立的hyperf我的项目rm -rf hyperf-skeleton 创立providercomposer create-project hyperf/hyperf-skeleton hyperf-skeleton/provider 创立时,选项只抉择一个JSON-PRC with Service Governance,其余都选n 创立consumercd hyperf-skeleton ...

February 26, 2021 · 3 min · jiezi

关于php:后期静态绑定在PHP中的使用

什么叫前期动态绑定呢?其实咱们在之前的文章PHP中的static中曾经说过这个货色了。明天咱们还是再次深刻的了解一下这个概念。 首先,咱们通过一段代码来引入前期动态绑定这一概念: class A{ public static function who() { echo __CLASS__, PHP_EOL; } public static function test() { self::who(); }}class B extends A{ public static function who() { echo __CLASS__, PHP_EOL; }}B::test(); // A在这段代码中,咱们应用了self关键字,当应用B类调用test()静态方法时,self指向的是A类的who()办法,因而,输入的是A。别冲动,这是一般的动态绑定。self关键字调用的内容取决于它定义时所在的类。也就是说不管怎么继承,用哪个子类来调用test()办法,self关键字都会调用的是A类的who()办法。 而前期动态绑定呢?其实就有点像实例化的类对象,每个实例化的对象,调用的都是本身,而不是父类的属性办法。一般的动态调用可不是这样,然而事实中咱们又有这样的需要,就像实例化对象的调用形式一样来调用动态属性办法,这时,咱们就能够应用static关键字来实现前期动态绑定。 class C{ public static function who() { echo __CLASS__, PHP_EOL; } public static function test() { static::who(); }}class D extends C{ public static function who() { echo __CLASS__, PHP_EOL; }}D::test(); // D当应用static关键字后,这里D类调用的test()办法外部调用的who()就是D类本人了。 官网文档中的定义如下: 当进行静态方法调用时,该类名即为明确指定的那个(通常在 :: 运算符左侧局部);当进行非静态方法调用时,即为该对象所属的类。 ...

February 26, 2021 · 1 min · jiezi

关于php:我在VsCode上看基金你呢

一我是一个程序员。 代码是我的禁锢,基金是我的自在。 突破禁锢,奔向自在,兴许只差几个定投。 有人说,买基金肯定要心态好,要学会危险对冲,把8成的钱全仓买基金,残余2成买意外身亡险,基金大涨就赚,基金大跌就跳楼,赔率1:4,怎么都赚钱。 可是我心态不行。 基金的操作,我向来只崇奉追涨杀跌,长处是简略易操作,毛病就是容易亏钱。 所以为了少亏钱,我须要频繁的看基金涨跌状况,大略5分钟一次,好决定如何优雅的追涨杀跌。 明明就是买个基金,硬是有了华尔街之狼的感觉。 当基金涨了,我会感觉老子是投资之神,下班能赚多少钱,不想下班。 当基金跌了,我会感觉md赚的工资还不够赔的,有啥意思,不想下班。 当我不想下班的心态还没有体现到我的项目延期的时候,均匀5分钟拿起手机看基金涨跌的动作胜利吸引到老板的留神。 在一番友善的交谈之后,我感觉本人如果失去这份工作可能真的会饿死,当即我就决定: 我要换种形式看基金! 遍寻GitHub之后,果然找到了,居然能够间接在VsCode看基金实时数据,完满。 尽管这个我的项目的名字我不太喜爱。 情谊揭示,关注文章下方公众号,回复「基金」 可获取IDEA 查看基金/股票插件。二韭菜盒子韭菜盒子——VsCode 里也能够看股票 & 基金实时数据,做最好用的投资插件。 https://github.com/LeekHub/le... 性能个性基金实时涨跌,实时数据,反对海外基金展现股票实时涨跌,反对 A 股、港股、美股开市主动刷新,节假日敞开轮询反对升序/降序排序、基金持仓金额升序/降序基金实时走势图和历史走势图基金排行榜基金持仓信息股市资金流向(沪深港通资金流向、北向资金、南向资金)雪球用户动静关注(雪球新闻)自定义涨跌图标(吃面、吃肉、烤韭菜、烤肉、喝酒)基金持仓金额设置(用于动静计算盈亏)基金盈亏展现(依据实时基金涨跌状况动静实时计算盈亏)反对保护持仓成本价,主动计算收益率 v1.6.7基金趋势统计图股票反对分组展现(A 股、港股、美股)股票涨跌揭示设置看的进去,性能还是很全的,完满符合我的诉求,急不可待试试吧。 实战还是很简略的,就是VsCode装置插件,不过性能真的挺丰盛。 应用文档: https://github.com/LeekHub/le...三应用韭菜盒子一段时间之后,我终于变成了一个合格的韭菜。。。 回复[基金],可获取IDEA 查看基金/股票插件。

February 25, 2021 · 1 min · jiezi

关于php:PHP中引入文件的方式和他们之间的区别

引入形式require include require_once include_onc各种引入形式的不同require在程序开始时加载,include在引入时加载include_once/require_once示意曾经加载的不加载include遇到谬误给出提醒继续执行,require遇到谬误时给出提醒进行执行

February 25, 2021 · 1 min · jiezi

关于php:如何为SEO信息图找到关键字

关键字是搜索引擎优化的基石。如果没有人搜寻您公布的内容,无论您如许致力,都不会从Google取得流量。 那么,什么是关键字呢?关键字是人们在搜索引擎中键入的单词和短语。它们也称为搜寻查问或“ SEO关键字”。 如何发现SEO的正确关键字 为了找到适合的关键字,咱们须要思考潜在客户如何搜寻您的产品或服务。而后,您能够应用关键字钻研工具扩大这些想法并找到更多关键字。 以下是一些技巧,可帮忙您轻松发现产品的某些关键字: 您提供的产品-如果您曾经领有要在线推广的产品或业务,则很容易想到种子关键字。考虑一下您提供的服务,您就会晓得人们在Google上搜寻的内容。 扩大关键字-许多关键字倡议工具可在线收费取得,而Google领有一个。或者,您能够输出已确定的关键字以在Google中查看相似的倡议,并且能够找到更多的关键字或相似的关键字组。 考察竞争对手的关键字-许多SEO工具(例如Amazon Alexa)提供收费服务,以查看人们应用哪些热门关键字来吸引您的竞争对手。钻研这些关键字,而后抉择与您的产品或服务相干的关键字。 其余数字营销模板(Visual Paradigm Online) 守业图 数字营销信息图 营销打算图 什么是数字营销信息图 5营销趋势图 5步骤内容营销清单信息图表 SEO营销的信息图 衰弱食品信息图 业余营销信息三折小册子 等距图形的数字营销Instagram帖子 等距图形的数字营销登陆网站 可恶的营销Instagram公布与等距图 蓝色业余营销简历 广告素材时间轴简略简历 光明信息图表营销助理简历 紫色时间轴卓越简历

February 25, 2021 · 1 min · jiezi

关于php:关于PHP中对象复制的那点事儿

咱们曾经在PHP设计模式之原型模式中探讨过对于PHP中对象复制的问题,这次就当做是一次温习。 原型模式能够看作是对象复制中的一个重要内容。在学习原型模式时,咱们理解到对象中的援用变量,也就是变量也是一个对象时,间接复制这个对象会导致其中的援用变量还是指向同一个对象。是不是有点绕,咱们还是用例子来阐明: // clone办法class testA{ public $testValue;}class A{ public static $reference = 0; public $instanceReference = 0; public $t; public function __construct() { $this->instanceReference = ++self::$reference; $this->t = new testA(); } public function __clone() { $this->instanceReference = ++self::$reference; $this->t = new testA(); }}$a1 = new A();$a2 = new A();$a11 = clone $a1;$a22 = $a2;var_dump($a11); // $instanceReference, 3var_dump($a22); // $instanceReference, 2$a1->t->testValue = '当初是a1';echo $a11->t->testValue, PHP_EOL; // ''$a2->t->testValue = '当初是a2';echo $a22->t->testValue, PHP_EOL; // 当初是a2$a22->t->testValue = '当初是a22';echo $a2->t->testValue, PHP_EOL; // 当初是a22// 应用clone后$a22 = clone $a2;var_dump($a22); // $instanceReference, 4$a2->t->testValue = '当初是a2';echo $a22->t->testValue, PHP_EOL; // NULL$a22->t->testValue = '当初是a22';echo $a2->t->testValue, PHP_EOL; // 当初是a2首先,通过变量的变动,咱们能够看出应用clone关键字的对象复制会调用__clone()办法。这个魔术办法正在原型模式的外围所在。在这个办法中,咱们能够从新实例化或者定义对象中的援用成员。通过clone,咱们让$t变量从新实例化,从而让$t成为了新的对象,从而防止援用带来的问题。 ...

February 25, 2021 · 1 min · jiezi

关于php:Laravel-的事件订阅者

事件订阅者在 Laravel 的事件零碎 中说到,一个事件能够对应多个监听器,但一个监听器只监听一个事件。 那么如果想在一个类中订阅多个事件,例如在订单发货、签收、退货事件产生时,都须要进行“发短信操作”,该如何解决呢,这时候能够应用事件订阅者。 事件订阅者能够在类外部订阅多个事件,即在单个类中定义多个事件处理器。 编写事件订阅者<?phpnamespace App\Listeners;use Illuminate\Auth\Events\Login;use Illuminate\Auth\Events\Logout;class UserEventSubscriber{ /** * 解决用户登录事件 */ public function handleUserLogin($event) {} /** * 解决用户登记事件 */ public function handleUserLogout($event) {} /** * 为事件订阅者注册监听器 * * @return array */ public function subscribe() { return [ Login::class => [UserEventSubscriber::class, 'handleUserLogin'], Logout::class => [UserEventSubscriber::class, 'handleUserLogout'], ]; }}注册事件订阅者<?phpnamespace App\Providers;use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;class EventServiceProvider extends ServiceProvider{ /** * 利用的事件监听器映射 */ protected $listen = [ // ]; /** * 被注册的订阅者类 */ protected $subscribe = [ 'App\Listeners\UserEventSubscriber', ];}

February 24, 2021 · 1 min · jiezi

关于php:PHP面试题

1,&援用(https://www.cnblogs.com/chrdai/p/11061174.html)        在PHP中,将变量 $a赋值给 $b,实际上就是将两个变量指向了同样的内存地址。 $a = range(1,100000);var_dump(memory_get_usage()); // int(6698184)$b = $a;var_dump(memory_get_usage()); // int(6698184)$a = range(1,200000);var_dump(memory_get_usage()); // int(17184024)        从上边能够看到,当 $b=$a时,并不是重新分配内存空间给 $b,而是将两个变量指向了同样的内存地址。而当给 $a从新赋值时,则是从新开拓一片内存空间给 $a。         变量间的援用赋值,就是将变量都指向同一个内存地址,当任意一个变量值发生变化时,就会将两个变量指向的内存地址都批改为新调配的内存地址。 $a = range(1,100000);var_dump(memory_get_usage()); // int(6698208)$b = &$a;var_dump(memory_get_usage()); // int(6698208)$a = range(1,100000);var_dump(memory_get_usage()); // int(6698208)        对于援用的变量执行 unset操作,也只会勾销援用,而不会销毁内存空间。 $a = 1;$b = & $a;unset($b);echo $a;        对象的援用: class A { public $name = 1; function getName(){ echo $this->name; }}$a = new A;$b = $a; // $b 与 $a 指向同一个内存空间地址$b->name = 2;$a->getName(); // 2变量援用示例: $d = ['a', 'b', 'c'];foreach($d as $k => $v){ $v = &$d[$k];}//最终程序执行实现之后 $d 的值是?        第一次遍历:$d[0]被援用赋值给 $v,都指向了同一个值的内存地址 'a'。        第二次遍历:$d[1]被援用赋值给 $v,因为之前$v和 $d[0]都指向了同一个地址,因而,这一次循环会将 $d[0]和 $v都被批改成了 $d[1]的值 b。        第三次遍历:$d[2]被援用赋值给 $v,于之前$v和 $d[1]都指向了同一个地址,因而,这一次循环会将 $d[1]和 $v都被批改成了 $d[2]的值 c。        因而最终 $d = ['b', 'c', 'c'] ...

February 24, 2021 · 3 min · jiezi

关于php:PHPMQTT-v130-版本发布MQTT-协议解析-协程客户端

v1.3.0 版本新增了一个 Message 类簇,次要不便用于在 Server 中回复对端 ACK。 use Simps\MQTT\Protocol\Types;use Simps\MQTT\Protocol\V3;use Simps\MQTT\Message\ConnAck;use Simps\MQTT\Message\PingResp;$server = new Swoole\Server('127.0.0.1', 1883, SWOOLE_BASE);$server->set( [ 'open_mqtt_protocol' => true, 'package_max_length' => 2 * 1024 * 1024, ]);$server->on('connect', function ($server, $fd) { echo "Client #{$fd}: Connect.\n";});$server->on('receive', function (Swoole\Server $server, $fd, $from_id, $data) { $data = V3::unpack($data); if (is_array($data) && isset($data['type'])) { switch ($data['type']) { case Types::CONNECT: if ($data['protocol_name'] != 'MQTT') { $server->close($fd); return false; } $server->send( $fd, (new ConnAck())->setCode(0) ->setSessionPresent(0) ); break; case Types::PINGREQ: $server->send($fd, (new PingResp())); break; } } else { $server->close($fd); }});$server->on('close', function ($server, $fd) { echo "Client #{$fd}: Close.\n";});$server->start();在收到CONNECT包之后,须要回复CONNACK报文,之前的版本须要用户手动调用pack类来生成send_data ...

February 24, 2021 · 1 min · jiezi

关于php:具有创意的现代菜单设计-可增进食欲

想设计胜利的菜单,仅提供信息已不再足够。餐馆老板心愿通过菜单来引诱和启发客人的意欲。 咱们汇总了多种最佳菜单设计,能够为您提供本人的菜单灵感!业余菜单设计的汇合,将激发您对菜单设计我的项目的想法。 您将看到休闲、低档餐厅、酒吧的菜单等各式各样的设计,也蕴含快餐场合,以假日为主题的菜单,复旧格调的菜单等等。这些开胃的设计联合了良好的品尝和性能,并且十分无效地吸引了感官。你筹备开始了吗? Visual Paradigm Online - Menu 140个模板 简略的红黑酒吧菜单 彩色和橙色披萨照片披萨餐厅菜单 棕色咖啡照片网格咖啡店菜单 简略的红酒和美食酒店餐厅菜单 紫果汁照片陈腐饮料菜单 粉红色的陈腐咖啡咖啡馆照片简略菜单 棕色和红色圆圈照片每周菜单 简略的橙色花卉照片婚礼菜单 蓝色复活节彩蛋咖啡厅菜单 复活节面包店销售菜单 复活节全套餐餐厅菜单 复活节全课程菜单 复活节庆贺牛排菜单 [简略大胆的节日菜单设计理念](https://online.visual-paradigm.com/app/diagrams/#infoart:proj=0&gallery=/repository/3d6b63f9-88e5-40ed-b04a-2065938464e5.xml&name=Easter%20Ice-cream%20Menu) 可恶的婴儿色调复活节菜单设计模板 复活节庆贺紫色晚餐菜单设计 时尚的复活节庆典菜单设计模板 简略可恶的紫色复活节摇篮菜单设计 简略布局的西餐厅菜单 带有明确信息的棕色餐厅菜单 乏味的陈腐果汁菜单与水果的图形 全天早餐菜单,棕色和红色 粉红2列情人节茶点菜单 [灰色色调的甜点菜单](https://online.visual-paradigm.com/app/diagrams/#infoart:proj=0&gallery=/repository/267ad54a-cf65-46d6-b793-46da27f19961.xml&name=Monochrome%20Colour%20Tone%20Dessert%20Menu) 蛋糕照片的甜点菜单 彩色简略的日常汉堡菜单 勃艮第的冷咖啡和面包店菜单设计 令人愉悦的绿色菜单设计理念 两个设计模板的浪漫餐厅菜单 苦涩的粉红色庆典菜单模板设计 西餐厅的老式深色调菜单 ...

February 24, 2021 · 1 min · jiezi

关于php:CentOS-下给-php-安装-Xdebug-扩展

Xdebug是PHP的一个扩大,可帮忙开发者进行调试和开发。 这里以源码编译装置的PHP为例,如果是yum或apt装置的php能够参考官网:Installation Xdebug。 下载 Xdebug 源码wget https://xdebug.org/files/xdebug-2.9.2.tgz解压tar -xzf xdebug-2.9.2.tgz编译装置cd xdebug-2.9.2/ 执行phpize命令,该命令个别在php的装置目录bin目录下: /usr/local/php/bin/phpize接着就是编译装置了,其中 /usr/local/php/bin/php-config 门路也是位于php装置目录里: ./configure --enable-xdebug --with-php-config=/usr/local/php/bin/php-configmake && make install配置找到php配置文件php.ini的地位,个别是在php装置目录的etc目录下,在最初退出: [Xdebug]zend_extension="xdebug.so"留神:如果要一起应用Xdebug和OPCache,则必须在OPCache配置之后增加Xdebug行。否则,它们将无奈失常工作。 最初重启一下相干服务(php-fpm)使其失效,而后就能够在phpinfo()页面看到Xdebug模块了。 也能够在命令下通过php -m列出所有已装置的模块。

February 24, 2021 · 1 min · jiezi

关于php:关于PHP的方法参数类型约束

在之前的文章PHP办法参数的那点事儿中,咱们讲过对于PHP办法参数的一些小技巧。明天,咱们带来的是更加深刻的钻研一下PHP中办法的参数类型。 在PHP5之后,PHP正式引入了办法参数类型束缚。也就是如果指定了办法参数的类型,那么传不同类型的参数将会导致谬误。在PHP手册中,办法的类型束缚仅限于类、接口、数组或者callable回调函数。如果指定了默认值为NULL,那么咱们也能够传递NULL作为参数。 class A{}function testA(A $a){ var_dump($a);}testA(new A());// testA(1); // Fatal error: Uncaught TypeError: Argument 1 passed to testA() must be an instance of A, int given,在这个例子中,咱们定义了参数类型为A类,所以当咱们传递一个标量类型时,间接就会返回错误信息。 function testB(int $a){ var_dump($a);}testB(1);testB('52aadfdf'); // 字符串强转为int了// testB('a');// Fatal error: Uncaught TypeError: Argument 1 passed to testB() must be of the type int, string givenfunction testC(string $a){ var_dump($a);}testC('测试');testC(1); // 数字会强转为字符串// testC(new A()); // Fatal error: Uncaught TypeError: Argument 1 passed to testC() must be of the type string在手册中明确阐明了标量类型是不能应用类型束缚的。但其实是能够应用的,不过如果都是标量类型则会进行互相的强制转换,并不能起到很好的束缚作用。比方上例中int和string类型进行了互相强制转换。指定了非标量类型,则会报错。此处是本文的重点,小伙伴们可要划个线了哦。其实说白了,如果咱们想指定参数的类型为固定的标量类型的话,在参数中指定并不是一个好的抉择,最好还是在办法中进行再次的类型判断。而且如果参数中进行了强转,也会导致办法外部的判断产生偏差。 ...

February 24, 2021 · 1 min · jiezi

关于php:Laravel-Guzzle-使用踩雷及指南

明天在应用Guzzle时遇到了几个问题,在这里记录一下。 1.报错HttpFoundationFactory not foundClass 'Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory' not found遇到这个问题是因为Guzzle的应用是须要依赖这个包的,然而咱们没有,解决办法十分间接: composer require symfony/psr-http-message-bridge如果之前没有应用镜像,那么问题就间接解决了,然而如果应用过镜像那就呈现了第二个问题 2.增加依赖包时报错Could not find package[InvalidArgumentException] Could not find package symfony/psr-http-message-br idge. Did you mean one of these? symfony/psr-http-message-bridge loophp/unaltered-psr-http-message-bridge-bundl e呈现这个问题的起因是因为应用镜像,解决办法十分间接: composer config -g --unset repos.packagist -上面记录一下guzzle的根本用法: //新建client配置base_uri,能够间接在这前面拼接比拟不便$client = new Client([ 'base_uri' => 'http://127.0.0.1:8000/', 'timeout' => 2.0]);try { return $client->request('GET', '/api/v4/alarms', [ 'auth' => ['admin', 'public'] ]);} catch (GuzzleException $e) { return array([ 'msg' => 'error' ]);}

February 23, 2021 · 1 min · jiezi

关于php:JavaJavaScriptCCPHPPython都是用来开发什么

用任何编程语言来开发程序,都是为了让计算机干活,比方编写一篇文章,下载一首MP3等,而计算机干活的CPU只意识机器的指令,所以,只管不同的编程语言差别极大,最初都得“翻译”成CPU能够执行的机器指令。实践上任何语言干任何事件简直都能够, 然而次要干什么那就不一样了。 对于刚步入IT行业的小白,或者只晓得某一语言绝对应的薪资是多少,但却不晓得次要是做什么的,更不会思考到当前的职业倒退方向问题。以下将对编程语言进行具体的解说。 C和C++ C/C++实践上说能够做任何开发, 只有有适合的硬件驱动和API,特点是效率高,基本上是编译语言外面效率最高的。 除非你的零碎中连C/C++编译器都不具备. 某些零碎当中C++编译器是不具备的, 然而C个别都具备. 目前而言, C语言次要用来开发底层模块(比方驱动,解码器,算法实现), 服务利用(比方web服务器)和嵌入式应用(比方微波炉里的程序). C++也能够做这些, 不过因为C++的复杂性和规范问题, 人们还是更违心应用C来做. C++更适宜比较复杂但又特地须要高效率的设施,比方大型游戏,一些根底库, 大型桌面利用。 总结: C: 零碎底层, 驱动, 嵌入式开发. C++: 游戏开发, 大规模, 高性能, 分布式要求的程序开发。 Java java经常跟”企业”分割在一起, 因为具备一些很好的语言个性, 以及丰盛的框架, 在企业应用中最被青眼, 你总能够听到对于J2EE, JSP, Hibernate之类的货色的探讨. 同时, java在手机畛域也有一席之地, 在广泛智能化之前, 很多手机就是以反对java利用作为卖点的, 而智能手机暴发之后, java手机主场变成了android, 作为安卓的规范编程语言而存在。 总结: Java: 网页, 企业级开发, 一般应用软件, 游戏后盾。 JavaScript Javascript听起来跟java有关系, 其实并没有任何关系, 只是名字像而已.就好比雷峰塔和雷锋的关系一样,尽管只差一个字。js最宽泛的利用毫无疑问是在web前端. 简略的说, 网站给你传过来的是一堆用各种标签示意格局的文档, 而js负责操纵这些文档实现一些客户端动态效果. js的领地还不仅如此, 当初的Node.js还能够用于服务器端的开发。 总结: JavaScript是浏览器的脚本语言,个别和Html,CSS这些一起学,次要做网站的前端开发,展示各种酷炫的画面。 Python Python因为具备丰盛和弱小的库,它又叫做作胶水语言,可能把用其余语言制作的各种模块(尤其是C/C++)很轻松地联结在一起。 常见的一种利用情景是,应用Python疾速生成程序的原型(有时甚至是程序的最终界面),而后对其中有特地要求的局部,用更适合的语言改写,比方3D游戏中的图形渲染模块,性能要求特地高,就能够用C/C++重写,而后封装为Python能够调用的扩大类库。 Python是做服务器开发与物联网开发。信息安全,大数据处理,数据可视化机器学习,物联网开发,各大软件的api,桌面利用,都须要python。 总结: Python:动静解释型,开发效率高,开源,灵便,入门门槛低。 ...

February 23, 2021 · 1 min · jiezi

关于php:用-symfonyoptionsresolver-优雅的校验类初始化选项

示例类use Symfony\Component\OptionsResolver\OptionsResolver;/** * Class Email * composer require symfony/options-resolver */class Email{ /** * Email constructor. * * @param array $options */ public function __construct(array $options = []) { $this->configureOptions($options, function (OptionsResolver $resolver){ $resolver->setDefaults([ 'host' => 'smtp.example.org', 'username' => 'user', 'password' => 'password', 'port' => 25, ]); $resolver->setRequired(['host', 'username', 'password', 'port']); $resolver->setAllowedTypes('host', 'string'); $resolver->setAllowedTypes('username', 'string'); $resolver->setAllowedTypes('password', 'string'); $resolver->setAllowedTypes('port', 'int'); }); } /** * @param array $options * @param \Closure $closure */ public function configureOptions(array $options, Closure $closure) { $resolver = new OptionsResolver; $closure($resolver); $this->options = $resolver->resolve($options); }}正确的选贤$email = new Email([ 'host' => 'smtp.example.org', 'username' => 'user', 'password' => 'password', 'port' => 25,]);var_export($email);Email::__set_state(array( 'options' => array ( 'host' => 'smtp.example.org', 'username' => 'user', 'password' => 'password', 'port' => 25, ),))未通过校验的选项$email = new Email([ 'host' => 'smtp.example.org', 'username' => 'user', 'password' => 'password', 'port' => '25', // 留神这里]);var_export($email);PHP Fatal error: Uncaught Symfony\Component\OptionsResolver\Exception\InvalidOptionsException: The option "port" with value "25" is expected to be of type "int", but is of type "string".总结集体感觉可应用该 symfony/options-resolver 组件较好的对开发第三方 sdk 的客户端类初始化参数进行校验,例如集体适配的 Yii 极光推送扩大包 - yii-jpush 中的利用。 ...

February 23, 2021 · 1 min · jiezi

关于php:trait能力在PHP中的使用

置信大家对trait曾经不生疏了,早在5.4时,trait就曾经呈现在了PHP的新个性中。当然,自身trait也是个性的意思,但这个个性的次要能力就是为了代码的复用。 咱们都晓得,PHP是现代化的面向对象语言。为了解决C++多重继承的凌乱问题,大部分语言都是单继承多接口的模式,但这也会让一些能够复用的代码必须通过组合的形式来实现,如果要用到组合,不可避免的就要实例化类或者应用静态方法,无形中减少了内存的占用。而PHP为了解决这个问题,就正式推出了trait能力。你能够把它看做是组合能力的一种变体。 trait A{ public $a = 'A'; public function testA() { echo 'This is ' . $this->a; }}class classA{ use A;}class classB{ use A; public function __construct() { $this->a = 'B'; }}$a = new classA();$b = new classB();$a->testA();$b->testA();从上述代码中,咱们能够看出,trait能够给利用于任意一个类中,而且能够定义变量,十分不便。trait最须要留神的是对于同名办法的重载优先级问题。 trait B { function test(){ echo 'This is trait B!'; }}trait C { function test(){ echo 'This is trait C!'; }}class testB{ use B, C; function test(){ echo 'This is class testB!'; }}$b = new testB();$b->test(); // This is class testB!// class testC{// use B, C;// }// $c = new testC();// $c->test(); // Fatal error: Trait method test has not been applied, because there are collisions with other trait methods on testC在这里,咱们的类中重载了test()办法,这里输入的就是类中的办法了。如果正文掉testB类中的test()办法,则会报错。因为程序无奈辨别出你要应用的是哪一个trait中的test()办法。咱们能够应用insteadof来指定要应用的办法调用哪一个trait。 ...

February 23, 2021 · 1 min · jiezi

关于php:一些不常用的PHP字符类型检测函数

原文链接:何晓东 博客 次要是 Ctype 扩大所提供的函数,用来检测在以后的区域设定下,一个字符或者字符串,是否仅蕴含指定类型的字符。此类函数用来代替简略的正则验证,效率高于正则验证。参数为字符串,如果给出一个 -128 到 255 之间(含)的 int, 将会被解释为该值对应的 ASCII 字符 (负值将加上 256 以反对扩大 ASCII 字符). 其它整数将会被解释为该值对应的十进制字符串。 Ctype 系列函数ctype_alnum — 做字母和数字字符检测,仅蕴含 [A-Za-z0-9] 返回 truectype_alpha — 做纯字符检测,仅蕴含 [A-Za-z] 返回 truectype_cntrl — 做控制字符检测,\r \t \n 为控制字符,仅蕴含控制字符才返回 truectype_digit — 做纯数字检测,请看上面额定阐明ctype_graph — 做可打印字符串检测,空格除外,测试显示蕴含 \r \t \n 会返回 false,'asdf ' 同样会返回 falsectype_lower — 做小写字符检测ctype_print — 做可打印字符检测 'asdf ' 字符串会返回 truectype_punct — 检测可打印的字符是不是不蕴含空白、数字和字母,其实就是全都是标点符号才返回 true,其余返回 falsectype_space — 做空白字符检测,必须全为 ' ' 空字符串才返回 true,其余返回 falsectype_upper — 做大写字母检测ctype_xdigit — 检测字符串是否只蕴含十六进制字符,即只能蕴含十进制的树枝和 [A-Fa-f] 的字母,否则返回 falsectype_digit 额定阐明:这个函数的参数要求是一个 string 这一点是十分有用的,因而当你传入一个 integer 的参数兴许不能失去冀望的后果。 ...

February 22, 2021 · 1 min · jiezi

关于php:PHP基础二常用字符串处理函数

chr(int $ascii) : string 依据指定ASCII值返回指定的字符。$a = chr(65);echo $a; // Aecho(string $arg1, string $...) : void 输入一个或多个字符串,echo 不是一个函数(只是一个语言构造)explode(string $delimiter, string $string, int $limit = ? ) : array返回一个由 $delimiter宰割 $string之后产生的子串组成的数组。如果设置了 $limit参数,则返回的数组里蕴含最多 $limit个元素,其中最初的那个元素将蕴含 string的残余局部。$a = 'Hello World,This is my house!';$b = explode(' ', $a);print_r($a);// Array ( [0] => Hello [1] => World,This [2] => is [3] => my [4] => house! )$c = explode(' ', $a, 3);print_r($c);// Array ( [0] => Hello [1] => World,This [2] => is my house! )fprintf(resource $handle, string $format, mixed $... = ?) : int写入一个经 $format格式化后的字符串到由 fopen关上的资源 $handle中去,返回写入的字符串的长度。$year = date('Y');$month = date('m');$day = date('d');$file = fopen('./a.txt','w+');fprintf($file, '%04d-%02d-%02d', $year, $month, $day);htmlspecialchars( string $string, int $flags = ENT_COMPAT | ENT_HTML401, string $encoding = ini_get("default_charset"), bool $double_encode = true) : string 将特殊字符转换为 HTML 实体implode(string $glue, array $pieces) : string用 $glue返回一个用 $glue将一维数组的值连成的一个字符串。glue默认为空join,implode 函数的别名lcfirst(string $str) : string返回将字符串的第一个字母转为小写后的新字符串。$a = 'Hello';echo lcfirst($a);//helloltrim( string $str, string $character_mask = ?) : string 删除字符串结尾的空白字符(或其余指定的字符),并返回md5( string $str, bool $raw_output = false) : string计算字符串的 MD5 散列值number_format( float $number, int $decimals = 0, string $dec_point = ".", string $thousands_sep = ",") : string 格式化数字。如果只提供第一个参数,number的小数局部会被去掉并且每个千位分隔符都是英文小写逗号",";如果提供两个参数,number将保留小数点后的位数到你设定的值,其余同楼上;如果提供了四个参数,number 将保留decimals个长度的小数局部, 小数点被替换为dec_point,千位分隔符替换为thousands_sepord(string $string) : int返回指定字符的ASCII值。同chr()函数相同操作。print(string $arg) : int print 实际上也不是函数,所以能够不必圆括号突围参数列表。其和 echo的区别是echo能够有多个参数,而print只能有一个参数,且print总是返回1。printf(string $format, mixed $args = ?, mixed $... = ?) : int输入格式化后的字符串。rtrim(string $str, string $character_mask = ?) : string删除$str末端的空白字符,并返回。str_contains( string $haystack, string $needle) : bool查找字符串$haystack中是否蕴含字符串$needle,蕴含则返回true,否则返回false(PHP >= 8.0)str_ends_with(string $haystack, string $needle) : bool查看字符串$haystack是否以字符串$needle结尾,是则返回true,否则返回false(PHP >= 8.0)str_ireplace(mixed $search, mixed $replace, mixed $subject, int &$count = ?) : mixed函数返回一个字符串或者数组。该字符串或者数组是将subject中全副search都被replace替换掉当前的后果,不辨别大小写。str_replace()是此函数辨别大小写的版本。$a = "Hello world!This is my sister,Ella.";$str = str_ireplace('e','E',$a);echo $str;//HEllo world!This is my sistEr,Ella.$b = ['ella','jason','jack','musk'];$b = str_ireplace('a','aa',$b);print_r($b);//Array ( [0] => ellaa [1] => jaason [2] => jaack [3] => musk )str_pad( string $input, int $pad_length, string $pad_string = " ", int $pad_type = STR_PAD_RIGHT) : string 将字符串$input从左边(默认左边,能够抉择右边或两端)填充到指定长度$pad_length,如果没有指定填充的字符串$pad_string,则默认应用空格填充。$str = "A";$b = str_pad($str, 10);echo strlen($b); // 10$c = str_pad($str,10,'a');echo $c; //Aaaaaaaaaa$c = str_pad($str,10,'a', STR_PAD_LEFT);echo $c; //aaaaaaaaaA$c = str_pad($str,10,'a', STR_PAD_BOTH);echo $c; // aaaaAaaaaastr_repeat( string $input, int $multiplier) : string 返回$input反复$multiplier次之后的后果。如果multiplier为0,则返回空字符串。$str = 'Hello';$a = str_repeat($str,2);$b = str_repeat($str,0);echo $a; //HelloHelloecho $b; // str_split( string $string, int $split_length = 1) : array将一个字符串转换为数组,数组中的每个元素的长度由$split_length(大于0的整数)指定。当$split参数不指定时,则默认为单个字符组成一个元素。$str = 'hello';$b = str_split($str);print_r($b); // Array ( [0] => h [1] => e [2] => l [3] => l [4] => o ) $c = str_split($str, 3);print_r($c); // Array ( [0] => hel [1] => lo )str_starts_with( string $haystack, string $needle) : bool 判断字符串$haystack是否以字符串$needle结尾。(PHP >= 8.0)stripos( string $haystack, string $needle, int $offset = 0) : int 查找$needle在字符串$haystack中首次呈现的地位,不辨别大小写。如果未发现则返回false。stripos()函数是其辨别大小写的版本。$str = "hello world";$a = stripos($str, 'wo');echo $a; // 6$b = stripos($str, 'A');var_dump($b); // bool(false)stristr( string $haystack, mixed $needle, bool $before_needle = false) : string返回$haystack字符串从$needle第一次呈现的地位开始到结尾的字符串,不辨别大小写。strstr是其辨别大小写的版本。$str = "hello world";$a = stristr($str, 'wo');echo $a; //world$b = strstr($str,'Wo');var_dump($b); // bool(false)strlen( string $string) : int 返回给定字符串的长度strrchr( string $haystack, mixed $needle) : string函数返回 haystack字符串中的一部分,这部分以 needle的最初呈现地位开始,直到haystack开端,辨别大小写。不同于strstr的是,这个函数中,如果$needle参数有多个字符,则只应用第一个字符。$str = "hello wrld";$a = strrchr($str, 'wo');echo $a; // wrldstrrev( string $string) : string 反转字符串。$str = 'hello world';$b = strrev($str);echo $b; // dlrow ollehstrripos( string $haystack, string $needle, int $offset = 0) : int返回$haystack中$needle最初一次呈现的地位,不辨别大小写。函数strrpos()与此函数性能雷同,区别是辨别大小写。$str = "hello world";$a = strripos($str, 'wo');echo $a; // 6strtolower( string $string) : string 将字符串中所有字符都转为小写,并返回strtoupper( string $string) : string 将字符串中所有字符都转为大写,并返回substr_count( string $haystack, string $needle, int $offset = 0, int $length = ?) : int函数返回子字符串$needle在字符串$haystack中呈现的次数,辨别大小写。$str = "hello world";$a = substr_count($str, 'wo');echo $a; // 1$b = substr_count($str, 'Wo');echo $b; // 0substr( string $string, int $start, int $length = ?) : string返回指定字符串的子字符串。$str = 'Hello World';$a = substr($str, 2, 10);echo $a; // llo Worldtrim( string $str, string $character_mask = " \t\n\r\0\x0B") : string返回字符串$string两端去除首位空白字符或指定字符后的后果。ucfirst( string $str) : string 将字符串首字母转为大写,并返回ucwords( string $str, string $delimiters = " \t\r\n\f\v" ) : string将字符串中每个单词的首字母转为大写字母,并返回。wordwrap( string $str, int $width = 75, string $break = "\n", bool $cut = false) : string打断字符串为指定数量的字串$str = 'Hello World! this is my house!';$a = wordwrap($str, 3,'');var_dump($a); // string(30) "Hello\World!\this\is\my\house!"

February 22, 2021 · 3 min · jiezi

关于php:PHP中类的自动加载

在之前,咱们曾经学习过Composer主动加载的原理,其实就是利用了PHP中的类主动加载的个性。在文末有该系列文章的链接。 PHP中类的主动加载次要依附的是__autoload()和spl_autoload_register()这两个办法。明天咱们就来简略的看一下这两个办法的应用。 __autoload()做为一个曾经快要被淘汰的魔术办法,咱们只须要理解即可。如果在PHP7中应用这个办法的话,会报出过期的正告,零碎会倡议咱们应用spl_autoload_register()办法。 function __autoload($name){ include __DIR__ . '/autoload/' . $name . '.class.php';}$autoA = new AutoA();var_dump($autoA);当咱们实例化AutoA类时,以后的文件并没有这个类,也没有从其余文件中include或者require,这时,就会主动进入魔术办法__autoload()中。咱们在__autoload()办法中只须要去include这个类所在的文件即可。 spl_autoload_register()这个办法目前曾经代替了上述魔术办法主动加载类的性能。它是spl扩大库中的一个办法,spl扩大库当初曾经默认集成在了PHP中,大家能够释怀地间接应用。 spl_autoload_register()绝对于__autoload()的益处是它能够去注册一个__autoload(),并且实现并保护了一个__autoload()队列。原来在一个文件中只能有一个__autoload()办法,但当初,你领有的是一个队列。 这样,你就不须要将所有加载代码都写在一个__autoload()办法中,而是能够应用多个spl_autoload_register()去独自进行每个类的加载解决。 spl_autoload_register(function($name){ include __DIR__ . '/autoload/' . $name . '.class.php';});$autoA = new AutoA();var_dump($autoA);参考:深刻学习Composer原理(二) 应用include还是include_once在主动加载中,咱们只须要应用include就能够了,类并不会反复加载。 spl_autoload_register(function($name){ include __DIR__ . '/autoload/' . $name . '.class.php'; echo $name, PHP_EOL;});$autoA = new AutoA();var_dump($autoA);$autoA = new AutoA();var_dump($autoA);$autoA = new AutoA();var_dump($autoA);$autoB = new AutoB();var_dump($autoB);从代码中,咱们能够看出&dollar;name在屡次实例化类的状况下只被输入了一次。所以并不需要关怀会有类文件反复加载的问题。而且在大型框架中应用composer的时候会加载十分多的类,_once办法也会带来效率的问题。 总结这次的文章只是对类主动加载进行了简略的介绍,想深刻理解这方面常识的能够移步之前写过的Composer系列文章: 深刻学习Composer原理(一)深刻学习Composer原理(二)深刻学习Composer原理(三)深刻学习Composer原理(四)测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/201912/source/PHP%E4%B8%AD%E7%B1%BB%E7%9A%84%E8%87%AA%E5%8A%A8%E5%8A%A0%E8%BD%BD.php 参考文档: https://www.php.net/manual/zh/language.oop5.autoload.php各自媒体平台均可搜寻【硬核项目经理】

February 22, 2021 · 1 min · jiezi

关于php:PHP中的重载是个啥

很多面试官在面试的时候都会问一些面向对象的问题,面向对象的三大个性中,多态最次要的实现形式就是办法的重载和重写。然而在PHP中,只有重写,并没有齐全的重载能力的实现。 重写,子类重写父类办法。 // 重写class A{ public function test($a) { echo 'This is A:' . $a, PHP_EOL; }}class childA extends A{ public function test($a) { echo 'This is A child:' . $a, PHP_EOL; }}$ca = new childA();$ca->test(1);这个在PHP中是没有任何问题的,子类能够重写父类的办法。当实例化子类的时候,调用的就是子类实现的重写的办法。 重载,雷同办法名但参数数量或者类型不同。 class A{ function foo($a){ echo $a; } // Fatal error: Cannot redeclare A::foo() function foo($a, $b){ echo $a+$b; }}道歉,这样写的后果将会是间接的报错。PHP并不反对这样的重载能力。而在PHP的官网手册上,重载的定义是应用__set()、__get()、__call()、__callStatic()等魔术办法来对无法访问的变量或办法进行重载。这与咱们所学习的面向对象中的重载齐全不同,在手册中的note里也有很多人对此提出了疑难。当然,咱们明天并不会再去讲这些魔术办法的应用。对于它们的应用能够参考咱们之前写过的文章:PHP中的那些魔术办法(一)、PHP的那些魔术办法(二) 那么,在PHP中能够实现重载吗?当然能够,只不过会麻烦一些: // 重载class B{ public function foo(...$args) { if (count($args) == 2) { $this->fooAdd(...$args); } else if (count($args) == 1) { echo $args[0], PHP_EOL; } else { echo 'other'; } } private function fooAdd($a, $b) { echo $a + $b, PHP_EOL; }}$b = new B();$b->foo(1);$b->foo(1, 2);应用一个办法来调用其余办法,依据参数数量来进行判断,就能够实现参数数量不同的办法重载。 ...

February 21, 2021 · 2 min · jiezi

关于php:如何在Php中获得一个Final类的Protected的static成员属性

<?php final class ConstantOne { static protected $ERRNO_OK; static protected function init_ERRNO_OK() { return 0; } static protected function init_ErrorMsg() { return array( 0 => "OK", ); }}请答题:如何获取'0'? 谬误形式1class test extends ConstantOne{}ECHO test::init_ERRNO_OK();形式1起因:PHP Fatal error: Class test may not inherit from final class (ConstantOne) 谬误形式2var_dump(ConstantOne::init_ErrorMsg());形式2起因:PHP Fatal error: Uncaught Error: Call to protected method ConstantOne::init_ErrorMsg() 思考staitc的话,我能够不实例化就能够调用,protected的话,能够实例化本类或者父类调用,然而要害是还有个final润饰。Final润饰的类不能被继承,所以只能本类调用,未实例的类调用static的办法又说是因为protected的。static实质是类的办法, 解决思路/** * Base class for constant Management */abstract class BaseConstant{ /** * Don't instanciate this class */ protected function __construct() {} /** * Get a constant value * @param string $constant * @return mixed */ public static function get($constant) { if(is_null(static::$$constant)) { // echo sprintf('static::init_%s', $constant); static::$$constant = call_user_func( sprintf('static::init_%s', $constant) ); } return static::$$constant; }}final class ConstantTwo extends BaseConstant { static protected $ERRNO_OK; static protected function init_ERRNO_OK() { return 100; } static protected function init_ErrorMsg() { return array( 100 => "OK", ); }//以下这也也能够 public static function outOK (){ echo static::init_ERRNO_OK(); }}echo ConstantTwo::get('ERRNO_OK');echo ConstantTwo::outOK();

February 20, 2021 · 1 min · jiezi

关于php:PHP面试题一

一、根底篇1,数组处理函数: array_change_key_case(array $array [, int $case = CASE_LOWER]) : array将数组 array 中的所有键名全副改为大写或小写,通过 $case 参数管制。case 参数可用值为:CASE_LOWER(默认,小写),CASE_UPPER(大写),返回被批改过键名后的数组。array_column(array $input, mixed $column_key [, minxed $index_key=null]) : array返回input数组中值为column_key的列,如果指定了$index_key参数,则返回的数组中,$index_key这一列的值将作为$column_key这一列值的键$a = array( array('name' => 'zhangsan', 'age'=>12), array('name' => 'lisi', 'age'=>13), array('name' => 'wangwu', 'age'=>14) ); $b = array_column($a, 'name');print_r($b);//Array ( [0] => zhangsan [1] => lisi [2] => wangwu )$c = array_column($a, 'age', 'name');print_r($c);//Array ( [zhangsan] => 12 [lisi] => 13 [wangwu] => 14 )array_combine(array $keys, array $values) : array 返回一个数组,用来自$key的数组的值作为键名,用来自$values数组的值作为相应的值。如果$keys和$values中的数组元素个数不统一,则会报错。$keys数组中非法的值将会被转换为字符串类型$keys = array("zhangsan","lisi","wangwu");$values = array(11,12,13);$c = array_combine($keys, $values);print_r($c);//Array ( [zhangsan] => 11 [lisi] => 12 [wangwu] => 13 )array_count_values(array $array) : array 统计数组$array中所有的值呈现的次数。返回一个关联数组,数组的键为$array数组的值,值为其呈现的次数。如果$array数组中呈现非字符串或整型的元素,则会报错。$a = ['zhangsan',1,'lisi','lisi','a'];$b = array_count_values($a);print_r($b);//Array ( [zhangsan] => 1 [1] => 1 [lisi] => 2 [a] => 1 )array_diff(array $array1, array $array2 [, array $array...]) : array 比照$array1和其余的一个或多个数组,返回在$array1中然而不在其余array数组里的值。    含有相似性能的函数还有:array_diff_assoc、array_diff_key、array_diff_uassoc、array_diff_ukey ...

February 20, 2021 · 3 min · jiezi

关于php:API接口请求的配置化封装

抛出问题问题1:日常开发中,咱们都会遇到接口类的申请,各种各样的第三方接口,以及外部接口等,大家都是怎么方便快捷的保护这些接口的疾速申请呢?问题2:面对第三方的接口,对接的时候记得,后续查找会不会感觉找不到在哪了呢?或者查找归类比拟麻烦呢?问题3:相似的第三方接口,你是否写反复的办法调用和处理结果呢?……如果你有下面的相似问题,是否会思考优化呢?也就是把几户一样的接口做成配置化,不论是调用还是前期保护都比拟不便呢?本着“不便别人,造福本人”的开发准则,必须从优解决,安顿! API接口例子// 接口1地址: $url = 'https://www.test.com/api/test';参数: $param = array('id' => 1, 'code' => '123', 'status' => 1);返回: array('code' => 200, 'msg' => '');// 接口2地址: $url = 'https://www.test.com/api/test2';参数: $param = array('type' => 1, 'num' => '');返回: array('code' => 200, 'msg' => '');// 接口N针对下面的两个接口,如果做成配置化的申请,也就是,写好对立的申请入口,对于后续新增同样接口,只须要依据格局配置接口地址以及申请参数即可。 接口申请类设计准则繁多入口接口信息可配置化对立校验接口参数,避免非法参数申请对立的申请办法和解决接口返回数据格式统一……申请类的繁多入口繁多入口是指每个接口申请,公共申请这个办法即可,此办法须要传配置的接口键的值,以及申请参数等,具体能够看代码里的正文阐明。 /** * 接口申请入口 * @param string $action 配置的接口键名 * @param array $param 申请参数 * @param bool $is_format 是否格式化申请后果 * @param bool $debug 是否开启调试模式 * @return array|string 返回申请后果 */public static function request($action = '', $param = array(), $is_format = true, $debug = false){ // 初始化 self::initParam(); // 校验参数,并设置申请参数 $check = self::setApiParam($action, $param); if (!$check) { return self::$result; } // 发动接口申请 $response = self::curlByPost(self::$url, self::$param, self::$token, self::$type); // 无需格式化间接返回 if (!$is_format) { return $response; } // 设置返回值 self::setResult($response); // 是否调试输入申请信息 if ($debug) { self::echo_msg("url: " . self::$url); self::echo_msg("token: " . self::$token); self::echo_msg("param: " . json_encode(self::$param)); self::echo_msg("response: " . $response); } return self::$result;}配置接口信息下面的2个接口,间接做成配置化的模式,此配置api_config的键的名字能够自定义,最好命名为接口的阐明,url为接口地址,type为Content-Type的类型抉择,param就是接口参数,具体的参数配置看正文即可。 ...

February 20, 2021 · 6 min · jiezi

关于php:mysql一张表到底能存多少数据

前言程序员平时和mysql打交道肯定不少,能够说每天都有接触到,然而mysql一张表到底能存多少数据呢?计算依据是什么呢?接下来咱们逐个探讨 常识筹备数据页在操作系统中,咱们晓得为了跟磁盘交互,内存也是分页的,一页大小4KB。同样的在MySQL中为了进步吞吐率,数据也是分页的,不过MySQL的数据页大小是16KB。(确切的说是InnoDB数据页大小16KB)。具体学习能够参考官网咱们能够用如下命令查问到。 mysql> SHOW GLOBAL STATUS LIKE 'innodb_page_size';+------------------+-------+| Variable_name | Value |+------------------+-------+| Innodb_page_size | 16384 |+------------------+-------+1 row in set (0.00 sec)明天咱们数据页的具体构造指针等不深究,晓得它默认是16kb就行了,也就是说一个节点的数据大小是16kb 索引构造(innodb)mysql的索引构造咱们应该都晓得,是如下的b+树结构通常b+树非叶子节点不存储数据,只有叶子节点(最上面一层)才存储数据,那么咱们说回节点,一个节点指的是(对于上图而言) 每个红框选中的局部称为一个节点,而不是说某个元素。理解了节点的概念和每个节点的大小为16kb之后,咱们计算mysql能存储多少数据就容易很多了 具体计算方法根节点计算首先咱们只看根节点 比方咱们设置的数据类型是bigint,大小为8b在数据自身现在还有一小块空间,用来存储下一层索引数据页的地址,大小为6kb 所以咱们是能够计算出来一个数据为(8b+6b=14b)的空间(以bigint为例)咱们刚刚说到一个数据页的大小是16kb,也就是(161024)b,那么根节点是能够存储(161024/(8+6))个数据的,后果大略是1170个数据如果跟节点的计算方法计算出来了,那么接下来的就容易了。 其余层节点计算第二层其实比拟容易,因为每个节点数据结构和跟节点一样,而且在跟节点每个元素都会延长进去一个节点,所以第二层的数据量是1170*1170=1368900,问题在于第三层,因为innodb的叶子节点,是间接蕴含整条mysql数据的,如果字段十分多的话数据所占空间是不小的,咱们这里以1kb计算,所以在第三层,每个节点为16kb,那么每个节点是能够放16个数据的,所以最终mysql能够存储的总数据为 1170 1170 16 = 21902400 (千万级条) 其实计算结果与咱们平时的工作教训也是相符的,个别mysql一张表的数据超过了千万也是得进行分表操作了。 总结最初用一张图片总结一下明天探讨的内容,心愿您能喜爱

February 20, 2021 · 1 min · jiezi

关于php:Mac下软件管理工具brew更换国内源及常用命令

更换国内源:官网链接 cd "$(brew --repo)" git remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core" git remote set-url origin https://mirrors.aliyun.com/homebrew/homebrew-core.git echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.bash_profile'source ~/.bash_profile装置多个版本软件,例如php brew install php@7.4brew install php // 默认装置php8brew link --overwrite php@7.4 //切换版本查找软件 brew updatebrew search xxx查看软件装置状况 brew info xxx

February 17, 2021 · 1 min · jiezi

关于php:Swoole-v46-版本新特性之-HttpResponse-增强

在 4.6 版本中,对 Swoole\Http\Response 进行了一些加强: 增加 Http\Response::isWritable (db56827) (@matyhtf)加强 Response\create() 办法,能够独立于 Server 应用 (#3998) (@matyhtf)再来看一下上一篇文章的示例代码: use Swoole\Server;use Swoole\Http\Request;$server = new Server('127.0.0.1', 9501);$server->on('Receive', function (Server $server, $fd, $reactor_id, $data) { /** @var Request $request */ $request = Request::create(); $request->parse($data); $body = 'Hello, Swoole'; $body_len = strlen($body); $send_data = "HTTP/1.1 200 OK\r\nServer: swoole-server\r\nContent-Type: text/html;charset=utf-8\r\nContent-Length: {$body_len}\r\nConnection: keep-alive\r\n\r\n{$body}"; $server->send($fd, $send_data);});$server->start();须要用户自行处理$send_data的数据,而此次加强当前,能够这样应用: use Swoole\Server;use Swoole\Http\Request;use Swoole\Http\Response;$server = new Server('127.0.0.1', 9501);$server->on('Receive', function (Server $server, $fd, $reactor_id, $data) { /** @var Request $request */ $request = Request::create(); $request->parse($data); /** @var Response $response */ $response = Response::create($server, $fd); $response->status(200); $response->end('Hello, Swoole');});$server->start();还能够这样: ...

February 9, 2021 · 2 min · jiezi

关于php:Swoole-v463-版本发布祝大家-2021-春节快乐

牛年春节在即,Swoole 也迎来了 2020年(农历)的最初一个版本。 在此感激为 Swoole 的代码、文档以及生态方面做出奉献的小伙伴,也期待有更多的小伙伴退出\~ 祝大家 2021 牛年春节快乐,Bug 全走开。 v4.6.3 版本次要是一个 Bug 修复版本,没有向下不兼容改变。 新增了 Swoole\Coroutine\go 和 Swoole\Coroutine\defer 函数,这个操作次要避免用户手动敞开了短名,去复制粘贴运行示例代码时会报错的问题use function Swoole\Coroutine\go;use function Swoole\Coroutine\run;use function Swoole\Coroutine\defer;run(function () { defer(function () { echo "co1 end\n"; }); sleep(1); go(function () { usleep(100000); defer(function () { echo "co2 end\n"; }); echo "co2\n"; }); echo "co1\n";});如果用户晓得 Content-Length 的长度,在此版本中也容许用户自行设置 Content-Length 的 HTTP 头。 用户设置的 Content-Length HTTP 头会笼罩底层计算的 Content-Lengthuse Swoole\Http\Server;use Swoole\Http\Request;use Swoole\Http\Response;$http = new Server('0.0.0.0', 9501);$http->on('Request', function (Request $request, Response $response) { $msg = 'Hello, Swoole'; $response->header('Content-Length', strlen($msg)); $response->end($msg);});$http->start();更新日志上面是残缺的更新日志: ...

February 9, 2021 · 1 min · jiezi

关于php:踩坑tp5模板视图中js使用url方法传参问题

@TOC 问题形容:最近,冷月在应用tp5搭建集体博客后盾踩到了一个坑,在tp5自带的视图模板引擎中。 其中有一个利用场景是js的 window.location.href 跳转到指定页面并且传递文章id 于是冷月采纳了上面2种形式进行操作,均不能胜利解析到id的值,而是间接将变量名拼接成字符串输入。代码及谬误实例如下: /** * Created by 冷月小白. * 微信公众号: 学长冷月var articleID = $("#articleID").val(); //采纳jQuery的选择器window.location.href = "{:url('article/markdown',['id'=>"+articleID+"])}"; // 解析失败window.location.href = "{:url('article/markdown','id=" + articleID + "')}"; // 解析失败 */ 解决办法:采纳上面的拼接形式,则可能正确解析,获取到id的值。 /** * Created by 冷月小白. * 微信公众号: 学长冷月 window.location.href = "{:url('article/markdown')}?id=" + articleID; //解析胜利 */ 如果这篇博文有帮忙到您,能够帮冷月点一个赞或者加一个关注哦! 欢送关注我的公众号:学长冷月,取得独家整顿的学习资源和日常干货推送。如果您对我的专题内容感兴趣,也能够关注我的博客:www.lengyueit.cn

February 9, 2021 · 1 min · jiezi

关于php:过年假期这两天撸了个laravel的starter欢迎大家使用及star

把日常开发中的罕用性能抽出来做一个starter,防止每次开新我的项目时消耗的大量反复工作,该repo会长期保护,欢送大家star。在应用中如有bug或体验问题,请提issue。 x1a0xv4n/laravel-starter: ???? Your next laravel-api-starter in 30 seconds 基本功能api模块 dingo????jwt-auth 多表多用户零碎隔离????jwt-auth黑名单fractal????RSA接口加密(前台用户零碎借鉴gadmin,应用RSA加密)封装好的Exception异样类记录每条申请的参数和响应-后置中间件admin模块 CORS????RBAC????后盾log-后置中间件????common模块 文件上传(七牛云、并记录附件)????短信发送????redis罕用操作RedisService、redis锁RedisLock????敏感词性能????罕用辅助函数库????其余 laravel分模块的最佳实际????MRSC模型(已留出文件夹,具体业务相干不写)????swagger(php的swagger不好用,不写)????反对切换dev、test、prod环境配置????反对我的项目初始化 数据库迁徙工具(自身jwt须要的user表,也须要迁徙工具)更新goutils等引入拓展包的版本laravel谬误日志的最佳实际代码品质 php-cs-fixerphp-cs-fixer fix $PWD --config=cs.php动态检测工具:基于phpstan实现的larastan./vendor/bin/phpstan analyse罕用性能 第三方登录(微信登录、qq登录)第三方领取(微信领取、支付宝)url转二维码图片验证码部署手动部署clone我的项目。gcl git@github.com:x1a0xv4n/laravel-starter.git切换分支。切换分支到对应laravel版本,master分支默认为laravel最新版本git checkout -b origin/target-version-branch配置文件。开发环境下,请复制.env.prod为.env.dev,并填写根本配置如数据库、redis、dingo等,如有问题,请发issue。sql文件。执行根目录下的laravel_starter.sql。docker-compose部署临时没空,过两天再写

February 9, 2021 · 1 min · jiezi

关于php:PHP-xdebug-分析代码性能瓶颈

通常启用了xdebug插件,性能测试输入文件会随同生成,通常是以cachegrind.out.xxxx 文件存在。 该文件能够通过第三方工具来进行代码性能剖析。 但如果本地有多个我的项目/网站,所有的profile 都输入到一个文件中了,这样并不不便前面进行性能剖析。 自定义profile 文件名称能够通过配置xdebug.profiler_output_name 参数来设置输入文件名称,局部参数如下: 符号含意配置样例样例文件名%c当前工作目录的crc32校验值cachegrind.out.%ccachegrind.out.1258863198%p以后服务器过程的pidcachegrind.out.%pcachegrind.out.9685%r随机数cachegrind.out.%rcachegrind.out.072db0%s脚本文件名(注)cachegrind.out.%scachegrind.out._home_httpd_html_test_xdebug_test_php%tUnix工夫戳(秒)cachegrind.out.%tcachegrind.out.1179434742%uUnix工夫戳(微秒)cachegrind.out.%ucachegrind.out.1179434749_642382%H$_SERVER['HTTP_HOST']cachegrind.out.%Hcachegrind.out.localhost%R$_SERVER['REQUEST_URI']cachegrind.out.%Rcachegrind.out._test_xdebug_test_php_var=1_var2%Ssession_id (来自$_COOKIE 如果设置了的话)cachegrind.out.%Scachegrind.out.c70c1ec2375af58f74b390bbdd2a679d%%%字符cachegrind.out.%%cachegrind.out.%%编辑php.ini 配置文件: xdebug.profiler_output_name = cachegrind.out.%H而后重启 php server。 在Mac 下,profile 文件寄存于/var/tmp/目录中。 性能剖析在Mac 下,有MacCallGrind 和 qcachegrind 能够应用,不过前者是免费,间接通过Apple Store下载,后者是收费。须要手动装置。 装置graphviz,用来Call Graph性能: $ brew install graphviz装置 qcachegrind: $ brew install qcachegrind装置实现之后,就能够关上 qcachegrind 利用了,图形界面如下: 其余不过须要留神,开启了profile文件输入之后,如果本地我的项目多的话,很容易占用磁盘大面积空间,下图是我半年左右没有清理的状态: 能够应用命令进行清理: $ sudo rm -fr /private/var/tmp/cachegrind.out.*参考链接应用xdebug对php进行profile的输入php+xdebug+qcachegrind(mac)性能剖析

February 7, 2021 · 1 min · jiezi

关于php:我是如何从-php-转型写-go-的

原本想连续上一个公众号 <<不定期更新的日常>>系列,然而想想还是先写下这篇吧。心愿对那些刚转型 Go 或者有动向转型的小伙伴有所帮忙。 终点去年七月初的时候,在上家公司感觉到毕业以来第一次瓶颈,加上小公司我的项目半凉的状态,随即提出到职。在交接的过程中,我开始投递简历进去面试,因为学历并不是很好,加之在开源世界并没有什么拿得出手的我的项目,也就没对大厂抱有心愿,整个期间就面了三家公司,拿了其中两家 offer,一家做直播的,一家做电商行业的,抉择了电商的那家,不算很大,一千多人还是有的,而后就实现了到职到就任的无缝连贯,当初入职半年多了。 面试的时候面的就是 php 岗位,因为也没别的语言教训,入职第一周没有具体的工作安顿,就是相熟环境。第二周开始接了点小需要,评审之后看了下也不是很难。不过新公司第一次上线多少还是有点忐忑的,好在没出啥问题,一切正常。 来到八月份,因为咱们做的是一个全新的我的项目,我开始搭建一些根底的,和业务没什么牵扯的模块,还对接了一些平台。 大略到九月初的时候,因为某种场景不太适宜应用 php,加上咱们无意识的想把纯业务的和底层通用模块做拆散。理解到其余部门在搭建他们的中台业务也是把技术栈从 php 迁徙到 Go,加上外部也有专门的部门去搭建 Go 框架、封装专用进步业务开发效率的包……,而后老大就过去问我,有没有动向搞 Go,我的答复是求之不得!!! 我大略花了一天的时候,过一下语法。我之前提到过,看了学院君的 Go 入门教程。简略的把下面的根底语法过了一遍,全程敲下来。因为之前有偷偷学过一点,所以没花多少工夫就复原了之前为数不多的功力。这时候曾经能看懂这样简略的代码了。 package mainimport "fmt"func main() { go func() { fmt.Println("打印不?") }()}如果你始终寂静在 php-fpm 那一套,导致的景象可能是你不晓得下面的运行后果。别不信,好多人真的不晓得为什么,当然我没有黑语言的意思。 接着因为公司外部的框架有基于 gin。我就把 gin 官网的 demo 本人全敲了一遍,我也倡议你这样干。初学者,要学会从模拟做起,模拟当然就是入手操作。 而后老大就让一个大佬给我开了一个基于公司外部框架构建的一个业务我的项目,不是很大,我跑下来之后,依据 readMe 进行系列操作,运行过程也有点崎岖,还踩到一个坑,虚心求教了大佬后才解决。依据这个我的项目去理解它的运行流程、生命周期以及波及到的知识点……,这时候千万不要陷入代码细节,细节是魔鬼! 大略过了三天,我就开始入手写咱们部门的我的项目了,始终写到当初。这个过程很乏味,我常常在后一天发现前几天实现的并不好, 而后就是继续重构,继续调整。 我是咋么发现的呢? 当然是学习!首先,那段时间除了在公司实现需求过程中,遇到 Go 相干不明确的点,比方包之类的,那就去官网搜,或者看一些文章。遇到外部框架不明确的中央,就去求教大佬,大佬对我总是那么和颜悦色。 上班后,我也没闲着,疯狂的补充 Go 相干的常识,记得我有次看 sync.Mutex 外面定义的常量不明确,前面就专门去查了材料。其实是很根底的货色,代码如下, const ( mutexLocked = 1 << iota // mutex is locked mutexWoken mutexStarving mutexWaiterShift = iota)func main() { fmt.Println("mutexLocked的值",mutexLocked) fmt.Println("mutexWoken的值",mutexWoken) fmt.Println("mutexStarving的值",mutexStarving) fmt.Println("mutexWaiterShift的值",mutexWaiterShift) //为什么后果是:// mutexLocked的值 1// mutexWoken的值 2// mutexStarving的值 4// mutexWaiterShift的值 3}想想那时候就乏味。 ...

February 6, 2021 · 1 min · jiezi

关于php:PHP怎么遍历对象

对于php来说,foreach是十分不便好用的一个语法,简直对于每一个PHPer它都是日常接触最多的申请之一。那么对象是否能通过foreach来遍历呢? 答案是必定的,然而有个条件,那就是对象的遍历只能取得它的公共属性。 // 一般遍历class A{ public $a1 = '1'; public $a2 = '2'; public $a3 = '3'; private $a4 = '4'; protected $a5 = '5'; public $a6 = '6'; public function test() { echo 'test'; }}$a = new A();foreach ($a as $k => $v) { echo $k, '===', $v, PHP_EOL;}// a1===1// a2===2// a3===3// a6===6不论是办法还是受爱护或者公有的变量,都无奈遍历进去。只有公共的属性能力被遍历进去。其实,咱们之前在讲设计模式时讲过的迭代器模式就是专门用来进行对象遍历的,而且PHP曾经为咱们筹备好了相干的接口,咱们只须要去实现这个接口就能够实现迭代器模式的创立了。具体的内容能够参考之前的设计模式系列文章:PHP设计模式之迭代器模式 // 实现迭代器接口class B implements Iterator{ private $var = []; public function __construct($array) { if (is_array($array)) { $this->var = $array; } } public function rewind() { echo "rewinding\n"; reset($this->var); } public function current() { $var = current($this->var); echo "current: $var\n"; return $var; } public function key() { $var = key($this->var); echo "key: $var\n"; return $var; } public function next() { $var = next($this->var); echo "next: $var\n"; return $var; } public function valid() { $var = $this->current() !== false; echo "valid: {$var}\n"; return $var; }}$b = new B([1, 2, 3, 4]);foreach ($b as $k => $v) { echo $k, '===', $v, PHP_EOL;}// rewinding// current: 1// valid: 1// current: 1// key: 0// 0===1// next: 2// current: 2// valid: 1// current: 2// key: 1// 1===2// next: 3// current: 3// valid: 1// current: 3// key: 2// 2===3// next: 4// current: 4// valid: 1// current: 4// key: 3// 3===4// next:// current:// valid:如果明天的文章只是讲之前讲过的迭代器模式,那就太没意思了,所以,咱们还要来学习一个更有意思的利用。那就是让对象能够像数组一样进行操作。这个其实也是应用PHP早已为咱们筹备好的一个接口:ArrayAccess。 ...

February 6, 2021 · 2 min · jiezi

关于php:php-获取私有属性的值

最近要导入一下数据,要把一个我的项目的局部数据导入到另一个我的项目中 采纳laravel的chunkById段落查询方法,一次查问2K,而后批量入库,因为这个表没啥改变,能够间接查问后导入 遇到的问题是,查问后的数据属性是一个数组,要手动组装下能力间接入库,字段有点多,试想能不能间接拿到这个属性数据而后丢到数组里间接入库 查问出的数据是这样是公有属性 间接 (array)$value 后是这样 那么间接$arrTemp['x00*x00attributes']应该就能够,试了下的确行 封装下: public function getProtectedValue($obj, $name) { $array = (array)$obj; $prefix = chr(0).'*'.chr(0); return $array[$prefix.$name];}截图中x00对应的ASCII码为0,用chr将0的ASCII码转换为字符串,即chr(0)对应ASCII码为x00,而后拼接下*就OK 调整后的代码为 $arrTemp = $this->getProtectedValue($value, 'attributes');

February 5, 2021 · 1 min · jiezi

关于php:PHP匿名类的用法

在PHP7之后,PHP中退出了匿名类的个性。匿名类和匿名办法让PHP成为了更现代化的语言,也让咱们的代码开发工作越来越不便。咱们先来看看匿名类的简略应用。 // 间接定义$objA = new class{ public function getName() { echo "I'm objA"; }};$objA->getName();// 办法中返回function testA(){ return new class { public function getName() { echo "I'm testA's obj"; } };}$objB = testA();$objB->getName();// 作为参数function testB($testBobj){ echo $testBobj->getName();}testB(new class{ public function getName() { echo "I'm testB's obj"; } });一次性给出了三种匿名类的应用办法。匿名类能够间接定义给变量,能够在办法中应用return返回,也能够当做参数传递给办法外部。其实,匿名类就像一个没有当时定义的类,而在定义的时候间接就进行了实例化。 // 继承、接口、访问控制等class A{ public $propA = 'A'; public function getProp() { echo $this->propA; }}trait B{ public function getName() { echo 'trait B'; }}interface C{ public function show();}$p4 = 'b4';$objC = new class($p4) extends A implements C{ use B; private $prop1 = 'b1'; protected $prop2 = 'b2'; public $prop3 = 'b3'; public function __construct($prop4) { echo $prop4; } public function getProp() { parent::getProp(); echo $this->prop1, '===', $this->prop2, '===', $this->prop3, '===', $this->propA; $this->getName(); $this->show(); } public function show() { echo 'show'; }};$objC->getProp();匿名类和一般类一样,能够继承其余类,能够实现接口,当然也包含各种访问控制的能力。也就是说,匿名类在应用方面和一般类并没有什么不同。但如果用get_class()获取类名将是零碎主动生成的类名。雷同的匿名类返回的名称当然也是雷同的。 ...

February 5, 2021 · 1 min · jiezi

关于php:2快速排序PHP版

<?phpfunction quickSort(&$array,$left,$right) { if ($left > $right) return; $middle = partition($array,$left,$right); quickSort($array,$left,$middle-1); quickSort($array,$middle+1,$right);}function partition(&$array,$left,$right) { $v = $array[$left]; $j = $left; for ($i=$left;$i<=$right;$i++) { if($array[$i] < $v) { $temp = $array[$j+1]; $array[$j+1] = $array[$i]; $array[$i] = $temp; $j++; } } $temp = $array[$j]; $array[$j] = $array[$left]; $array[$left] = $temp; return $j;}function makeArray($n) { $array = []; for ($i = 0;$i<$n;$i++) { $array[$i] = mt_rand(0,$n); } return $array;}$array = makeArray(100);quickSort($array,0,count($array)-1);echo implode(',',$array);

February 4, 2021 · 1 min · jiezi

关于php:1归并排序PHP版

最新在学习算法与数据结构,2018年初的买的课程,到2020年初才开始看。因为本人的半路才进去学习的,之前重来都不懂算法和数据结构,也不明确为什么算法和数据结构是一起的。开始学这门课后,才晓得,算法是数据结构优化,数据-构造(存储数据的形式)是相铺相成的。为什么Mysql-存储引擎为Innodb,存储索引的构造为B+数呢?数组,二叉树,堆又有什么作用呢? 代码如下: <?phpfunction mergeSort(&$array,$left,$right) { if ($left >= $right) { return; }; $middle = floor(($right+$left)/2); mergeSort($array,$left,$middle); mergeSort($array,$middle+1,$right); merge($array,$left,$middle,$right);}function merge(&$array,$left,$middle,$right) { $tempArr = []; for($i = $left;$i<=$right;$i++) { $tempArr[$i-$left] = $array[$i]; } $i = $left; $j = $middle + 1; for($k=$left;$k<=$right;$k++) { if ($i > $middle) { $array[$k] = $tempArr[$j-$left]; $j++; } elseif ($j>$right) { $array[$k] = $tempArr[$i-$left]; $i++; } elseif($tempArr[$i-$left] > $tempArr[$j-$left]) { $array[$k] = $tempArr[$j-$left]; $j++; } else { $array[$k] = $tempArr[$i-$left]; $i++; } }}function makeArray($n) { $array = []; for ($i = 0;$i<$n;$i++) { $array[$i] = mt_rand(0,$n); } return $array;}$array = makeArray(100);mergeSort($array,0,count($array)-1);echo implode(",",$array);须要解释几个参数:middle:相当于一个数组,每次从数组的两头离开。tempArr:合并的时候,须要复制出一个雷同空间大小的数组i:数组中被离开的右边的值j:数组中两头的第一个值 ...

February 4, 2021 · 1 min · jiezi