关于php:php人像分割-人像抠图-证件照换底色-在线制作证件照API-Ai智能抠图

需要证件照在咱们生存中也是随时都须要的,例如去办证、体检、或者是参加考试等,但不是每个人都会P图,有些时候并不需要问了一个电子版证件照去照相馆拍照,所以能够利用技术开发一个在线工具,即拍即出图。 筹备本文应用百度AI开放平台提供的收费人像宰割API实现抠图,这点百度是很良心的,看过很多同款API,其余都得花钱,收费体验的次数也就几次、几十次调用,而百度间接就是50000次!况且百度是做AI比拟业余的,解决进去的后果很好! 1、先申请APIhttps://ai.baidu.com/tech/bod... 2、创立利用后就能取得API Key和Secret Key 3、开发文档https://ai.baidu.com/ai-doc/B... 4、写代码(1)获取access_token获取获取access_token文档:https://ai.baidu.com/docs#/Au... 代码获取获取access_token代码 <?phpheader("Content-type:application/json"); //初始化 CURL$ch = curl_init(); //指标服务器地址 curl_setopt($ch, CURLOPT_URL, 'https://aip.baidubce.com/oauth/2.0/token'); //设置上传的文件curl_setopt($ch, CURLOPT_POST, true);$data = array( 'grant_type' => 'client_credentials', 'client_id' => '填写你的', 'client_secret' => '填写你的');curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // 对认证证书起源的查看curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);// 从证书中查看SSL加密算法是否存在curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //获取的信息以文件流的模式返回,而不是间接输入curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //申请头数组$headers[] = "user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3947.100 Safari/537.36";//设置申请头curl_setopt($ch, CURLOPT_HTTPHEADER,$headers); //发动申请$result = curl_exec($ch);echo $result; //敞开申请curl_close($ch); ?>图片转base64工具:http://tool.chinaz.com/tools/... 申请接口,人像宰割代码 <?phpheader("Content-type:text/html;charset=utf-8"); //初始化 CURL$ch = curl_init(); //指标服务器地址 curl_setopt($ch, CURLOPT_URL, 'https://aip.baidubce.com/rest/2.0/image-classify/v1/body_seg'); //设置上传的文件curl_setopt($ch, CURLOPT_POST, true);$data = array( 'access_token' => '上一步获取到的access_token', 'image' => '这里要用base64去掉图片头的base64代码' );curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // 对认证证书起源的查看curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);// 从证书中查看SSL加密算法是否存在curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //获取的信息以文件流的模式返回,而不是间接输入curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //申请头数组$headers[] = "Content-Type:application/x-www-form-urlencoded";//设置申请头curl_setopt($ch, CURLOPT_HTTPHEADER,$headers); //发动申请$result = curl_exec($ch); // 解析json$arr_result = json_decode($result);$imgurl = $arr_result->foreground; // 输入图片echo "<img src='./8.jpg' style='background:#f00'/>";echo "<img src='data:image/png;base64,".$imgurl."' style='background:#f00'/><br/>";echo "<img src='data:image/png;base64,".$imgurl."' style='background:#39f'/>";echo "<img src='data:image/png;base64,".$imgurl."' style='background:#fff'/>"; //敞开申请curl_close($ch); ?>最初就返回了抠图胜利的base64图片代码,也是不带图片头的,如果须要展现图片,就得拼接data:image/jpg;base64,就能够了! ...

April 25, 2021 · 1 min · jiezi

关于php:php基础知识4运算符

php是一门计算机编程语言,次要利用于开发web利用(网站建设等),本系列博客从php根底语法登程,介绍php基础知识。使读者深入浅出的学习到编程的乐趣。 本系列博客将解说以下9个知识点,变量、常量、数据类型、运算符、数组、流程管制(程序、抉择、循环)、函数、文件解决、面向对象 每篇文章都会在文末留下一个课后作业,答案获取请私聊我,大家能够在评论区踊跃探讨,共同进步 运算符的概念运算符是进行各类运算所应用的符号,其实咱们在小学时就曾经接触过运算符的概念了。小学最开始学习的加减乘除(+ - * / )就是最简略的算数运算符。 本节,次要解说算术运算符、逻辑运算符、赋值运算符、比拟运算符、三元运算符。 运算符的分类算术运算符进行加减乘除所应用的符号,加(+),减(-),乘(*),除(/) <?php/** * Created by 冷月小白. * 微信公众号: 学长冷月 */echo 1 + 1; //输入2echo 2 - 1; //输入1echo 3 * 1; //输入3echo 3 / 1; //输入3逻辑运算符进行逻辑运算,次要是与、或、非。逻辑运算符返回的是布尔类型(bool),也就是说只会返回真或假。与(&&),都为真才为真;或(||),一个为真都为真;非(!),取反。 <?php/** * Created by 冷月小白. * 微信公众号: 学长冷月 */echo true && true; //返回trueecho true || false; //返回trueecho !true; //返回false赋值运算符根本的赋值运算符是 "="。它意味着左操作数被设置为右侧表达式的值。 <?php/** * Created by 冷月小白. * 微信公众号: 学长冷月 */$a = 1;//将变量a赋值为1比拟运算符用于比拟2个数的值,>、>=、<、<=、 \=\=(数值等则返回true)、===(数值和数据类型等才返回true) <?php/** * Created by 冷月小白. * 微信公众号: 学长冷月 */echo 2>1; //trueecho 2>=1;//trueecho 2<1; //falseecho 2<=1;//falseecho 2=="2";//trueecho 2==="2";//false三元运算符语法格局:条件 ? 后果1 : 后果2 问号后面是判断的条件,如果满足条件返回后果1,不满足时返回后果2。 ...

April 25, 2021 · 1 min · jiezi

关于php:PHP中的输出缓冲控制

在 PHP 中,咱们间接进行 echo 、 或者 print_r 的时候,输入的内容就会间接打印进去。然而,在某些状况下,咱们并不想间接打印,这个时候就能够应用输入缓冲管制来进行输入打印的管制。当然,这一套性能并不仅限出针对打印的内容,咱们还能够做其它一些操作,这个咱们放到最初再说。 革除输入首先,咱们先来看看不让 echo 之类的内容打印输出。 ob_start();echo 111, PHP_EOL;echo "aaaa", PHP_EOL;ob_end_clean();置信有不少小伙伴应该见过 ob_start() 这个函数,它的作用就是开始一段输入缓冲管制。在 ob_start() 之后的代码中的输入语句都会进入输入缓冲区,这个时候,如果咱们调用了 ob_end_clean() 、 ob_clean() 或者 ob_get_clean() ,则不会有任何输入了。它们三个的作用都是革除输入缓冲区的内容。具体的区别大家能够参考文章最初给出的函数阐明或者官网文档。 取得输入缓冲区的内容ob_start();echo 111, PHP_EOL;echo "aaaa", PHP_EOL;$v = ob_get_contents();ob_end_clean();echo $v;下面说过,应用了 ob_end_clean() 就会革除输入缓冲区外面的内容,然而在这段代码中,咱们应用 ob_get_contents() 函数间接将缓冲区的内容赋值给了变量 \$v 。这时候,$v 中就有了后面两段 echo 中的内容,也就是说,这个一套操作咱们就拿到了自身应该输入的内容,并将它保留在了变量中。这样做有什么用呢?咱们能够取得相似于 phpinfo() 、 var_dump() 这些间接输入函数的内容了,并且不会打印在客户端屏幕上。比方: ob_start();php_info();$v = ob_get_contents();ob_end_clean();echo $v;在 $v 中的内容就是 php_info() 的内容了。这就是输入缓冲管制的第二个能力。 刷新(输入)缓冲区内容ob_start();echo 111, PHP_EOL;echo "aaaa", PHP_EOL;flush();ob_flush();相似的,咱们在缓冲区中想要再次间接输入内容,应用 flush() 、ob_flush() 、 ob_end_flush() 及 ob_get_flush() 就能够了,其实就是相当于让 ob_start() 之后的 echo 这类输入语句从新失效并失常输入。 ...

April 25, 2021 · 2 min · jiezi

关于php:php基础知识3数据类型

php是一门计算机编程语言,次要利用于开发web利用(网站建设等),本系列博客从php根底语法登程,介绍php基础知识。使读者深入浅出的学习到编程的乐趣。 本系列博客将解说以下9个知识点,变量、常量、数据类型、运算符、数组、流程管制(程序、抉择、循环)、函数、文件解决、面向对象 每篇文章都会在文末留下一个课后作业,答案获取请私聊我,大家能够在评论区踊跃探讨,共同进步 数据类型的概念很多初学的小伙伴对于数据类型这一定义很难了解,其实如果给出一个数,计算机并不像人一样可能一眼辨认出是整数还是小数,计算机只能辨认0 和 1的二进制代码,而数据类型就是帮忙计算机辨认这个数到底是整数还是小数。 本文将介绍php中5大根底数据类型:int(整型)、float(浮点型)、string(字符串类型)、bool(布尔类型)、null(空类型) 数据类型的分类int(整型)int(整型),其实就是整数,像100、-50 这样不带小数的整数都叫整型,能够是负数或正数。 <?php/** * Created by 冷月小白. * 微信公众号: 学长冷月 */$a = 100;$b = -50;float(浮点型)float(浮点型),其实就是小数,像10.05、2.03 这样带小数都叫浮点型 <?php/** * Created by 冷月小白. * 微信公众号: 学长冷月 */$a = 10.05;$b = 2.03;string(字符串类型)string(字符串类型),顾名思义就是一段字符串例如 "abc"或者'abc',用单引号和双引号蕴含都可。输入字符串要用var_dump()函数。 <?php/** * Created by 冷月小白. * 微信公众号: 学长冷月 */$a = "i am lengyue";$b = 'my name is lengyue';var_dump($a); //打印i am lengyuevar_dump($b);//my name is lengyuebool(布尔类型) 布尔型通常用于条件判断。能够是 TRUE(真) 或 FALSE(假)。<?php/** * Created by 冷月小白. * 微信公众号: 学长冷月 */$a = true; //真$b = false; //假null(空类型)NULL 值示意变量没有值。NULL 是数据类型为 NULL 的值。 ...

April 24, 2021 · 1 min · jiezi

关于php:使用证件照研究院接口实现制作证件照

之前始终应用的阿里云证件照制作,因为咱们的我的项目须要制作的要求非常高,最近发现阿里云的证件照接口制作解决的照片不满足咱们的要求,我来发现有一家证件照研究院的制作证件照接口制作进去的成果非常好,根本满足了咱们的要求,而且他还有检测性能,能够对制作进去的照片进行检测 证件照研究院接口文档地址:http://dev.id-photo-verify.co... 应用证件照接口后期筹备: 1:注册 登录证件照研究院的官网进行注册:http://dev.id-photo-verify.com/ 2:创立利用 注册胜利后进入管理中心,创立一个利用,这里我应用的是利用是制作并检测证件照 3:制作并检测证件照接口地址 http://apicall.id-photo-verif... 4:post传参 接口的返回参数如下: 以上的返回参数,咱们次要应用到了img_wm_url_list参数和file_name参数,其余以解检测参数,咱们能够依据咱们的需要来应用即可 img_wm_url_list参数返回的是带水印的证件照图片 此接口是收费的所有只能返回带水印的证件照,如果须要无水印的证件照的话,咱们须要应用file_name参数值来调用另一个接口,那个接口是免费的,具体操作详情请查看 https://www.wj0511.com/site/d... 5:代码实例(这里我应用的是Yii的yiisoft/yii2-httpclient插件调用接口) $file = 'XXX';//图片地址$mime_type= mime_content_type($file);//将图片进行base64编码$base64_data = base64_encode(file_get_contents($file));$base64_file = $base64_data;$data = [ 'file' => $base64_file,//须要制作的base64照片 'spec_id' => '1',//已有的规格ID,具体参考文档 'app_key' => 'XXX',//已申请的app_key 'is_fair' => 1,//是否美颜 //美颜参数 'fair_level' => [ 'leyelarge' => 0.2, 'reyelarge' => 0.2, 'mouthlarge' => 0, 'skinwhite' => 0.2, 'skinsoft' => 0.2, 'coseye' => 0, 'facelift' => 0.2, ], 'ppi' => 300, 'background_color' => [[ 'start_color' => 3379122, 'color_name' => 'blue', 'enc_color' => 3379122, ]], 'hairline_top_max_p' => '200px', 'hairline_top_min_p' => '100px', 'facial_width_max_p' => 300, 'facial_width_min_p' => 180, 'file_size_max' => 204800, 'file_size_min' => 102400, //上面是须要检测的参数,值越小越严 'facial_pose' => 10,//人脸姿势 'sight_line' => 20,//眼帘程度 'face_contrast' => 60,//眼帘程度 'facial_shelter' => 80,//面部无遮挡 'eyes_close' => 50,//闭眼 'eyes_nature' => 10,//眼帘天然 'mouse_nature' => 50,//嘴巴天然 'shoulder_equal' => 1,//肩膀等高 'face_unbalance' => 70,//阴阳脸 'glasses_glare' => 20,//眼镜反光 'face_blur' => 80,//含糊水平 'face_over_kbt' => 60,//过曝光 'bg_shadow' => 10,//背景暗影 'incomplete_head' => 60,//头部残缺 'face_too_dark' => 80,//照片过暗 'body_posture' => 60,//身材姿势 身子不正,自拍时斜向下,举手,手放脑后,抠鼻孔,托腮等 'hat_threshold' => 20,//帽子检测];$client = new Client();$response = $client->createRequest() ->setMethod('POST') // 申请形式 ->setUrl('http://apicall.id-photo-verify.com/api/cut_check_pic') // 申请地址 ->setData($data) //数据传数组 ->setHeaders(['Content-Type'=>'application/json']) //header ->setFormat(Client::FORMAT_JSON) //提交的数据的格局 ->send();//获取检测后果,1示意通过,0示意失败$result = isset($response->data['result']) ? $response->data['result'] : [];$checkResult = isset($result['check_result']) ? $result['check_result'] : [];//保留水印照片$savePath = '保留地址';$img = file_get_contents($response->data['result']['img_wm_url_list'][0]);file_put_contents($savePath, $img);//获取file_name$fileName = $response->data['result']['file_name'][0];如上咱们就能够实现制作证件照 ...

April 23, 2021 · 1 min · jiezi

关于php:laravel-输出sql

第一步:关上Providers/AppServiceProvider.php,新增办法sql_listen() /** * listen database and dump sql which only be used for debug * @param bool|false $isShowTime */function sql_listen($isShowTime = false){ app('db')->listen(function ($queryExecuted, $bindings = [], $time = '') use ($isShowTime) { static $_static_sql = []; $sql = ''; if (is_object($queryExecuted)) { $sql = $queryExecuted->sql; $bindings = $queryExecuted->bindings; $time = $queryExecuted->time; } foreach ($bindings as $i => $binding) { if (is_string($binding)) { $bindings[$i] = "'$binding'"; } } $rawSql = str_replace(array( '%', '?' ), array( '%%', '%s' ), $sql); $rawSql = vsprintf($rawSql, $bindings) . ';'; if (!$_static_sql || !in_array($rawSql, $_static_sql)) { $_static_sql[] = $rawSql; } else { return; } $usedTime = ''; if ($isShowTime) { $time = $time / 1000; $usedTime = " ({$time}s)"; } $sqlContent = $rawSql . $usedTime; logger()->channel('sqlLog')->info("我是SQL:" . $sqlContent . PHP_EOL, [ //'raw_sql' => $sql, 'connection_name' => isset($queryExecuted->connectionName) ? $queryExecuted->connectionName : '', 'duration_time' => round($time, 5), 'created_at' => date('Y-m-d H:i:s') ]); });}而后boot办法注册sql_listen()函数 ...

April 23, 2021 · 1 min · jiezi

关于java:10种编程语言实现Y组合子

简介: Y组合子是Lambda演算的一部分,也是函数式编程的实践根底。它是一种办法/技巧,在没有赋值语句的前提下定义递归的匿名函数,即仅仅通过Lambda表达式这个最根本的“原子”实现循环/迭代。本文将用10种不同的编程语言实现Y组合子,以及Y版的递归阶乘函数。 作者 | 技师起源 | 阿里技术公众号 一 Y-CombinatorY组合子是Lambda演算的一部分,也是函数式编程的实践根底。它是一种办法/技巧,在没有赋值语句的前提下定义递归的匿名函数。即仅仅通过Lambda表达式这个最根本的“原子”实现循环/迭代,颇有道生一、毕生二、二生三、三生万物的感觉。 1 从递归的阶乘函数开始 先不思考效率等其余因素,写一个最简略的递归阶乘函数。此处采纳Scheme,你能够抉择本人相熟的编程语言跟着我一步一步实现Y-Combinator版的阶乘函数。 (define (factorial n) (if (zero? n) 1(* n (factorial (- n 1)))))Scheme中 (define (fn-name)) 是 (define fn-name (lambda)) 的简写,就像JS中,function foo() {} 等价于 var foo = function() {}。把下面的定义开展成Lambda的定义: (define factorial (lambda (n) (if (zero? n) 1 (* n (factorial (- n 1))))))2 绑定函数名想要递归地调用一个函数,就必须给这个函数取一个名字。匿名函数想要实现递归,就得取一个长期的名字。所谓长期,指这个名字只在此函数体内无效,函数执行实现后,这个名字就随同函数一起隐没。为解决这个问题,第一篇文章中[1]强制规定匿名函数有一个暗藏的名字this指向本人,这导致this这个变量名被强行占用,并不优雅,因而第二篇文章[2]借鉴Clojure的办法,容许自定义一个名字。 但在Lambda演算中,只有最一般的Lambda,没有赋值语句,如何绑定一个名字呢?答案是应用Lambda的参数列表! (lambda (factorial) (lambda (n) (if (zero? n) 1 (* n (factorial (- n 1))))))3 生成阶乘函数的函数尽管通过参数列表,即应用闭包技术给匿名函数取了一个名字,但此函数并不是咱们想要的阶乘函数,而是阶乘函数的元函数(meta-factorial),即生成阶乘函数的函数。因而须要执行这个元函数,取得想要的阶乘函数: ...

April 23, 2021 · 4 min · jiezi

关于php:php基础知识2常量

php是一门计算机编程语言,次要利用于开发web利用(网站建设等),本系列博客从php根底语法登程,介绍php基础知识。使读者深入浅出的学习到编程的乐趣。 本系列博客将解说以下9个知识点,变量、常量、数据类型、运算符、数组、流程管制(程序、抉择、循环)、函数、文件解决、面向对象 每篇文章都会在文末留下一个课后作业,答案获取请私聊我,大家能够在评论区踊跃探讨,共同进步 常量的概念常量顾名思义是不变的量,在整个php代码执行阶段其值不能扭转。 常量的命名规定同变量一样,然而传统上常量标识符总是大写的。并且常量的申明不必加$符号。 初学的小伙伴必定会认为变量和常量都是代表一个值,那么为啥还要辨别变量和常量呢?其实变量和常量都各自不必的职责,在实在开发中会依据不同的应用场景来抉择适合的变量和常量。 如何申明常量 define()函数应用php内置的define()即可定义常量,第一个参数为常量名(大写),第二个参数为常量值。 <?php/** * Created by 冷月小白. * 微信公众号: 学长冷月 */define("NAME","lengyue"); //NAME为常量名 , lengyue为值echo NAME; //输入lengyue应用const关键字间接在申明常量前加关键字 const即可。 <?php/** * Created by 冷月小白. * 微信公众号: 学长冷月 */const NAME = "lengyue";echo NAME;代码实操<?php/** * Created by 冷月小白. * 微信公众号: 学长冷月 */define("NAME","lengyue"); //应用define()申明常量NAMEecho NAME;const AGE = 18;//应用const申明常量AGEecho AGE;课后练习申明常量的两种办法?常量的命名规定?课后练习答案,通过微信搜一搜「 学长冷月 」回复php获取文章继续更新,本文 GitHub https://github.com/lengyueit/phpFamily 已收录,欢送Star。如果这篇博文有帮忙到您,能够帮冷月点一个赞或者加一个关注哦!

April 23, 2021 · 1 min · jiezi

关于swoole:swoole46x-连接池底层原理深度分析

https://www.bilibili.com/vide...

April 23, 2021 · 1 min · jiezi

关于php:不使用pcntlpthreadsswoole的前提下-laravel该如何实现伪多进程

引言家喻户晓,多过程/多线程能够并行/并发的执行多个工作,进步运行效率。PHP默认是不反对多过程/多线程的,须要装置pcntl/pthreads扩大来反对。协程如果不必swoole等框架,那么实现比较复杂。以上办法均不应用,那么该如何进步程序的运行效率呢?<!--more-->思路对于耗时的工作, 通常会推送到工作队列中,而后队列生产过程从工作队列中获取工作执行。一个队列是能够开启多个生产过程的,那么执行工作的效率是比单个过程程序执行效率多很多的。如果不须要期待所有工作的执行实现来获取后果的话,其实开启多个队列生产过程曾经够了。如果须要期待所有工作实现才返回后果的操作,比方在定时工作中须要读取Mysql的100条记录,去调用第三方的API,这个三方API很Low,调用一次须要2s,最终须要生成这100条记录的CSV文件。程序执行至多须要200s能力实现, 如果有4个队列生产过程, 那么只须要50s左右即可实现。次要问题在于如何解决过程间通信?因为须要晓得这些子工作是否执行完,以及须要晓得工作的执行后果。那么是否能够将应用redis来通信呢?用redis进行计数操作,每个工作执行完将计数器加1,每个工作的执行后果都放在redis的list/hash中,当计数器的总数等于工作总数的时候,就能够判定工作曾经执行实现,而后取出redis寄存的后果,生成csv文件。实现理论我的项目已在线上稳固跑了几个月了,在这里只贴伪代码展现一下实现思路,有趣味的能够本人实现试试。 定时工作command,这里次要是程序入口, 设置好计数器, 并且期待队列工作执行实现,获取后果。 具体任务Job代码, 次要执行耗时工作,以及执行实现计数器进行加1,须要留神的是异样也要保障计数器+1,否则工作总数跟执行总数不相等,那么主过程command会卡死。 将工作相干信息保留到redis的hash数据结构中, 须要保留工作总数的key, 用于统计的已执行工作总数的key,计数能够用工夫复杂度为O(1)的hincrby命令。 后果也能够保留到该hash中, 通过hvals获取后果前先把两个count的key删除即可。 该代码示例只适宜学习应用,如果须要生产应用须要本人解决细节问题。开启多个工作队列, 可手动开启几个终端手动执行:php artisan queue:work redis --queue=calculate启动多个队列生产过程,也能够通过supervisor来启动, 通过配置numprocs=8参数来限度过程数量。

April 22, 2021 · 1 min · jiezi

关于vue.js:在crmeb开源项目中已发布的小程序生成小程序码不显示提示小程序二维码需要发布正式版后才能获取到如何处理

crmeb零碎(开源地址请戳:http://github.crmeb.net/u/crm...好多开发者会遇到小程序产品分销二维码生成不了,提醒“小程序二维码须要公布正式版后能力获取到” 这个应该如何解决呢,当初就解决办法整顿了一下 具体解决办法如下: 1、小程序须要正式公布后,能力生成产品二维码 2、检测小程序后盾,检测下载域名是否配置:“downloadFile非法域名” 图片设置了云存储,也要将下载非法域名进行设置。3、检测SSL证书等级是否太低,苹果手机要求SSL证书tls反对1.2以上,安卓手机要求1.2 查看证书等级:https://myssl.com/4、手动清理附件表eb_system_attachment module_type =2 的数据 5、产品图片不在服务器上,从新上传下产品图片 6、分明用户长期生成的附件 7、根目录runtime文件 777权限,所有者www(这个文件外面文件的权限也须要一样的) 8、改完之后须要把手机的小程序删除从新进微信小程序

April 22, 2021 · 1 min · jiezi

关于php:Swoole-v466-版本发布Bug-修复版本

v4.6.6 版本次要是一个 Bug 修复版本,没有向下不兼容改变。 更新日志上面是残缺的更新日志: 加强反对在 FreeBSD 下 Master 过程退出后向 Manager 过程发送 SIGTERM 信号 (#4150) (@devnexen)反对将 Swoole 动态编译到 PHP 中 (#4153) (@matyhtf)反对 SNI 应用 HTTP 代理 (#4158) (@matyhtf)修复修复同步客户端异步连贯的谬误 (#4152) (@matyhtf)修复 Hook 原生 curl multi 导致的内存透露 (swoole/swoole-src@91bf243) (@matyhtf)

April 22, 2021 · 1 min · jiezi

关于php:redis实际应用限流

为什么要做限流首先让咱们先看一看零碎架构设计中,为什么要做“限流”。 旅游景点通常都会有最大的接待量,不可能无限度的放游客进入,比方故宫每天只卖八万张票,超过八万的游客,无奈买票进入,因为如果超过八万人,景点的工作人员可能就忙不过来,过于拥挤的景点也会影响游客的体验和情绪,并且还会有安全隐患;只卖N张票,这就是一种限流的伎俩。 软件架构中的服务限流也是相似,也是当系统资源不够的时候,曾经不足以应答大量的申请,为了保障服务还可能失常运行,那么依照规定,零碎会把多余的申请间接回绝掉,以达到限流的成果; 不晓得大家留神过没有,比方双11,刚过12点有些顾客的网页或APP会显示下单失败的提醒,有些就是被限流掉了。 常见的限流算法计数法顾名思义就是来一个,记录一个,比方我1分钟只能解决1000个申请,那么咱们就能够设置一个计数器,来一个申请就incr+1,当1分钟之内的数量大于等于1000之后不解决了即可,伪代码如下 $redis = new Redis();$redis->connect('127.0.0.1', 6379);$rate_limit = 1000; //限度个数$rate_seconds = 60; //限度工夫$redis_key = "redis_limit";$count = $redis->get($redis_key);if ($count >= $rate_limit){ //判断60秒内申请个数是否曾经达到下限 //间接返回,不解决申请 return}$redis->incr($redis_key, 1);//申请计数$redis->expire($redis, $rate_seconds); //设置过期工夫 60s//to do 业务逻辑解决.......这种计数形式比较简单快捷,然而有很大的毛病,因为申请的拜访不肯定是很安稳的,如果0:59过去了1000个申请,1:01曾经是下一个窗口,又过去了1000个申请,但实际上三秒内来了2000个申请,曾经超过咱们的限流下限了。所以这种办法是不举荐的。 滑动窗口算法还拿下面的例子,一分钟分6份,每份10秒;每过10秒钟,咱们的工夫窗口就会往右滑动一格,每个格子都有独立的计数器,咱们每次都计算工夫窗口内的数量,能够解决计数器法中的问题,而且当滑动窗口的格子越多,那么限流的统计就会越准确。具体能够参考下图,看图比拟清晰伪代码实现如下 function api_limit($scene, $period, $maxCount){ $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $key = sprintf('hist:%s', $scene); //限流场景惟一标识 $now = msectime(); // 毫秒工夫戳,这样更准确 $pipe=$redis->multi(Redis::PIPELINE); //应用管道晋升性能 $pipe->zadd($key, $now, $now); //value 和 score 都应用毫秒工夫戳 $pipe->zremrangebyscore($key, 0, $now - $period); //移除工夫窗口之前的行为记录,剩下的都是工夫窗口内的 $pipe->zcard($key); //获取窗口内的行为数量 $pipe->expire($key, $period/1000 + 1); //多加一秒过期工夫 $replies = $pipe->exec(); return $replies[2] <= $maxCount; //$replies[2]为zcard返回的个数 如果zcard后果大于maxCount,则不处理结果}for ($i=0; $i<20; $i++){ //测试限流是否实现代码 var_dump(isActionAllowed("uniq_scene", 60*1000, 5)); //执行能够发现只有前5次是通过的}//返回以后的毫秒工夫戳function msectime() { list($msec, $sec) = explode(' ', microtime()); $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000); return $msectime; }这段代码还是略显简单,须要读者花肯定的工夫好好啃。它的整体思路就是:每一个行为到来时,都保护一次工夫窗口。将工夫窗口外的记录全副清理掉,只保留窗口内的记录。 ...

April 22, 2021 · 1 min · jiezi

关于github:这款简洁的开源客户关系管理系统真是好东西

 大家好,我是为宽广程序员兄弟操碎了心的小编,每天举荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节俭开发效率,实现不加班不熬夜不掉头发,是我的指标! 明天小编举荐一款PHP开发的开源客户关系管理系统(CRM),零碎提供客户关系管理员(CRM),进销存(JXC),人力资源(HRM),后勤(办公用品,固定资产,公物培修)、物业管理等性能,软件开源收费。 开源协定 应用 LGPL-3.0 开源许可协定,用户可收费应用,但禁止任何单位或集体批改软件后再次发行的行为。 git地址 公众号【Github导航站】回复关键词【fly】获取git地址 功能模块商品治理(商品色彩,计量单位,商品类型,商品保护);组织构造(部门、权限、职务、用户治理);企业类型,仓库治理,发货形式,销售阶段,服务类型;供应商治理供应商治理:实现对公司提供产品及服务的货源进行根本信息的记录.客户治理:实现对客户信息的增加及批改查问性能。洽购单(进销存):对采购员与供应商所签订的订单信息的记录,便于后勤查问与跟踪。库存治理:将商品列表中的商品进行入库,并主动生成入库单。销售治理:销售流程:欠缺客户信息(客户治理)---销售机会---跟踪----记录客户需要,制订相干的解决方案----剖析竞争产品----报价---我的项目报备----订单----编辑出库商品信息---生成出库单---仓库管理员确认出库----发货。财务管理:贴近理论业务的财务模块,毋庸财务常识,就能上手操作。演示截图部门治理 权限治理 沟通记录 客户起源 服务记录 销售机会 产品报价 合同增加 销售订单 增加供应商 财务流水 费用支出类型 汇款打算增加 结尾 本期就分享到这里,我是小编南风吹,专一分享好玩乏味、离奇、实用的开源我的项目及开发者工具、学习资源!心愿能与大家独特学习交换,欢送关注我的公众号【Github导航站】。

April 22, 2021 · 1 min · jiezi

关于php:动态查看及加载PHP扩展

在编译并实现 php.ini 的配置之后,咱们就胜利的装置了一个 PHP 的扩大。不过, PHP 也为咱们提供了两个在动静运行期间能够查看扩大状态以及加载未在 php.ini 中进行配置的扩大的函数。上面,咱们就来看看它们的应用。 查看是否曾经加载了扩大echo extension_loaded("redis");非常简单的一个函数,它的作用就是查看一个扩大是否曾经加载。它返回的是一个布尔值,当扩大曾经加载则返回 true ,如果扩大没有加载,则返回 false 。 在 PHP-FPM 的网页中,咱们能够通过 phpinfo() 函数来查看以后 PHP 的状态及扩大相干信息。而在 CLI 命令行脚本中,咱们能够应用 php -m 命令来查看已加载的扩大。 动静加载扩大首先,咱们在 php.ini 中敞开 redis 扩大的加载,并且同时须要关上 enable_dl=1 ,这样,咱们就能够应用 dl() 函数来动静加载一个扩大了。 dl("redis");echo extension_loaded("redis");// 1没错, dl() 函数正是用来动静加载扩大的一个函数。不过它的应用是有许多限度的,这也并不是一个平安的函数。所以在 PHP7 中,它在 php.ini 的配置 enable_dl 曾经是默认敞开的了。咱们在生产环境也尽量不要应用这种形式进行扩大的加载。 另外,这个函数在 PHP7 中仅对 CLI 环境无效。也就是说,在 PHP-FPM 的网页环境下,这个函数是没用的,即便曾经关上了 php.ini 中的 enable_dl 。 扩大加载的目录是以 PHP 默认的扩大目录为根底进行加载的,在 windows 环境下留神扩大名为 .dll 文件。当扩大加载失败时,不仅这个函数会返回 false ,同时还会产生一条 E_WARNING 的谬误音讯。最初,在 PHP 平安模式下,这个函数也同样是无奈应用的。 ...

April 22, 2021 · 1 min · jiezi

关于php:PHP如何在两个大文件中找出相同的记录

引言给定a,b两个文件, 别离有x,y行数据, 其中(x, y均大于10亿), 机器内存限度100M,该如何找出其中雷同的记录?<!--more--> 思路解决该问题的艰难次要是无奈将这海量数据一次性读内内存中.一次性读不进内存中,那么是否能够思考屡次呢?如果能够,那么屡次读入要怎么计算雷同的值呢?咱们能够用分治思维, 大而化小。雷同字符串的值hash过后是相等的, 那么咱们能够思考应用hash取模, 将记录扩散到n个文件中。这个n怎么取呢? PHP 100M内存,数组大概能够存100w的数据, 那么按a,b记录都只有10亿行来算, n至多要大于200。此时有200个文件,雷同的记录必定在同一个文件中,并且每个文件都能够全副读进内存。那么能够顺次找出这200个文件中各自雷同的记录,而后输入到同一个文件中,失去的最终后果就是a, b两个文件中雷同的记录。找一个小文件中雷同的记录很简略了吧,将每行记录作为hash表的key, 统计key的呈现次数>=2就能够了。实操10亿各文件太大了,实操浪费时间,达到实际目标即可。 问题规模放大为: 1M内存限度, a, b各有10w行记录, 内存限度能够用PHP的ini_set('memory_limit', '1M');来限度。 生成测试文件生成随机数用于填充文件: /** * 生成随机数填充文件 * Author: ClassmateLin * Email: classmatelin.site@gmail.com * Site: https://www.classmatelin.top * @param string $filename 输入文件名 * @param int $batch 按多少批次生成数据 * @param int $batchSize 每批数据的大小 */function generate(string $filename, int $batch=1000, int $batchSize=10000){ for ($i=0; $i<$batch; $i++) { $str = ''; for ($j=0; $j<$batchSize; $j++) { $str .= rand($batch, $batchSize) . PHP_EOL; // 生成随机数 } file_put_contents($filename, $str, FILE_APPEND); // 追加模式写入文件 }}generate('a.txt', 10);generate('b.txt', 10);宰割文件将a.txt, b.txt通过hash取模的形式宰割到n个文件中./** * 用hash取模形式将文件扩散到n个文件中 * Author: ClassmateLin * Email: classmatelin.site@gmail.com * Site: https://www.classmatelin.top * @param string $filename 输出文件名 * @param int $mod 按mod取模 * @param string $dir 文件输入目录 */function spiltFile(string $filename, int $mod=20, string $dir='files'){ if (!is_dir($dir)){ mkdir($dir); } $fp = fopen($filename, 'r'); while (!feof($fp)){ $line = fgets($fp); $n = crc32(hash('md5', $line)) % $mod; // hash取模 $filepath = $dir . '/' . $n . '.txt'; // 文件输入门路 file_put_contents($filepath, $line, FILE_APPEND); // 追加模式写入文件 } fclose($fp);}spiltFile('a.txt');spiltFile('b.txt');执行splitFile函数, 失去如下图files目录的20个文件。 ...

April 21, 2021 · 3 min · jiezi

关于php:PHP中的数据库连接持久化

数据库的优化是咱们做web开发的重中之重,甚至很多状况下其实咱们是在面向数据库编程。当然,用户的所有操作、行为都是以数据的模式保留下来的。在这其中,数据库的连贯创立过程有没有什么能够优化的内容呢?答案当然是有的,Java等语言中有连接池的设定,而PHP在一般开发中并没有连接池这种货色,在牵涉到多线程的状况下往往才会应用连接池的技术,所以PHP每次运行都会创立新的连贯,那么这种状况下,咱们如何来优化数据连贯呢? 什么是数据库连贯长久化咱们先来看下数据库连贯长久化的定义。 长久的数据库连贯是指在脚本完结运行时不敞开的连贯。当收到一个长久连贯的申请时。PHP 将查看是否曾经存在一个(后面曾经开启的)雷同的长久连贯。如果存在,将间接应用这个连贯;如果不存在,则建设一个新的连贯。所谓“雷同”的连贯是指用雷同的用户名和明码到雷同主机的连贯。 对 web 服务器的工作和分布负载没有齐全了解的读者可能会谬误地了解长久连贯的作用。特地的,长久连贯不会在雷同的连贯上提供建设“用户会话”的能力,也不提供无效建设事务的能力。实际上,从严格意义上来讲,长久连贯不会提供任何非长久连贯无奈提供的非凡性能。 这就是PHP中的连贯长久化,不过它也指出了,长久连贯不会提供任何非长久连贯无奈提供的非凡性能。这就很让人纳闷了,不是说好了这个计划能够带来性能的晋升吗? 连贯长久化有什么用?没错,从上述定义中指出的非凡性能来看,长久化连贯的确没有带来新的或者更高级的性能,然而它最大的用途正是晋升了效率,也就是性能会带来晋升。 当Web Server创立到SQL服务器的连贯消耗(Overhead)较高(如耗时较久,耗费长期内存较多)时,长久连贯将更加高效。 也就是说连贯消耗高的时候,创立数据库连贯的老本开销也会越大,工夫当然也越长。应用长久化连贯之后,使得每个子过程在其生命周期中只做一次连贯操作,而非每次在解决一个页面时都要向SQL 服务器提出连贯申请。这也就是说,每个子过程将对服务器建设各自独立的长久连贯。 例如,如果有 20 个不同的子过程运行某脚本建设了长久的 SQL 服务器长久连贯,那么实际上向该 SQL 服务器建设了 20 个不同的长久连贯,每个过程占有一个。 效率比照话不多说,咱们间接通过代码来比照。首先,咱们定义好一个统计函数,用来返回以后的毫秒工夫。另外,咱们还要筹备好数据的连贯参数。 function getmicrotime(){ list($usec, $sec) = explode(" ", microtime()); return ((float) $usec + (float) $sec);}$db = [ 'server' => 'localhost:3306', 'user' => 'root', 'password' => '', 'database' => 'blog_test',];接下来,咱们先应用一般的 mysqli 进行测试。 $startTime = getmicrotime();for ($i = 0; $i < 1000; $i++) { $mysqli = new mysqli($db["server"], $db["user"], $db["password"], $db["database"]); //长久连贯 $mysqli->close();}echo bcsub(getmicrotime(), $startTime, 10), PHP_EOL;// 6.5814000000在 1000 次的循环创立数据库的连贯过程中,咱们耗费了6秒多的工夫。接下来咱们应用长久化连贯的形式进行这 1000 次的数据库连贯创立。只须要在 mysqli 的 $host 参数前加上一个 p: 即可。 ...

April 21, 2021 · 1 min · jiezi

关于php:Yii2配合LinuxCrontab执行定时脚本

首先咱们就来说说Yii Console 是如何实现定时工作的   一、首先在创立Controlle 并继承 yii\console\Controller;<?phpnamespace app\commands; use yii\console\Controller;class HelloController extends Controller{ public function actionIndex($message = 'hello world'){ echo $message . "\n";}}   二、测试是否胜利切换至框架根目录 执行 php yii hello/index   三、设置定时工作linux下,运行crontab -e 增加以下代码 30 21 * /usr/local/php/bin/php /your_project_path/yii hello/index 下面的例子示意每晚的21:30执行下面的定时程序 上面是定时工作设置的一些根本介绍 根本格局 : command分 时 日 月 周 命令 第1列示意分钟1~59 每分钟用或者 /1示意 第2列示意小时1~23(0示意0点) 第3列示意日期1~31 第4列示意月份1~12 第5列标识号星期0~6(0示意星期天) 第6列要运行的命令 crontab文件的一些例子: Shell   30 21 * /usr/local/etc/rc.d/lighttpd restart 下面的例子示意每晚的21:30重启apache。  45 4 1,10,22 /usr/local/etc/rc.d/lighttpd restart ...

April 19, 2021 · 1 min · jiezi

关于php:Mysql-将多行结果以逗号合并为一行

阐明: 1.GROUP_CONCAT() 中的值为你要合并的数据的字段名; SEPARATOR 函数是用来分隔这些要合并的数据的,默认以 逗号 分隔; ' '中是你要用哪个符号来分隔;2.必须要用GROUP BY 语句来进行分组治理,不然所有的数据都会被合并成一条记录失常查问: SELECT a.order_id,goods_nameFROM A AS aLEFT JOIN B AS b ON a.order_id = b.order_id查问后果: 想要的后果: sql 实现: SELECT a.order_id,GROUP_CONCAT( goods_name SEPARATOR ',' ) AS goods_name FROM A AS aLEFT JOIN B AS c ON a.order_id = c.order_idGROUP BY a.order_id

April 16, 2021 · 1 min · jiezi

关于php:PHP多文件上传格式化

文件上传是所有web利用中最常见的性能,而PHP实现这一性能也十分的简略,只须要前端设置表单的 enctype 值为 multipart/form-data 之后,咱们就能够通过 $_FILES 取得表单中的 file 控件中的内容。 同时,咱们还能够将 file 控件的名称写成带 [] 的数组模式,这样咱们就能够接管到多个上传的文件。比方上面这个测试用的表单: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <form action="" enctype="multipart/form-data" method="post"> myfile1:<input type="file" name="myfile[]"/><br/> myfile2:<input type="file" name="myfile[a][]"/><br/> myfile3:<input type="file" name="myfile[a][b][]"/><br/> myfile4:<input type="file" name="myfile[c][]"/><br/> myfile5:<input type="file" name="myfile[]"/><br/> myfile6:<input type="file" name="myfile[][]"/><br/> <br/> newfile1:<input type="file" name="newfile[][]"/><br/> newfile2:<input type="file" name="newfile[s]"/><br/> singlefile: <input type="file" name="singlefile"/><br/> <input type="submit" value="submit"/> </form></body></html>一共有9个 file 控件,其中 myfile 和 newfile 都是数组类型的表单名,而 singlefile 则是一个独自的。先简略的看一下 $_FILES 所取得的内容。 print_r($_FILES);Array( [myfile] => Array ( [name] => Array ( [0] => 2591d8b3eee018a0a84f671933ab6c74.png [a] => Array ( [0] => 12711584942474_.pic_hd 1.jpg [b] => Array ( [0] => 12721584942474_.pic_hd 1.jpg ) ) [c] => Array ( [0] => 12731584942474_.pic_hd.jpg ) [1] => background1.jpg [2] => Array ( [0] => adliu_pip_data.xlsx ) ) [type] => Array ( [0] => image/png [a] => Array ( [0] => image/jpeg [b] => Array ( [0] => image/jpeg ) ) [c] => Array ( [0] => image/jpeg ) [1] => image/jpeg [2] => Array ( [0] => application/vnd.openxmlformats-officedocument.spreadsheetml.sheet ) ) [tmp_name] => Array ( [0] => /private/var/folders/wj/t2z1cfhs0m9gq48krm8nc0vm0000gn/T/phphD88ZY [a] => Array ( [0] => /private/var/folders/wj/t2z1cfhs0m9gq48krm8nc0vm0000gn/T/phpNY8MzY [b] => Array ( [0] => /private/var/folders/wj/t2z1cfhs0m9gq48krm8nc0vm0000gn/T/php3MX5tk ) ) [c] => Array ( [0] => /private/var/folders/wj/t2z1cfhs0m9gq48krm8nc0vm0000gn/T/phpjgrHMj ) [1] => /private/var/folders/wj/t2z1cfhs0m9gq48krm8nc0vm0000gn/T/phppXRtnc [2] => Array ( [0] => /private/var/folders/wj/t2z1cfhs0m9gq48krm8nc0vm0000gn/T/phpekSY1M ) ) [error] => Array ( [0] => 0 [a] => Array ( [0] => 0 [b] => Array ( [0] => 0 ) ) [c] => Array ( [0] => 0 ) [1] => 0 [2] => Array ( [0] => 0 ) ) [size] => Array ( [0] => 4973 [a] => Array ( [0] => 3007 [b] => Array ( [0] => 1156 ) ) [c] => Array ( [0] => 6068 ) [1] => 393194 [2] => Array ( [0] => 36714 ) ) ) [newfile] => Array ( [name] => Array ( [0] => Array ( [0] => 数据列表 (2).xlsx ) [s] => background1.jpg ) [type] => Array ( [0] => Array ( [0] => application/vnd.openxmlformats-officedocument.spreadsheetml.sheet ) [s] => image/jpeg ) [tmp_name] => Array ( [0] => Array ( [0] => /private/var/folders/wj/t2z1cfhs0m9gq48krm8nc0vm0000gn/T/phplSsRfM ) [s] => /private/var/folders/wj/t2z1cfhs0m9gq48krm8nc0vm0000gn/T/phpuQAvRb ) [error] => Array ( [0] => Array ( [0] => 0 ) [s] => 0 ) [size] => Array ( [0] => Array ( [0] => 77032 ) [s] => 393194 ) ) [singlefile] => Array ( [name] => timg (8).jpeg [type] => image/jpeg [tmp_name] => /private/var/folders/wj/t2z1cfhs0m9gq48krm8nc0vm0000gn/T/phpxtSQ4J [error] => 0 [size] => 10273 ))看出有什么问题了吗? ...

April 15, 2021 · 4 min · jiezi

关于php:PHPRSA加密解密

<?php/*** App RSA 加密解密辅助函数**/function app_pri_encrypt($data){ $privateKey = openssl_pkey_get_private(file_get_contents("app-private.key")); $encrypted = null; openssl_private_encrypt($data,$encrypted,$privateKey); return base64_encode($encrypted);}function app_pri_decrypt($data){ $privateKey = openssl_pkey_get_private(file_get_contents("app-private.key")); $decrypted = null; openssl_private_decrypt(base64_decode($data),$decrypted,$privateKey); return $decrypted;}function app_pub_encrypt($data){ $publicKey = openssl_pkey_get_public(file_get_contents("app-public.key")); $encrypted = null; openssl_public_encrypt($data,$encrypted,$publicKey); return base64_encode($encrypted);}function app_pub_decrypt($data){ $publicKey = openssl_pkey_get_public(file_get_contents("app-public.key")); $decrypted = null; openssl_public_decrypt(base64_decode($data),$decrypted,$publicKey); return $decrypted;}

April 15, 2021 · 1 min · jiezi

关于docker:Docker-PHP-安装扩展

编写 Dockerfilevim DockerfileFROM php:7.3-fpmADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"RUN chmod +x /usr/local/bin/install-php-extensions && sync && \ install-php-extensions bcmath bz2 calendar exif gd gettext gmp igbinary imagick memcached mongodb mysqli pcntl pdo_mysql pdo_pgsql pgsql redis shmop sockets swoole sysvmsg sysvsem sysvshm wddx xhprof xsl zipRUN install-php-extensions @composer构建镜像并运行$ docker build -t my-php .$ docker run -itd --name php -p 9001:9000 \-v /mnt/website/prod/project-name:/var/www/html \my-php:latest反对的扩大ExtensionPHP 7.2PHP 7.3PHP 7.4PHP 8.0amqp✓✓✓✓apcu✓✓✓✓apcu_bc✓✓✓ bcmath✓✓✓✓bz2✓✓✓✓calendar✓✓✓✓cmark✓✓✓ csv ✓✓✓dba✓✓✓✓decimal✓✓✓✓ds✓✓✓✓enchant✓✓✓✓ev✓✓✓✓excimer✓✓✓✓exif✓✓✓✓ffi ✓✓gd✓✓✓✓gearman✓✓✓✓geoip✓✓✓ geospatial✓✓✓✓gettext✓✓✓✓gmagick✓✓✓✓gmp✓✓✓✓gnupg✓✓✓✓grpc✓✓✓✓http✓✓✓✓igbinary✓✓✓✓imagick✓✓✓✓imap✓✓✓✓interbase✓✓ intl✓✓✓✓ioncube_loader✓✓✓ json_post✓✓✓✓ldap✓✓✓✓mailparse✓✓✓✓maxminddb✓✓✓✓mcrypt✓✓✓✓memcache✓✓✓✓memcached✓✓✓✓mongodb✓✓✓✓mosquitto✓✓✓ msgpack✓✓✓✓mysqli✓✓✓✓oauth✓✓✓✓oci8✓✓✓✓odbc✓✓✓✓opcache✓✓✓✓opencensus✓✓✓ parallel✓✓✓ pcntl✓✓✓✓pcov✓✓✓✓pdo_dblib✓✓✓✓pdo_firebird✓✓✓✓pdo_mysql✓✓✓✓pdo_oci✓✓✓✓pdo_odbc✓✓✓✓pdo_pgsql✓✓✓✓pdo_sqlsrv✓✓✓✓pgsql✓✓✓✓propro✓✓✓ protobuf✓✓✓✓pspell✓✓✓✓raphf✓✓✓✓rdkafka✓✓✓✓recode✓✓ redis✓✓✓✓seaslog✓✓✓✓shmop✓✓✓✓smbclient✓✓✓✓snmp✓✓✓✓snuffleupagus✓✓✓✓soap✓✓✓✓sockets✓✓✓✓solr✓✓✓✓sqlsrv*✓✓✓✓ssh2✓✓✓✓swoole✓✓✓✓sysvmsg✓✓✓✓sysvsem✓✓✓✓sysvshm✓✓✓✓tensor✓✓✓ tidy✓✓✓✓timezonedb✓✓✓✓uopz✓✓✓ uuid✓✓✓✓wddx✓✓ xdebug✓✓✓✓xhprof✓✓✓✓xlswriter✓✓✓✓xmlrpc✓✓✓✓xsl✓✓✓✓yaml✓✓✓✓yar✓✓✓✓zip✓✓✓✓zookeeper✓✓✓ zstd✓✓✓✓已有的内置扩大$ docker run --rm php:7.3-fpm php -m[PHP Modules]CorectypecurldatedomfileinfofilterftphashiconvjsonlibxmlmbstringmysqlndopensslpcrePDOpdo_sqlitePharposixreadlineReflectionsessionSimpleXMLsodiumSPLsqlite3standardtokenizerxmlxmlreaderxmlwriterzlib[Zend Modules]参考:https://github.com/mlocati/do... ...

April 14, 2021 · 1 min · jiezi

关于php:金三银四刷一波新鲜出炉的面试题

举荐电子书去年因为疫情起因公司欠薪,被迫在4,5月开始找工作,棘手写了一本《phper面试2020》。至今一共卖了500本+,也算是无心插柳柳成荫。往年站在一个更高的视角,整顿了《phper面试2021》,一方面能对基础知识有一个常读常新的意识,一方面有一个极其状况有能力走出舒服区的底气。 侧重点《2021》从新梳理针对面试的常识体系,有两个侧重点。 (1)《phper面试真题》依照技术分类来拆分章节的,《phper面试2021》调整为依照面试轮数(难度等级)来布局章节。 (2)语句简短口语化,用关键词命中知识点。照着读有一种就如同在答复问题的感觉,让面试官明确你会这道题。 内容截图 ## 后记 本书内容根本实现,我仍在一直减少新的面试题,做答案优化。敌人反馈往年金三银四机会多多,收费的货色往往是最贵的,比如说读者的工夫,这本电子书耗时至多100个小时+,心愿读者能够开卷有益。电子书地址

April 14, 2021 · 1 min · jiezi

关于php:PHP的CLI命令行运行模式浅析

在做开发的时候,咱们不仅仅只是做各种网站或者接口,也常常须要写一些命令行脚本用来解决一些后端的事务。比方对数据进行解决统计等。当然也是为了效率着想,当一个事务有可能会有较长的耗时时,往往会交由服务器的定时器来固定工夫调用脚本进行解决,从而让客户端可能有更好的用户体验。咱们明天就来理解下 PHP 的命令行运行模式,也就是 PHP CLI 。 CLI 与 CGI首先来看一下 CLI 和 CGI 的区别。咱们都晓得,Nginx 应用的是 FastCgi 来调用 PHP 的服务。 CGI 是通用编程接口,也就是给调用者提供的一种应用本程序的接口。 Nginx 这种类型的服务器并不是间接运行 PHP 程序的,而是通过 FastCgi 来执行 PHP 程序并取得返回后果。 CLI 则是 Command Line Interface,即命令行接口。次要用作 PHP 的开发外壳利用。也就是用 PHP 来进行 shell 脚本的开发。相比 linux 原生的 shell 来说,当然是不便了许多。在命令行状态下,间接应用 php 命令就能够运行某段 PHP 代码或某个 PHP 文件了。 另外,咱们在命令行也能够间接应用 phpcgi 来运行一段 PHP 代码或者某个 PHP 文件,它和间接应用 php 命令来运行有什么区别呢? CLI 的输入没有任何头信息CLI 在运行时,不会把工作目录改为脚本的当前目录CLI 出错时输入纯文本的错误信息(非 HTML 格局)强制笼罩了 php.ini 中的某些设置,因为这些设置在外壳环境下是没有意义的// PHP的CLI命令行运行模式浅析.phpecho getcwd();// php-cgi dev-blog/php/202004/source/PHP的CLI命令行运行模式浅析.php// ...../MyDoc/博客文章/dev-blog/php/202004/source// php dev-blog/php/202004/source/PHP的CLI命令行运行模式浅析.php// ...../MyDoc/博客文章咱们选取最典型的一个例子,咱们运行的这个文件中,应用 getcwd() 输入以后脚本运行的目录,能够看出两种运行形式输入的后果显著不同。php-cgi 是以文件所在目录为基准输入,而 php 则是以以后运行这个命令的目录为基准输入。 ...

April 14, 2021 · 2 min · jiezi

关于php:Laravel-Tinker-的使用

Laravel Tinker 简介在原生 PHP 中,能够通过 php -a 命令应用交互式 Shell: # php -aphp > $msg = "Hello world!";php > print $msg;Hello world!php > $num = array_sum([1, 2, 3]);php > print $num;6此外,还能够应用 PsySH ,相较于原生的 php -a,PsySH 领有更多高级个性,性能更加弱小。 通过 Composer 全局装置: composer g require psy/psysh:@stable而后在命令行执行 psysh 即可进入交互式 Shell 了(需确保全局 Composer 的 bin 目录在零碎门路中),在 PsySH 中能够编写各种代码,打印语句、计算表达式、编写函数等等。 Laravel Tinker 就是基于 PsySH 实现的,通过 Tinker,咱们能够在命令行中实现与 Laravel 利用的各种交互,包含数据库的增删改查。 在命令行中通过 php artisan tinker 即可进入 Laravel Tinker 的交互式 Shell。 ...

April 12, 2021 · 1 min · jiezi

关于nginx:吃透-Nginx-编译安装过程

编译出适宜本人的NginxNginx的装置形式装置Nginx有两种办法,除了编译以外,还能够间接用操作系统上自带的一些工具,比方yum、apt-get 然而间接装置Nginx的二进制文件会有个问题,因为Nginx的二进制文件会把模块间接编译进来。Nginx的官网模块,并不是每一个都默认开启的,如果你想增加第三方的Nginx模块,你必须通过编译Nginx这种形式能力把第三方的模块增加到Nginx中 编译装置Nginx过程下载NginxNginx下载官网 进入官网之后,点击右下角的download 能够发现Nginx有两类版本,一个是Mainline version(最新版本)、一个是Stable version(稳固版本)。咱们通常会抉择下载稳固版本(这里最新的是1.18.0) 抉择一个稳固版本,复制下载链接,通过wget的形式下载下来即可,下载下来之后是一个压缩包,通过下边命令解压即可 tar -xzf nginx-1.18.0.tar.gz各目录介绍进入解压之后的源码目录中,能够看到如下构造 auto目录其中cc目录是用于编译的,还有lib库,os目录是对所有的操作系统进行判断的。其它的文件都是为了在configure脚本执行的时候,去断定Nginx反对哪些模块,以后操作系统有什么样的个性能够供Nginx应用 CHANGES文件CHANGES文件记录的是每个Nginx版本中提供了哪些个性和bugfix,局部内容截图 CHANGES.ru文件因为Nginx作者是一个俄罗斯人,所以这是一个俄罗斯语言的CHANGES文件 conf目录它是一个示例目录,就是把Nginx装置实现当前,为了不便运维去配置,会把conf中的示例文件拷贝到装置目录 configure脚本configure脚本是一个用来生成两头文件,执行编译前的必备动作 contrib目录它提供了两个脚本和vim的一个工具,比方在没有应用它提供的vim工具时关上Nginx的配置文件,会发现色调没什么变动(能够看到Nginx配置文件的语法,没有在vim中高亮的显示) 而后当初将contrib目录中下的所有vim文件拷贝到本地装置的vim目录中 sudo cp -r contrib/vim/* ~/.vim/而后再关上Nginx的配置文件 html目录该目录中提供了两个规范的html文件,一个是发现500谬误的时候能够重定向到50x.html文件,另外一个是默认的Nginx欢送界面 man目录man目录是linux对Nginx的帮助文件(关上命令:man ./nginx.8) src目录src目录是Nginx的源代码目录 Configure 编译编译之前,能够看一下Configure反对哪些参数 ./configure --help | more 它的参数里边次要分为几个大块: 第一类,确定Nginx执行中,它会去找哪些目录下的文件作为它的辅助文件。比方须要动静模块,此时 --modules-path=PATH 就会产生作用。如果没有任何变动的话,只须要指定 --prefix=PATH 这个参数就能够了,所有的其它的文件都会在prefix指定的目录上面建相应的文件夹第二类,次要是确定应用和不应用哪些模块,它的前缀通常是 --with- 和 --without- 。比如说 --with-http_ssl_module 、 --with-http_v2_module,通常须要咱们被动加--with模块的时候,意味着该模块默认是不会被编译进来的。而编译中须要应用 --without- ,意味着默认它会被编译进Nginx,如果你不加这个参数,他是会被编译进去,如果加了--without- ,它就不会被编译进去第三类,指定了Nginx编译中须要的一些非凡的参数,比方用gcc编译的时候,须要加一些什么样的优化参数,或者说须要打印dubug级别的日志 下边就应用默认参数编译一下Nginx,下边指定了Nginx的装置目录 ./configure --prefix=/home/geek/nginx如果在执行的过程中没有报错,就意味着Nginx编译胜利了。此时Nginx所有配置的个性,以及运行时的目录都会列在最下边 在上边编译实现之后,会生成一些两头文件 两头文件介绍编译实现之后,生成的两头文件,会放在解压之后的nginx目录下的objs目录下 objs目录下文件构造这里边最重要的是会生成一个文件叫ngx_modules.c,它决定了接下来执行编译的时候,有哪些模块会被编译进Nginx 每一行extern ngx_module_t 后边就是一个ngxin模块,所有会被编译进以后Nginx中的模块,都会被列在上边,他们最终会造成一个叫 *ngx_modules[]的指针数组 而后就能够执行make编译了。编译实现之后,会生成大量的两头文件,以及最终运行的Nginx二进制文件,能够在objs目录中看到 为什么须要晓得Nginx的指标文件是放在这里的? 因为如果咱们要做Nginx版本升级,此时不能执行make install,而是从这里把指标文件拷贝到装置目录中 C语言编译时生成的所有两头文件都会放在objs下的src目录下,如果咱们应用了动静模块,编译时会生成动静文件,这个动静文件也会放在objs目录下。接下来就能够执行make install(首次装置时执行该命令) 执行完之后,就能够在--prefix执行的门路下看到如下构造这里边最次要的Nginx二进制文件就在sbin目录下,决定Nginx性能的配置文件在conf目录下 能够看到在conf目录下,所有的文件就是在源代码中那个conf目录下所有文件copy过去了一份,内容也是截然不同的 以上便是Nginx的全副编译装置过程 Nginx配置文件通用语法介绍Nginx配置文件中,曾经指定了它蕴含了哪些模块,但每一个模块都提供举世无双的配置语法,这些所有的配置语法,会遵循同样的语法规定配置文件由指令与指令块形成每条指令以;分号结尾,指令与参数间以空格分隔指令块以{}大括号将多条指令组织在一起include语句容许组合多个配置文件以晋升可维护性应用#合乎增加正文,进步可读性应用$符号应用变量局部指令的参数反对正则表达式 ...

April 12, 2021 · 1 min · jiezi

关于php:PHP的引用计数是什么意思

什么是援用计数在PHP的数据结构中,援用计数就是指每一个变量,除了保留了它们的类型和值之外,还额定保留了两个内容,一个是以后这个变量是否被援用,另一个是援用的次数。为什么要多保留这样两个内容呢?当然是为了垃圾回收(GC)。也就是说,当援用次数为0的时候,这个变量就没有再被应用了,就能够通过 GC 来进行回收,开释占用的内存资源。任何程序都不能无限度的始终占用着内存资源,过大的内存占用往往会带来一个重大的问题,那就是内存泄露,而 GC 就是PHP底层主动帮咱们实现了内存的销毁,而不必像 C 一样必须去手动地 free 。 怎么查看援用计数?咱们须要装置 xdebug 扩大,而后应用 xdebug_debug_zval() 函数就能够看到指定内存的详细信息了,比方: $a = "I am a String";xdebug_debug_zval('a');// a: (refcount=1, is_ref=0)='I am a String'从上述内容中能够看出,这个 $a 变量的内容是 I am a String 这样一个字符串。而括号中的 refcount 就是援用次数,is_ref 则是阐明这个变量是否被援用。咱们通过变量赋值来看看这个两个参数是如何变动的。 $b = $a;xdebug_debug_zval('a');// a: (refcount=1, is_ref=0)='I am a String'$b = &$a;xdebug_debug_zval('a');// a: (refcount=2, is_ref=1)='I am a String'当咱们进行一般赋值后,refcount 和 is_ref 没有任何变动,但当咱们进行援用赋值后,能够看到 refcount 变成了2,is_ref 变成了1。这也就是说明以后的 \$a 变量被援用赋值了,它的内存符号表服务于 $a 和 $b 两个变量。 $c = &$a;xdebug_debug_zval('a');// a: (refcount=3, is_ref=1)='I am a String'unset($c, $b);xdebug_debug_zval('a');// a: (refcount=1, is_ref=1)='I am a String'$b = &$a;$c = &$a;$b = "I am a String new";xdebug_debug_zval('a');// a: (refcount=3, is_ref=1)='I am a String new'unset($a);xdebug_debug_zval('a');// a: no such symbol持续减少一个 $c 的援用赋值,能够看到 refcount 会持续减少。而后 unset 掉 $b 和 $c 之后,refcount 复原到了1,不过这时须要留神的是,is_ref 仍然还是1,也就是说,这个变量被援用过,这个 is_ref 就会变成1,即便援用的变量都曾经 unset 掉了这个值仍然不变。 ...

April 12, 2021 · 2 min · jiezi

关于php:最全PHP学习路线资源总结

文章介绍在之前分享过一篇无关PHP学习路线的思维导图,失去了大家的关注,有敌人举荐依据学习路线分享一些无关的学习资源(学习文章、学习数据或者学习网站等)。该篇文章联合本人学习总结一些不错的学习资源。文章波及到的资源能够通过我集体的公众号获取,间接回复"PHP学习路线资源"即可。同时该文章前面也会不断更新与欠缺,能够通过该链接理解最新进度文档地址 路线提纲 下面的截图就是一个大抵的提纲,接下来就针对整体的提纲做一个具体资源的介绍。上面的截图是集体平时看过的书籍,如果需要的话,你也能够分割我,赠送这些书籍(因集体思考切换城市,不不便携带)。 PHP资源PHP作为一门实用于web开发的编程语言,相比其余的编程语言要求较低一些,在网上的学习资源也是十分多的,集体不举荐看各种文档,可能把官网的文档多看几遍就差不多了。官网文档。为什么举荐把官网文档多看几遍呢? 官网文档首先从学习思路来说,可能从浅到深的学习。可能让你理解到一个明确的学习路线。官网文档有中文版、英文版等多种语言版本,对于英语不是特地好的程序员来说是比拟敌对的。同时文档中也会有局部开发者提供的代码示例,也能够作为学习的一种资源。在相熟官网文档之后,对于PHP的基础知识根本理解的差不多了。这时候须要对其余的常识做一些扩大延长。例如PHP的设计模式、PHP底层相干的理解。 对于PHP设计模式举荐应用上面的网站,PHP设计模式 该网站的文章不仅仅从实践上解说PHP设计模式,还会举理论的案例和代码,让你学习设计模式不会感觉干燥、难懂。 对于大多数PHP开发者来说,想接触一些底层相干的常识,可能无从下手,不晓得如何去学习,集体比拟举荐PHP7底层原理剖析的一本书籍。 该书是腾讯高级工程师秦朋编写,在出版之后也失去业内大牛的举荐。该书基于PHP7版本,围绕SAPI、数据类型、内存治理、编译与执行、函数、类与根底语法的实现,粗浅解析了PHP底层zend引擎的实现原理。是一本学习PHP底层十分不错的书籍。 随着最近几年微服务技术的一直倒退,PHP相干我的项目也开始走向了微服务畛域。从PHP自身语言的角度不是特地适宜,然而也有其余的技术计划能够补救这方面的缺点,如韩天峰老师领导的swoole。 swoole官网文档,对于学习swoole的PHP开发者来说,多看几遍官网文档,同时依据官网文档的代码示例学习根本对swoole的基础知识有所理解,剩下的就是多在我的项目中实际与总结。 MySQL资源MySQL作为一门数据库语言,各大企业也在应用该数据库。也是一个PHP开发者不得不去深刻学习的一门语言。集体还是比拟举荐通过官网文档来学习。 官网文档有残缺的学习路线和常识演绎。常识内容丰盛,不仅仅有MySQL语法的常识,还有各种底层api相干的内容。惟一不好中央就是全文都是英文文档。对于英文不是很好的开发者能够通过高性能MySQL这本书籍来学习,概述涵盖了MySQL的各个知识点。对于想学习好MySQL的开发者,是十分不错的一本书籍。 这里举荐其余的几本MySQL不错的书籍。 MySQL王者升级之路。 对于想深刻理解MySQL中InnoDB存储引擎的能够多看看上面的书籍。 Redis资源Redis作为一门内存型的数据库,因为性能高、数据类型丰盛、反对长久化、集群、哨兵等性能应用畛域也越来越宽泛。对于学习Redis,首先比拟举荐通过书籍来学习,官网文档也只有英文,对于英文不好的开发者学起来可能比拟吃力。 这里举荐上面这本书。 该书没有对Redis底层过多的深刻解说,更多的是从Redis的各个性能、以及实现原理的角度来剖析与总结。例如Redis的数据类型、主从复制、长久化、哨兵、集群等方面的常识。只有你对书中的各个知识点深刻学习,根本对Redis性能有个全面的学习。 看完该书,如果你还想对Redis持续深刻学习一下。能够去极客工夫购买一本Redis核心技术与实战的电子书籍。官网链接 书籍目录 MongoDB资源MongoDB作为一种非关系型的数据库,最近几年也被开始宽泛应用到企业我的项目开发中。MongoDB应用场景总结。 MongoDB的学习,我次要还是通过官网文档,其余中央的文档也临时没发现更好的。官网文档 如果你不喜爱看文档,这里举荐一本书籍。 前端资源作为一个PHP开发者,或多或少都会一些前端的技术,对于一个后端开发者来说,把握根本的前端常识就差不多。我集体也是把握一些vue.js,JavaScript等。平时看的文档也是上面两个网站。 mozilla [vue.js文档] Linux资源Linux对于后端开发者来说,也是一门不得不把握一些根底的程序。例如环境的搭建(lamp),其余服务的搭建、Linux基本操作命令等。 对于根底的命令,集体比拟举荐间接查看手册即可。Linux命令手册 这里举荐几个蛮不错的Linux视频教程,也是集体学习Linux的入门教程,对于理解Linux来说是蛮不错的。 兄弟连Linux视频教程 2021韩顺平 一周学会Linux 计算机资源计算机根底大家大学都学习过了,都是有一些根底的。对于这基础知识比拟单薄的开发者来说,通过看书或者比拟干燥、难懂,这里举荐几个蛮不错的视频。 《深刻了解计算机系统》底层原理 韩立刚计算机网络 谢希仁 第7版 对应的根本书籍。

April 12, 2021 · 1 min · jiezi

关于java:Cloudreve-自建云盘实践我说了没人能限得了我的容量和速度

作者:小傅哥博客:https://bugstack.cn 积淀、分享、成长,让本人和别人都能有所播种!一、前言为啥要用自建网盘,市面上的云盘不香了? 每一个用户需要的背地都是因为有场景存在,而这些差异化的场景也都是因为不同的用户类型产生的。 就像我作为技术号主想分享一些本人总结的材料,放到一些云盘当前有时候会被其余不晓得从哪冒出来的小伙伴给举报,举报链接就勾销了,勾销了链接也就影响了我的材料分享。同时我可能还心愿我的分享内容能被记录到下载次数、容许几次下载、下载时是否要做一些引流动作等等。 所以相似这样的非凡场景下就须要自建网盘来保护集体须要的材料,与之类似的还有一些公司或者组织都会建绝对私域的网盘性能服务性能,给予外部用户应用。 所以,也并不一定市面的网盘不香了,只是因为我有须要自建网盘。在这条路上我尝试过自建、kodexplorer、Owncloud等,凑巧最近发现了 Cloudreve 尝试体验后感觉更香,反对的性能更多。所以筹备给小伙伴分享下对于 Cloudreve 的装置、配置和应用,也让有须要的小伙伴能够尝尝鲜。 二、Cloudreve 介绍Cloudreve,帮忙您以最低的老本疾速搭建公私兼备的网盘零碎。 性能 ✨ 个性☁️ 反对本机、从机、七牛、阿里云 OSS、腾讯云 COS、又拍云、OneDrive (包含世纪互联版) 作为存储端 上传/下载 反对客户端直传,反对下载限速 可对接 Aria2 离线下载 在线 压缩/解压缩、多文件打包下载 笼罩全副存储策略的 WebDAV 协定反对⚡ 拖拽上传、目录上传、流式上传解决️ 文件拖拽治理 多用户、用户组 创立文件、目录的分享链接,可设定主动过期️️ 视频、图像、音频、文本、Office 文档在线预览 自定义配色、光明模式、PWA 利用、全站单页利用 All-In-One 打包,开箱即用 材料官网:https://cloudreve.org文档:https://docs.cloudreve.org/getting-started/install社区:https://forum.cloudreve.org源码:https://github.com/cloudreve/Cloudreve演示:https://demo.cloudreve.org三、环境筹备 云服务器资源或本地服务器,举荐腾讯云轻量服务器,内含宝塔组件,算是是几个云服务里最简略的:https://console.cloud.tencent.com/lighthouse/instance/index已备案过的域名,如果不须要域名拜访,能够间接应用云服务提供的公网IPCloudreve安装包:https://github.com/cloudreve/Cloudreve/releases本章节的案例是基于腾讯云的,如果你应用的是其余云服务器,找到对应的地位配置即可。这些云服务应用形式根本大同小异,遇到问题能够分割对应的云服务客服,不要分割我哈哈哈 四、宝塔配置宝塔是一个简略好用的Linux/Windows服务器运维治理面板,在宝塔后盾页面上能够十分不便的安全软件和配置环境。个别能够在云服务器上安装宝塔,有一些厂商也把宝塔集成到本人的云服务器上了。 1. 获取用户名和明码 地址:https://console.cloud.tencent.com/lighthouse/instance/detail?rid=8&id=lhins-90pixwzq&tab=application进入服务的利用治理会看到利用内软件信息:宝塔,在这里点击登录按钮后,会获取到宝塔的登录地址、用户名和明码信息「这些信息能够前期在宝塔后盾批改」。 * Socket connection established * Last login: Sat Apr 10 09:33:50 2021 from 119.29.96.147 [lighthouse@VM-8-9-centos ~]$ sudo /etc/init.d/bt default ================================================================== BT-Panel default info! ================================================================== 外网面板地址: http://80.71.255.122:8888/cloudtencent 内网面板地址: http://10.0.8.9:8888/cloudtencent *以下仅为初始默认账户明码,若无奈登录请执行bt命令重置账户/明码登录 username: 3kkjecc3 password: 3f7d2743018b If you cannot access the panel, release the following panel port [8888] in the security group 若无法访问面板,请查看防火墙/平安组是否有放行面板[8888]端口 ==================================================================2. 8888 端口受权 ...

April 12, 2021 · 2 min · jiezi

关于php:Laravel-Artisan-命令行的使用

根底应用# 列出所有可用命令php artisan list# 查看命令帮忙php artisan help migrate编写命令php artisan make:command SendEmails# app/Console/Commands/SendEmails.phpnamespace App\Console\Commands;use App\User;use App\DripEmailer;use Illuminate\Console\Command;class SendEmails extends Command{ /** * 命令行的名称及签名 */ protected $signature = 'email:send {user}'; /** * 命令行的形容 */ protected $description = 'Send drip e-mails to a user'; public function __construct() { parent::__construct(); } /** * 命令运行内容 */ public function handle(DripEmailer $drip) { $drip->send(User::find($this->argument('user'))); }}命令参数和选项// 必填参数email:send {user}// 可选参数email:send {user?}// 带有默认值的可选参数email:send {user=foo}// 选项,传入即为true,否则为falseemail:send {user} {--queue}// 接管选项值email:send {user} {--queue=}// 选项的默认值email:send {user} {--queue=default}// 选项简写email:send {user} {--Q|queue}// 输出数组;php artisan email:send foo baremail:send {user*}// 选项数组;php artisan email:send --id=1 --id=2email:send {user} {--id=*}// 输出阐明email:send {user : The ID of the user} {--queue= : Whether the job should be queued}获取输出$userId = $this->argument('user');$arguments = $this->arguments();$queueName = $this->option('queue');$options = $this->options();编写输入# 输入文本$this->line('Display this on the screen');# 输入信息$this->info('Display this on the screen');# 输入谬误$this->error('Something went wrong!');# 输入表格$headers = ['Name', 'Email'];$users = App\User::all(['name', 'email'])->toArray();$this->table($headers, $users);# 输入进度条$users = App\User::all();$bar = $this->output->createProgressBar(count($users));$bar->start();foreach ($users as $user) { $this->performTask($user); $bar->advance();}$bar->finish();注册命令# app/Console/Kernel.php// 手动注册命令protected $commands = [ Commands\SendEmails::class];// 主动扫描目录注册命令protected function commands(){ $this->load(__DIR__.'/Commands'); require base_path('routes/console.php');}

April 11, 2021 · 1 min · jiezi

关于php:rabbitmq常见功能封装-php版本

在我的项目中rabbitmq失去了宽泛的时候,这里对rabbitmq的惯例性能做了一个简略的总结,并封装成了composer包,composer包地址、github地址,欢送fork,因为程度无限,不免存在bug,欢送提出宝贵意见 easy-rabbitmq 包简介对php-amqplib/php-amqplib包的二次封装,为常见性能提供一套开箱即用的生产解决方案。目前反对的性能列表如下: 推送音讯到直连交换机(含提早音讯)推送音讯到扇形交换机(含提早音讯)推送音讯到主题交换机(含提早音讯)订阅模式下的牢靠生产, 消费者生产失败后将会尝试持续生产,最多尝试5次。拉取模式下的牢靠生产, 消费者生产失败后将会尝试持续生产,最多尝试5次。如果还有其它场景,欢送持续补充,随后进行迭代!! 要求安装包对PHP版本对要求次要取决于php-amqplib/php-amqplib包自身对要求,这里为了兼顾php5.0的使用者,咱们应用了php-amqplib/php-amqplib包V2.9.0的版本。具体的要求参照这里。不过笔者举荐应用php7.0及其以上版本, 这个开发包也是在7.0这个版本下面开发实现的!装置 composer require maweibinguo/easyrabbitmq应用在这里咱们举荐php脚本+supervisor联合应用,用以保障生产过程的可靠性、加强worker的生产能力! 如果你还没有据说过supervisor,能够点击这里理解. 1、推送音讯1-1、推送音讯到直连交换机 $config = [ "host" => "127.0.0.1", "port" => "5672", "user" => "guest", "password" => "guest", "vhost" => "/", "channel_max_num" => 10, ]; $instance = RabbitMq::getInstance($config); //提早音讯,30 秒中后才会达到指定的交换机 $instance->pushToDirect( $msg = time(), //音讯体内容 $exchange = "easy_direct_exchange", //交换机名称 $routingKey = "direct_test_queue", //音讯的routingkey,consume办法到bingdingkey 要和routingkey保持一致 $delaySec = 30 //提早秒数 ); //无提早,推入到指定到直链交换机 $instance->pushToDirect( $msg = time(), //音讯体内容 $exchange = "easy_direct_exchange", //交换机名称 $routingKey = "direct_test_queue", //音讯的routingkey,consume办法到bingdingkey 要和routingkey保持一致 );1-2、推送音讯到扇形交换机 $config = [ "host" => "127.0.0.1", "port" => "5672", "user" => "guest", "password" => "guest", "vhost" => "/", "channel_max_num" => 10, ]; $instance = RabbitMq::getInstance($config); //提早音讯,30 秒中后才会达到指定的交换机 $instance->pushToFanout( $msg = time(), //音讯体内容 $exchange = "easy_fanout_exchange", //交换机名称 $delaySec = 30 //提早秒数 ); //无提早,推入到指定到直链交换机 $instance->pushToFanout( $msg = time(), //音讯体内容 $exchange = "easy_fanout_exchange" //交换机名称 );1-3、推送音讯到主题交换机 $config = [ "host" => "127.0.0.1", "port" => "5672", "user" => "guest", "password" => "guest", "vhost" => "/", "channel_max_num" => 10, ]; $instance = RabbitMq::getInstance($config); //提早音讯,30 秒中后才会达到指定的交换机 $instance->pushToTopic( $msg = time(), //音讯体内容 $exchange = "easy_topic_exchange", //交换机名称 $routingKey = "", $delaySec = 30 //提早秒数 ); //无提早,推入到指定到直链交换机 $instance->pushToTopic( $msg = time(), //音讯体内容 $exchange = "easy_topic_exchange", //交换机名称 $routingKey = "easy.topic.queue" //routingKey 要同consum的bindingKey相匹配 //bindingKey反对两种非凡的字符"*"、“#”,用作含糊匹配, 其中"*"用于匹配一个单词、“#”用于匹配多个单词(也能够是0个) //无论是bindingKey 还是routingKey, 被"."分隔开的每一段独立的字符串就是一个单词, easy.topic.queue, 蕴含三个单词easy、topic、queue );2、生产音讯生产反对主动重试,最多尝试重试5次,每次生产失败后该音讯将会被从新投入到生产队列中。从新的工夫将会随着失败的次数增多逐步推移,本客户端反对的推移策略如下:失败1次(1秒钟后会再被投递), 失败2次(2秒钟后会再被投递), 失败3次(4秒钟后会再被投递), 失败4次(8秒钟后会再被投递), 失败5次(16秒钟后会再被投递) ...

April 11, 2021 · 2 min · jiezi

关于docker:Laradock搭建开发环境

配置本地的 Laradock 环境(开发环境)克隆 laradock 源代码到本地环境在运行前须要装置docker环境 git clone https://github.com/laradock/laradock.git 创立 .env 文件cp env-example-local .env 能够据状况批改 .env 文件里的内容,以下是目前我的项目须要批改的配置。WORKSPACE_COMPOSER_REPO_PACKAGIST=https://mirrors.aliyun.com/co... WORKSPACE_NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirror... ... WORKSPACE_INSTALL_MONGO=trueWORKSPACE_INSTALL_AMQP=true WORKSPACE_INSTALL_SWOOLE=true 参考laradock我的项目中的README-zh.md文档阐明构建镜像docker-compose build workspace mysql nginx redis elasticsearch mongo rabbitmq 开启以下服务docker-compose up -d workspace mysql nginx redis elasticsearch mongo rabbitmq 最初进入容器能够执行其余命令,如果Artisan等 docker-compose exec workspace bash

April 10, 2021 · 1 min · jiezi

关于php:Swoole-v465-版本发布增加原生curl-multi支持

v4.6.5 版本没有向下不兼容改变,次要对原生 curl hook 进行了一些加强,反对了 curl multi 反对原生 curl multi应用原生 curl hook 的前提是在编译 Swoole 扩大时开启--enable-swoole-curl选项 能够应用以下代码进行测试: use Swoole\Runtime;use function Swoole\Coroutine\run;Runtime::enableCoroutine(SWOOLE_HOOK_NATIVE_CURL);run(function () { $ch1 = curl_init(); $ch2 = curl_init(); // 设置URL和相应的选项 curl_setopt($ch1, CURLOPT_URL, "http://www.baidu.com/"); curl_setopt($ch1, CURLOPT_HEADER, 0); curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch2, CURLOPT_URL, "http://www.gov.cn/"); curl_setopt($ch2, CURLOPT_HEADER, 0); curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1); $mh = curl_multi_init(); curl_multi_add_handle($mh, $ch1); curl_multi_add_handle($mh, $ch2); $active = null; // 执行批处理句柄 do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc == CURLM_OK) { $n = curl_multi_select($mh); if ($n != -1) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } $info1 = curl_multi_info_read($mh); $info2 = curl_multi_info_read($mh); $info3 = curl_multi_info_read($mh); assert($info1['msg'] === CURLMSG_DONE); assert($info2['msg'] === CURLMSG_DONE); assert($info3 === false); assert(strpos(curl_multi_getcontent($ch1),'baidu.com') !== false); assert(strpos(curl_multi_getcontent($ch2),'中央人民政府门户网站') !== false); curl_multi_remove_handle($mh, $ch1); curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);});反对 curl multi 之后,也就间接的反对了 Guzzle,无需更改任何代码,即可反对。 ...

April 9, 2021 · 3 min · jiezi

关于php:超酷的开源任务协作系统我粉了

 大家好,我是为宽广程序员兄弟操碎了心的小编,每天举荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节俭开发效率,实现不加班不熬夜不掉头发,是我的指标! 明天小编举荐一款轻量级的在线我的项目/工作合作零碎,反对项目管理、工作治理、账号治理、文件治理、团队治理和权限治理等多项性能,是中小型团队进行相互合作的最佳抉择。将来咱们还将继续迭代新性能,致力于打造一个灵便、高效、易用、乏味的合作零碎,帮忙大家晋升合作效率并且升高团队沟通老本。 开源协定PHP版本应用 GPL-3.0 开源许可协定JAVA版本应用 Apache-2.0 开源许可协定链接地址 公众号【Github导航站】回复关键词【ppr】获取git地址 性能一览项目管理工作合作工作流转统计分析账号相干组织体系我的项目模板文件上传团队成员部门合作系统配置拜访受权音讯推送主题格调技术栈php版 PHPWorkermanMySQLRedisHTML5JavaScriptVue.jsJava版,目前该版本还在欠缺中 JAVA 1.8 MYSQL 8 基于前后端拆散架构,服务端次要技术:springboot 、jwt 前端次要是vue; 演示截图工作台:在工作台能够查看以后已退出的我的项目、我的项目的最近动静和指派给本人的工作登信息 我的我的项目 工作看板 工作详情 文件上传 我的项目详情 团队成员 成员治理 结尾 本期就分享到这里,我是小编南风吹,专一分享好玩乏味、离奇、实用的开源我的项目及开发者工具、学习资源!心愿能与大家独特学习交换,欢送关注我的公众号【Github导航站】。

April 9, 2021 · 1 min · jiezi

关于php:PHP的内置WEB服务器

在很多时候,咱们须要简略的运行一个小 demo 来验证一些代码或者轮子是否可用,是否能够运行起来,然而去配 nginx 或者 apache 都很麻烦,其实,PHP CLI 曾经提供了一个简略的测试服务器,咱们间接就能够运行起来进行简略的一些测试工作。 间接启动一个内置服务器php -S localhost:8081间接应用 -S 命令选项,而后指定地址及端口号,咱们就能够运行起来一个 PHP 内置的繁难WEB服务器。默认状况下,这个地址会找当前目录下的 index.php 或 index.html 文件。当咱们在浏览器输出指定的文件时,就是拜访指定的文件,如果都没有找到会失常的返回404谬误。 而控制台会输入以后服务器的拜访状况,如下图所示: 这个内置服务器和用 nginx 等服务器搭起来的应用服务器实质上没有太大的区别,包含 $_SERVER 之类的内容都能够失常获取到,也能够失常应用 include 等性能加载其余文件,也就是说这个内置WEB服务器运行一些框架也是没有问题的。它是能够齐全满足咱们的测试要求的。然而须要留神的是,这个内置WEB服务器不能用于生产环境。毕竟它的性能还是太简略,不是一个生产装备的高规格服务器利用。 指定内置服务器的运行目录咱们也能够在任何目录去运行指定目录的php代码,只须要再减少一个 -t 选项来指明要运行起服务器的根目录即可。 php -S localhost:8081 -t dev-blog/php/202004/source这样咱们就能够运行起来一个以 dev-blog/php/202004/source 目录为根目录的测试环境服务器。 应用路由脚本php -S localhost:8081 PHP的内置WEB服务器.php如果咱们给以后服务器间接指定了一个PHP文件,那么间接关上链接就会拜访的是这个文件的内容,而不是去找 index.php 之类的文件。即便咱们持续给 URL 后盾减少其余门路或者其余文件名,它仍然会关上的是这个文件,也就是说,咱们启动了一个单文件入口的应用服务器程序。就像各种框架的 index.php 文件一样,比方咱们利用这个文件做一个简略的路由散发测试: $routePages = [ '/testRoute2.php', '/route/testRoute1.php'];if(in_array($_SERVER['REQUEST_URI'], $routePages)){ include __DIR__ . $_SERVER['REQUEST_URI'];}else{ print_r($_SERVER);}// route/testRoute1.phpecho "Hello Route1!";// testRoute2.phpecho "Hello Route2!";两个测试文件只是简略的输入了一段文字用于区别别离加载了两个文件。上述代码的意思是咱们拜访定义好的两个路由门路时,就会加载对应的文件,拜访其余门路则会打印以后服务器的 $_SERVER 信息。 测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202004/source/PHP%E7%9A%84%E5%86%85%E7%BD%AEWEB%E6%9C%8D%E5%8A%A1%E5%99%A8.php ...

April 9, 2021 · 1 min · jiezi

关于php:竞拍系统设计秒杀系统知识迁移

自从上次整顿了秒杀零碎的文章(php+golang商品秒杀)后,常识迁徙一新我的项目,商品竞拍。 技术:php、mysql、redis、laravel业务对象:商品、场次、订单竞拍过程:一、实现商品、竞拍场次和订单的CRUD;二、定时将秒杀场次、商品、库存等信息提前写入redis;三、配置Redis长久化;四、实现秒杀下单逻辑;五、秒杀过程redis优化;六、应用golang并发编程模仿秒杀。 一、实现商品、竞拍场次和订单的CRUD; 商品表: CREATE TABLE `goods` ( `id` int(12) unsigned NOT NULL AUTO_INCREMENT COMMENT 'pk', `num` varchar(64) NOT NULL COMMENT '商品编号', `users_id` int(12) unsigned NOT NULL COMMENT '拥有者', `create_users_id` int(12) unsigned NOT NULL COMMENT '商品创建人', `contract_roles_id` int(10) unsigned NOT NULL COMMENT '商品合约级别外键', `name` varchar(255) NOT NULL COMMENT '商品名称', `img` int(11) NOT NULL COMMENT '封面图', `price` decimal(10,2) unsigned NOT NULL COMMENT '以后价格', `area_id` int(11) NOT NULL COMMENT '区域id', `trade_num` int(11) unsigned NOT NULL COMMENT '交易次数', `user_name` varchar(100) DEFAULT NULL COMMENT '收货人名称', `user_phone` varchar(11) DEFAULT NULL COMMENT '收货人联系电话', `user_address` varchar(255) DEFAULT NULL COMMENT '收货人地址', `express_id` int(11) DEFAULT NULL COMMENT '物流ID', `express_no` varchar(255) DEFAULT NULL COMMENT '物流单号', `is_auction` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否可竞拍,1=》可 2=》不可', `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态1=>可交易 2=>待领取 3=>交易实现 4=>待发货 5=》配送中 6=>实现 7 =>待收款', `next_time` timestamp NULL DEFAULT NULL COMMENT '下次最早显示工夫', `trade_time` timestamp NULL 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=111 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;竞拍场次表: ...

April 9, 2021 · 3 min · jiezi

关于php:PHP打印跟踪调试信息

对于大部分编译型语言来说,比方 C 、 Java 、 C# ,咱们都能很不便地进行断点调试,然而 PHP 则必须装置 XDebug 并且在编辑器中进行简单的配置能力实现断点调试的能力。不过,如果只是简略的调试并且查看堆栈回溯的话,其实 PHP 曾经为咱们筹备好了两个函数,可能让咱们十分不便的看到程序运行时的调用状况。 debug_backtrace()从这个办法的字面意思上就能够看出,它的意思就是调试回溯,返回的也正是一段回溯信息的数组。 function a_test($str){ echo "Hi: $str", PHP_EOL; var_dump(debug_backtrace());}var_dump(debug_backtrace());a_test("A");// Hi: A/Users/zhangyue/MyDoc/博客文章/dev-blog/php/202004/source/PHP打印跟踪调试信息.php:7:// array(1) {// [0] =>// array(4) {// 'file' =>// string(93) "/Users/zhangyue/MyDoc/博客文章/dev-blog/php/202004/source/PHP打印跟踪调试信息.php"// 'line' =>// int(12)// 'function' =>// string(6) "a_test"// 'args' =>// array(1) {// [0] =>// string(1) "A"// }// }// }这个办法必须在函数中调用,在函数办法内部应用是不会有内容的。从内容中看,它输入了对于这个函数的 \_\_FILE__ 、 \_\_LINE__ 、 \_\_FUNCTION__ 、$argv 等信息。其实就是对于以后打印这行所在函数的相干内容。 咱们当然也能够多嵌套几层函数来看一下打印出的内容是什么。 function b_test(){ c_test();}function c_test(){ a_test("b -> c -> a");}b_test();// Hi: b -> c -> a// /Users/zhangyue/MyDoc/博客文章/dev-blog/php/202004/source/PHP打印跟踪调试信息.php:7:// array(3) {// [0] =>// array(4) {// 'file' =>// string(93) "/Users/zhangyue/MyDoc/博客文章/dev-blog/php/202004/source/PHP打印跟踪调试信息.php"// 'line' =>// int(37)// 'function' =>// string(6) "a_test"// 'args' =>// array(1) {// [0] =>// string(11) "b -> c -> a"// }// }// [1] =>// array(4) {// 'file' =>// string(93) "/Users/zhangyue/MyDoc/博客文章/dev-blog/php/202004/source/PHP打印跟踪调试信息.php"// 'line' =>// int(33)// 'function' =>// string(6) "c_test"// 'args' =>// array(0) {// }// }// [2] =>// array(4) {// 'file' =>// string(93) "/Users/zhangyue/MyDoc/博客文章/dev-blog/php/202004/source/PHP打印跟踪调试信息.php"// 'line' =>// int(40)// 'function' =>// string(6) "b_test"// 'args' =>// array(0) {// }// }// }没错,数组的输入程序就是一个栈的执行程序,b_test() 最先调用,所以它在栈底,对应的输入也就是数组中的最初一个元素。 ...

April 8, 2021 · 2 min · jiezi

关于golang:入门Go语言学习路线图必须跨过的误区

1 大厂认可,岗位需要炽热 最近,能够看到的招聘趋势曾经在大厂中占据了重要的位置,无论是职位的数量和薪资待遇,曾经和java持平,甚至稍微高出一点点。Go 语言具备入门快、程序库多、运行迅速等特点,也是完满均衡了开发效率和执行效率,是各大编程语言中的佼佼者。企业对于 Go 语言的应用状况正逐年回升。自2009年公布以来,Go 语言就深受明星大厂的青睐,包含 腾讯、B站、滴滴、今日头条、小米、奇虎 360、京东等明星公司了,业界甚至一度看好 Go 语言有取代 Java 王者位置的后劲。Go语言是谷歌公司推出的新一代的开发语言,出身名门的 Go 语言,你还不赶快上手,提前学习一下。 2 学习路线 & 基础知识一键获取入门 Go 语言的同学根底不一,具体能够分成上面几类。 零根底的同学:可能正筹备入行或对编程刚开始感兴趣,对计算机、操作系统和网络方面的常识不太理解。无编程教训或者编程教训较少的同学:可能正在从事其余的技术相干工作,兴许能够纯熟编写脚本,然而对程序设计的通用常识和技巧还不太理解。有其余语言编程教训的同学:可能曾经是程序员或软件工程师,能够用其余编程语言纯熟编写程序,但对 Go 语言还不太理解。有肯定 Go 语言编程教训的同学:已有 Go 语言编程根底,写过一些 Go 语言程序,急需进阶却看不清路径。基于以上分类,我制订了一份 Go 语言学习门路和基础知识图。不管你属于上述哪一类,都能够依照此门路去学习深造。 3 进阶高级知识点一一击破除了基础知识之外,如果你想要进阶高级 Go 语言工程师,还须要通关以下的知识点。 数据类型方面: 基于底层数组的切片;为了传递数据的通道;作为一等公民的函数;为实现面向对象的构造体;Go语言特色-无侵入实现的接口。在语法方面: 异步编程大杀器go语句;函数的最初防线defer语句;可做类型判断的switch语句;多通道操作利器select语句;十分有特色的异样处理函数panic和recover。Go 语言自带的程序测试套件,相干的概念和工具包含: 专用的testing代码包;+以及功能强大的go test命令。Go 语言的同步工具: 经典的互斥锁、读写锁、条件变量和原子操作;一次性次执行小助手 sync.Once;长期对象池 sync.Pool;sync.WaitGroup;context.Context;如果你了解了上述知识点,就把握了 Go 语言编程的精华。在这之后,再研读 Go 语言规范库和优良的第三方库,就会事倍功半;应用 Go 语言编写软件时,就会熟能生巧。 4 用美食做为案例,助力高效学习。学习门路逐层深刻:知识点——经典例子——随课练习。精美配图展现,知识点高深莫测,配合学习的代码包,亲自上手每一个实操演练。 企业级实战我的项目—吃货点评网。数据库: MySql后端(Golang语言): Gin Web框架 + Restful Api + 多层架构前端(小程序): React语法 + Taro框架 + Taro UI ...

April 7, 2021 · 1 min · jiezi

关于redis:REDIS自增INCR设置过期时间的原子操作LUAPHP实现

redis的自增操作没有原生的设置过期工夫,只能先自增而后通过expire设置过期工夫,若呈现非凡状况导致设置过期工夫失败,则会导致业务谬误。 上面是基于PHP和LUA脚本编写一个DEMO,使自增和过期工夫成为原子操作,从而防止上述问题。 <?php$redis = new Redis();$result = $redis->connect('127.0.0.1');$lua = <<<LUA local key,ttl=KEYS[1],KEYS[2] if redis.call('EXISTS',key)==0 then redis.call('SETEX',key,ttl,1) return 1 else return tonumber(redis.call('INCR',key)) endLUA;$sequence = $redis->eval($lua,["test",10],2); // eval函数请查问官网阐明文档var_dump("RES:".$sequence);$error = $redis->getLastError();if($error){ var_dump($error);}var_dump("VAL:".$redis->get("test"));var_dump("TTL:".$redis->ttl("test"));

April 7, 2021 · 1 min · jiezi

关于php:一些简单的错误处理函数二

接下来,咱们持续学习 PHP 中的谬误处理函数。上次学习过的函数是错误信息的获取、设置、发送等性能,明天学习的内容次要是对于谬误的捕捉相干的函数。 set_error_handler()首先是大家可能会接触过的一个函数,它能够用来捕捉一些谬误的信息。如果咱们须要对立解决一些谬误,比方规定日志格局或者将错误信息发送到邮件中,个别会在入口文件的结尾在全局范畴内定义一个这个函数进行对立的解决。 echo $a; // Notice: Undefined variable: a ...// E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING 不能解决set_error_handler(function($errno, $errstr, $errfile, $errline){ echo "Has Error:", $errno, ',', $errstr, ',', $errfile, ',', $errline, PHP_EOL; }, E_ALL | E_STRICT);echo $a; // Has Error:8,Undefined variable: a ...set_error_handler() 函数接管一个回调函数和一个谬误接管的类型,它的函数签名是: set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] ) : mixed$error_handler是一个回调(匿名)函数,这个函数外部能够获取到谬误的等级、信息、文件、行数等 handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] ) : bool其中,$errcontext 曾经在 PHP7.2 之后勾销了。 ...

April 7, 2021 · 2 min · jiezi

关于php:什么是PHP代码标识

什么是PHP代码标识,比方如何辨别猪和狗,他们之间必定有不一样的中央. 一样的情理,php与其余语言有什么不一样的中央呢,能够让你一眼就晓得这是用PHP写的 首先PHP代码的文件是以.php结尾的书写PHP代码的前缀,如下代码echo "欢送来PHP客栈网学习php"; ?> 留神这个红色的?>是能够省略的,最好写上放弃完整性 你也可能把代码写在一行上噢!如上面的代码: 这样就在页面上打印了一句话 欢送来PHP客栈网学习php 文章原地址:https://www.php-inn.com/detai...文章名::什么是PHP代码标识转载本文请附上文章原地址! 微信小程序收费学习 PHP零根底收费学习 欢送关注我的公众号:子枫的微妙世界,取得独家整顿的学习资源和日常干货推送。 如果您对我的其余专题内容感兴趣,中转我的集体博客:www.wangmingchang.com 。

April 7, 2021 · 1 min · jiezi

关于php:Docker-搭建-PHP-环境

版本介绍cli 命令行版本apache apache版本fpm 反向代理版本alpine 精简版本buster & stretch 用于Debian发行版应用形式形式一:基于 Dockerfile 构建vim DockerfileFROM php:7.3-fpmRUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"COPY . /usr/src/myappWORKDIR /usr/src/myappCMD [ "php", "./your-script.php" ]$ docker build -t my-php-app .$ docker run -it --rm --name my-running-app my-php-appPHP_INI_DIR 为 /usr/local/etc/phpWORKDIR 为 /var/www/html形式二:基于目录挂载运行$ docker run -it --rm --name my-running-script -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:7.3-fpm php your-script.php应用实战cd ~mkdir -p docker/phpdocker run -d --rm --name php php:7.3-fpm# 将所有配置文件复制到宿主机docker cp php:/usr/local/etc ~/docker/phpls etc/# 进行容器docker stop php启动容器 docker run -itd --name php -p 9001:9000 \-v /mnt/website/project-name:/var/www/html \-v /root/docker/php/etc:/usr/local/etc \php:7.3-fpm配置Nginx ...

April 6, 2021 · 1 min · jiezi

关于redis:redis入门教程3客户端

php1:php-redisc语言开发,效率较高。在应用前须要装置phpredis扩大。毛病是有些波及底层的代码须要查看对应的C代码。一些框架(比方thinkphp)在操作redis时会优先应用php-redis。总体举荐应用 参考 https://github.com/phpredis/p...2:predis/predis应用php开发的redis客户端。效率绝对php-redis来说会低一些。不须要装置对应扩大。在一些框架中(laravel)会优先应用。据说前期将不再保护。 参考 https://github.com/predis/predisgogo-redisgithub上star较多的一款go redis客户端。 参考 https://github.com/go-redis/r...

April 6, 2021 · 1 min · jiezi

关于php:Macbook-m1-Big-Sur-安装Valet-运行yii2

筹备工作假设你曾经在本机装置实现了 brew / composer / php查看环境变量$echo $PATH | grep composer#如果没有,增加环境变量$export PATH=~/.composer/vendor/bin:$PATH#检查一下$echo $PATH | grep composer/Users/yourname/.composer/vendor/bin:全局装置Valet$composer global require laravel/valetChanged current directory to /Users/yuanjian/.composerUsing version ^2.14 for laravel/valet./composer.json has been createdLoading composer repositories with package informationUpdating dependencies (including require-dev)Package operations: 22 installs, 0 updates, 0 removals - Installing symfony/polyfill-php80 (v1.22.1): Loading from cache - Installing symfony/polyfill-mbstring (v1.22.1): Loading from cache - Installing symfony/polyfill-php72 (v1.22.1): Loading from cache - Installing symfony/var-dumper (v4.4.21): Downloading (100%) - Installing tightenco/collect (v8.0.4): Downloading (100%) - Installing nategood/httpful (0.2.20): Downloading (100%) - Installing symfony/process (v4.4.20): Loading from cache - Installing psr/container (1.0.0): Loading from cache - Installing php-di/invoker (2.0.0): Downloading (100%) - Installing symfony/service-contracts (v1.1.9): Downloading (100%) - Installing symfony/polyfill-php73 (v1.22.1): Loading from cache - Installing symfony/console (v4.4.21): Loading from cache - Installing mnapoli/silly (1.7.2): Downloading (100%) - Installing psr/simple-cache (1.0.1): Loading from cache - Installing symfony/translation-contracts (v1.1.10): Downloading (100%) - Installing symfony/translation (v4.4.21): Downloading (100%) - Installing nesbot/carbon (2.46.0): Downloading (100%) - Installing doctrine/inflector (1.3.1): Downloading (100%) - Installing illuminate/contracts (v5.8.36): Downloading (100%) - Installing illuminate/support (v5.8.36): Downloading (100%) - Installing illuminate/container (v5.8.36): Downloading (100%) - Installing laravel/valet (v2.14.1): Downloading (100%) symfony/service-contracts suggests installing symfony/service-implementationsymfony/console suggests installing symfony/event-dispatchersymfony/console suggests installing symfony/locksymfony/console suggests installing psr/log (For using the console logger)symfony/translation suggests installing symfony/configsymfony/translation suggests installing symfony/yamlilluminate/support suggests installing illuminate/filesystem (Required to use the composer class (5.8.*).)illuminate/support suggests installing moontoast/math (Required to use ordered UUIDs (^1.1).)illuminate/support suggests installing ramsey/uuid (Required to use Str::uuid() (^3.7).)illuminate/support suggests installing vlucas/phpdotenv (Required to use the env helper (^3.3).)Writing lock fileGenerating autoload files11 packages you are using are looking for funding.Use the `composer fund` command to find out more!Valet install这将配置并装置 Valet 和 DnsMasq。此外,Valet 依赖的守护程序将配置为在系统启动时启动: ...

April 6, 2021 · 2 min · jiezi

关于php:PHP是什么PHP可以做什么为什么要用php

PHP 是什么PHP(Hypertext Preprocessor)即“超文本预处理器”,是在服务器端执行的脚本语言,尤其实用于Web开发并可嵌入HTML中。PHP语法利用了C、Java和Perl,该语言的次要指标是容许web开发人员疾速编写动静网页,这是百科对php的定义. PHP内核由C开发,因而在语法上跟C有不少相似之处。但PHP相对不是C。 PHP语法除了跟C有相似之处外,还跟Java、Perl比拟风行的编程语言存在类似的中央。因而,如果你有上述语言根底,PHP入门会更加疾速。 PHP能够做什么PHP能够开发网站程序,并且开发疾速.,这是我对PHP的认知 PHP能间接嵌入HTML语言中,与HTML混编。PHP开发的目标次要是容许 web 开发人员疾速编写动静生成的 web 页面,但 PHP 的用处远不只于此。 PHP能开发微信公众号 PHP能开发公司官网 PHP能开发商城零碎 PHP能开发微信小程序 PHP能做api接口 php能开发博客 等等..... 闻名的软件程序包含wordpress,discuz,shopex等等都有PHP的身影 为什么要用PHP1、PHP是开源,开发收费,没有任何免费的我的项目。能够轻易批改他的内核而后用于本人的商业应用。 2.、PHP开发组件丰盛 3、社区成熟,85%以上的问题能在社区找到相应的解决思路。 4、PHP学习成本低,不想某门语言要学就得三件套。见效快,学1个月根本能入门 5、开源库丰盛,根本所有类型均有开源产品 6、PHP7.0根本不输任何一门语言~!这是重点 7、与MySQL近乎完满的反对 8、找工作容易 看了这么多益处终于晓得了程序员业界流传的一句话 php是最好的语言~~~ 文章原地址:https://www.php-inn.com/detai...文章名::PHP是什么?PHP能够做什么?为什么要用php?转载本文请附上文章原地址! 微信小程序收费学习 PHP零根底收费学习 欢送关注我的公众号:子枫的微妙世界,取得独家整顿的学习资源和日常干货推送。 如果您对我的其余专题内容感兴趣,中转我的集体博客:www.wangmingchang.com 。

April 6, 2021 · 1 min · jiezi

关于php:防盗链的原理以及实现

大家在拜访网站的时候,常常会看到图片展现不进去的时候,如下图 大家有没有想过这是为什么嘛?其实这是一种简略的防盗链的解决,那么盗链是什么呢?为什么须要防呢?咱们明天来一起揭开它神秘的面纱。 盗链的概念盗链是指在本人的页面上展现一些并不在本人服务器上的一些内容, 获取他人的资源地址,绕过他人的资源展现页面,间接在本人的页面上向最终用户提供此内容。 个别被盗链的都是图片、 音乐、视频、软件等资源。通过盗链的伎俩能够加重本人服务器的累赘 比方我间接在本人的网站上 ![](http:www.baidu.com/imagepath/image.png)这样就能够间接展现百度的图片,然而实际上是无奈展现的(如下图),之所以无奈展现是因为百度的图片做过防盗链解决 防盗链的工作原理通过Refer或者签名,网站能够检测指标网页拜访的起源网页,如果是资源文件,则能够追踪到显示他的网页地址 一旦检测到起源不是本站,即进行阻止或者返回指定的页面 防盗链的实现办法Nginx模块,ngx_http_referer_module用于阻挡起源非法域名的申请 nginx指令valid_refers,全局变量$invalid_refer对资源的防盗链nginx配置为 location ~.*\.(gif|jpg|png|flv|swf|rar|zip)${ valid_referers none blocked test.com *.test.com; //加none的目标是确保浏览器能够间接拜访资源 if($invalid_referer) { #return 403; // 间接返回403 rewrite ^/ http://www.test.com/403.jpg;//返回指定提醒图片 }}对目录的防盗链nginx配置为 location /images/{ valid_referers none blocked test.com *.test.com; if($invalid_referer) { #return 403; rewrite ^/ http://www.test.com/403.jpg; }然而传统的防盗链也会存在一些问题,因为refer是能够伪造的, 所以能够应用加密签名的形式来解决这个问题。 什么是加密签名?就是当咱们申请一个图片的时候,我要给他带一些签名过来,而后返回图片的时候咱们判断下签名是否正确,相当于对一个暗号。 能够应用第三方模块HttpAccessKeyModule来解决防盗链的问题,咱们须要去装置。 装置好有这样一个指令: accesskey on|off 模块开关 accesskey_hashmethod md5 | sha-1 签名加密形式 accesskey_arg GET参数名称 accesskey_signature 加密规定 location ~.*\.(gif|jpg|png|flv|swf|rar|zip)${ accesskey on; accesskey_hashmethod md5; accesskey_arg sign; accesskey_signature "mypass$remote_addr";}意思是mypass加客户端ip通过md5加密 图片文件代码: ...

April 6, 2021 · 1 min · jiezi

关于nginx:初识Nginx一

因为Nginx对硬件和操作系统内核个性的深度开掘,使得它在放弃高并发的同时,实现了高吞吐量。优良的模块设计,使得Nginx的生态圈,异样丰盛。大量的第三方模块,使得Nginx能够轻松实现各种场景下的定制化需要 这些个性,使得Nginx成为互联网公司的标准配置 Nginx的三个次要利用场景 往往一个web申请从红色的箭头走下来当前,会先通过Nginx,再到应用服务,而后再去拜访Redis或者MySQL这样的数据库,提供根本的数据性能 这里有一个问题,应用服务因为对开发效率要求特地的高,它的运行效率是很低的,它的QPS、TPS或者并发都是受限的,所以就须要把很多这样的应用服务组成一个集群,向用户提供高可用性,而一旦很多应用服务形成集群的时候,就须要Nginx具备反向代理性能,能够将动静申请传给应用服务 很多的应用服务组成的集群,它肯定会带来两个需要: 须要动静的扩容有些服务出问题的时候,须要做容灾这样就使反向代理必须具备负载平衡性能。其次,在这样的一个链路中,Nginx是处在企业外部网络的边缘节点,随着网络链路的增长,用户体验到的时延会减少,所以如果咱们能把一些用户看起来不变的,或者在一段时间内看起来不变的动静内容,缓存在Nginx局部,由Nginx间接向用户提供拜访。那么这样用户拜访时延就会缩小很多 所以反向代理会衍生出另外一个性能叫缓存,它能减速拜访。很多时候咱们在拜访css、js或者一些小的图标图片,这样的动态资源,是没有必要由应用服务来提供拜访的,它只须要通过本地文件,零碎上搁置的动态资源,间接由Nginx提供拜访就能够了,这就是Nginx提供动态资源服务性能 第三个利用场景,则是因为应用服务它自身的性能因为有很多的问题,然而数据库服务要比应用服务好的多,因为它的利用场景比较简单,它的并发性能和TPS都要远高于应用服务,所以就衍生出第三个利用场景。由Nginx间接去拜访数据库(Redis或者相似这样的服务),利用Nginx弱小的并发性实现如:web防火墙,这样简单的业务性能来提供给用户。这要求API服务有十分弱小的业务解决性能,所以像OpenResty,或者像Nginx集成的JavaScript,利用JavaScript、Lua这样的语言性能,和它们语言先天自带的一些工具库来提供残缺的API服务 Nginx呈现的历史背景互联网数据量的快速增长摩尔定律:性能晋升低效的Apache次要是全球化和物联网的疾速倒退,导致接入互联网的人与设施的数量都在疾速回升,数据的疾速爆炸,对硬件性能提出了很高的要求,提到硬件,大家都晓得摩尔定律。之前我的服务跑在1GHz的CPU上,一年半当前,我更新到2GHz的CPU时,我能够预测到我的服务会有两倍的性能晋升 然而到本世纪初,摩尔定律在单颗CPU的频率上曾经生效了,CPU开始向多核方向倒退。这个时候,当你的服务是跑在8核CPU上时,一年当前,你换到16核的CPU,通常你的服务不会有一倍的性能晋升的 那么这些性能到底损耗在哪里? 次要是操作系统和大量的软件没有做好服务于多核架构的筹备,比方Apache,Apache是低效的,因为它的架构模型里,一个过程,同一时间,只会解决一个连贯一个申请,只有在这个申请解决完当前,才会去解决下一个申请 这有什么潜台词呢?这实际上是在应用操作系统的过程间切换的个性,因为操作系统宏观上只有无限的CPU,然而操作系统被设计为同时服务于数百甚至上千的过程,而Apache一个过程只能服务于一个连贯,这样的模式,会导致,当Apache须要面对几十万、几百万连贯的时候,它没有方法去开几百万的过程,而过程间切换的代价、老本又太高。当并发的连接数变多,这些过程间切换,引发的性能耗费也就越大。而Nginx是专门为了这样的利用场景而生的。Nginx能够解决数百万甚至数千万的并发连贯 Nginx的长处高并发、高性能可扩展性好高可靠性热部署BSD许可证它的Y轴是每秒解决的申请数(RPS),X轴是并发连接数。从图中能够看到,大部分的程序或web服务器,随着并发连接数的回升,它的RPS会急剧的降落,这就是上边说到的,它的架构设计是有问题的 Nginx的第一个长处就是高并发、高性能同时具备的,往往高并发只须要对每一个连贯所应用的内存尽量的少就能够达到。而具备高并发的同时又具备高性能,往往须要十分好的设计。Nginx能够达到什么样的规范呢?比如说当初比拟支流的服务器(32核、64G内存),能够轻松达到数千万的并发连贯,如果是解决一些简略的动态资源申请,它能够达到100w的RPS 第二个外围长处是它的可扩展性十分的好。它的可扩展性次要体现在它的模块化设计,模块化设计的十分稳固,使得Nginx的第三方模块生态圈十分的丰盛。丰盛的生态圈,为Nginx丰盛的性能提供了保障 第三个长处是它的高可靠性。所谓高可靠性是指Nginx能够在服务器上继续不间断的运行数年,而很多web服务器,往往运行几周或者几个月就须要做一次重启。对于Nginx这样一个高并发、高性能的反向代理服务器而言,它往往运行在企业内的边缘节点上,这个时候,如果企业想提供4个9,5个9,甚至更高的高可用性时,对Nginx继续运行,可能宕机的工夫一年可能只能以秒来计。所以在这样一个角色中,Nginx的高可靠性,提供了十分好的保障 第四个长处是热部署。是指能够在不进行服务的状况下降级Nginx,这个性能对Nginx来讲十分重要,因为在Nginx上可能跑了数百万的并发连贯。如果是一般的服务,咱们可能是须要kill掉过程而后再重启的形式就能够解决好。然而对于Nginx而言,因为kill掉Nginx过程,会导致操作系统为所有的曾经建设连贯的客户端发送一个TCP中的reset复位包,而很多的客户端是没有方法很好的解决复位申请的。在大并发场景下,一些偶尔事件,就会导致必然的恶性后果,所以热部署是十分有必要的 第五个长处是BSD许可证。它指的是Nginx不仅是开源的、收费的,而且大家能够在有定制的场景上来批改Nginx的源代码,在商业场景下是非法的 Nginx的四个次要组成部分 Nginx二进制可执行文件这个是由Nginx自身的框架,它的官网模块和编译进去的各种第三方模块,一起构建的文件。这个文件就相当于汽车自身,它有残缺的零碎,所有的性能都由它提供 Nginx.conf配置文件它相当于驾驶员,尽管二进制可执行文件曾经提供了许多性能,但这些性能有没有开启,或者开启了当前,定义怎么的行为解决申请,都是由Nginx.conf配置文件决定的。所以它相当于驾驶员,管制汽车的行为 access.log拜访日志它相当于这辆汽车通过的所有中央造成了GPS轨迹,access.log会记录下每一条http申请信息与响应信息 error.log谬误日志它相当于黑匣子一样,当呈现了一些不可预期的问题时,能够通过error.log去把问题定位进去 Nginx的版本公布状况 feature:公布了哪些性能bugfix:修复了哪些bugchange:做了哪些小的重构

April 6, 2021 · 1 min · jiezi

关于github:别再傻乎乎地买企业微信SCRM了试试这款开源项目

 大家好,我是为宽广程序员兄弟操碎了心的小编,每天举荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节俭开发效率,实现不加班不熬夜不掉头发,是我的指标! 明天的我的项目来自一位读者的投稿,举荐的是一款开源的企业微信利用开发框架&引擎,同时反对PHP/JAVA的语言,一套通用的企业微信管理系统,得益于 Swoole 和 Hyperf 框架的优良,本我的项目可提供超高性能的同时,也放弃着极其灵便的可扩展性。 开源协定 开源版遵循 GPL-3.0 开源协定公布,100%开源,并提供收费钻研应用,但绝不允许批改后和衍生的代码做为闭源的商业软件公布和销售! 链接地址 公众号【Github导航站】回复关键词【moc】获取git地址与教程 技术栈前端技术栈: Vue、Vuex、Vant、Ant Design of Vue后端技术栈: 同时反对PHP与Java、MySQL、Redis、 Swoole、Hyperf利用场景 可用于电商、金融、批发、餐饮服装等服务行业的企业微信用户,通过简略的分流、引流转化微信客户为企业客户,联合弱小的后盾反对,灵便的经营模式,建设企业与客户的强分割,让企业的盈利模式有了多种不同的抉择。 性能个性引流获取:通过多渠道活码获取客户,条理有序分类客户转化:素材库、欢送语互动客户,增强与客户分割客户治理:精准定位客户,一对一标签编辑,自定义跟踪轨迹,散失客户揭示与反馈客户群治理:于客户的根底,进一步获取客户裂变,主动拉群。集中管理,疾速群发聊天侧边栏:进步企业员工沟通效率,精准服务企业风控:客户聊天记录存档,并设立敏感词库、敏感词报警,多方位跟进治理员工服务局部演示截图 结尾 本期就分享到这里,我是小编南风吹,专一分享好玩乏味、离奇、实用的开源我的项目及开发者工具、学习资源!心愿能与大家独特学习交换,欢送关注我的公众号【Github导航站】。

April 6, 2021 · 1 min · jiezi

关于php:PHP常见模块扩展

gd图像的生成和解决 通过指定编译参数 −−with-gd=DIR 装置。Include GD support. DIR is the GD library base install directory BUNDLED 这是一个打包式的依赖,须要依赖如下安装包。 −−with-webp-dir=DIR(PHP 7.0, 7.1 only) −−with-jpeg-dir=DIR −−with-png-dir=DIR −−with-zlib-dir=DIR −−with-xpm-dir=DIR −−with-freetype-dir=DIR −−enable-gd-native-ttf −−enable-gd-jis-conv PHP5.4、PHP5.5、PHP5.6 则还有个 −−with-vpx-dir=DIR Debian/Ubuntu 需装置 libwebp-dev, libjpeg-dev, libpng-dev, libxpm-dev, libfreetype6-dev, libvpx-dev 依赖包。 Redhat/CentOS 需装置 libwebp-devel, libjpeg-devel, libpng-devel, libXpm-devel, freetype-devel, libvpx-devel 依赖包。 bz2用于读写 bzip2(.bz2)压缩文件 装置--with-bz2[=DIR] calendar日历 装置--enable-calendar ctype字符检测 此扩大默认为启用,编译时可通过下列选项禁用:−−disable-ctype curlPHP 反对 Daniel Stenberg 创立的 libcurl 库,可能连贯通信各种服务器、应用各种协定。 通过指定编译参数 −−with-curl=DIR 装置 datetime日期和工夫 日期和工夫函数,默认编译装置,不可禁止。 DBA通过指定编译参数 −−enable-dba 装置。该参数会默认自带 3个参数,−−with-cdb,−−enable-inifile,inifile-flatfile,若要禁止,则需通过参数−−without-cdb=DIR,−−disable-inifile,−−disable-flatfile 实现 ...

April 5, 2021 · 4 min · jiezi

关于golang:Go-群友提问Goroutine-数量控制在多少合适会影响-GC-和调度

若有任何问题或倡议,欢送及时交换和碰撞。我的公众号是 【脑子进煎鱼了】,GitHub 地址:https://github.com/eddycjy。大家好,我是煎鱼。 前几天在读者交换群里看到一位小伙伴,收回了一个致命发问,那就是:“单机的 goroutine 数量管制在多少比拟适合?”。 兴许你和群内小伙伴第一反馈一样,会回答 “管制多少,我感觉没有定论”。 紧接着延长出了更进一步的纳闷:“goroutine 太多了会影响 gc 和调度吧,次要是怎么估算这个数是正当的呢?” 这是本文要进行探讨的主体,因而本文的构造会是先摸索基础知识,再一步步揭开,深刻了解这个问题。 Goroutine 是什么Go 语言作为一个新生编程语言,其令人青睐的个性之一就是 goroutine。Goroutine 是一个由 Go 运行时治理的轻量级线程,个别称其为 “协程”。 go f(x, y, z)操作系统自身是无奈明确感知到 Goroutine 的存在的,Goroutine 的操作和切换归属于 “用户态” 中。 Goroutine 由特定的调度模式来管制,以 “多路复用” 的模式运行在操作系统为 Go 程序调配的几个零碎线程上。 同时创立 Goroutine 的开销很小,初始只须要 2-4k 的栈空间。Goroutine 自身会依据理论应用状况进行自伸缩,十分轻量。 func say(s string) { for i := 0; i < 9999999; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) }}func main() { go say("煎鱼") say("你好")}人称能够开几百几千万个的协程小霸王,是 Go 语言的得意之作之一。 调度是什么既然有了用户态的代表 Goroutine,操作系统又看不到他。必然须要有某个货色去治理他,能力更好的运作起来。 ...

April 5, 2021 · 2 min · jiezi

关于php:Laravel-Eloquent-ORM-常用操作整理

Laravel 反对原生的 SQL 查问、晦涩的查问结构器 和 Eloquent ORM 三种查问形式: 晦涩的查问结构器(简称DB),它是为创立和运行数据库查问提供的一个接口,反对大部分数据库操作,和手写SQL 的实质是一样的。Eloquent ORM(简称ORM),是一个对象关系映射(Object Relational Mapper)工具,通过建设模型与数据表进行交互,它会把数据库中的数据映射成对象和汇合对象,无需接触底层数据,能够间接调用映射进去的对象进行开发。这篇笔记次要来整顿下罕用的ORM 操作。 查问artisan tinker 是 Laravel 框架自带的命令,用以调出 Laravel 的交互式运行时,Eloquent ORM 的代码能够间接在该环境中运行。 查问列表获取所有数据: use App\Models\User;$users = User::all();如果只须要局部字段,有两种形式进行限定: $users = User::all(["id", "name"]);$users = User::select("id", "name")->get();获取单列: $name = User::pluck('name');// ["boo", "mac", "yumi"]还能够在返回的汇合中指定字段的自定义键名,留神:该自定义键必须是该表的其它字段列名,否则会报错: $name = User::pluck('email','name');// ["boo" => "boo@example.com", "yumi" => "yumi@example.com"]查问单条数据// 通过主键获取模型$user = User:;find(1);// 获取匹配查问条件的第一个模型$user = User::where('is_enable', 1)->first();// 获取第一条数据的指定列值$user = User::value("name"); // 返回后果是字符串:boo// 传递主键数组来调用 find 办法,返回匹配记录汇合$user = User::find([1,2,3]); // 等同于 $user = User::whereIn("id", [1,2,3])->get();解决返回后果集Eloquent ORM 查问返回值是 Illuminate\Database\EloquentCollection 的一个实例,所以除了能够应用传统的数组形式进行遍历,还能够应用汇合形式进行遍历。 ...

April 3, 2021 · 2 min · jiezi

关于后端:进程与socket基础知识分享

不论你目前在有用什么编程语言,你总得要运行在LINUX零碎上【大部分服务端我的项目】咱们的技术体系中,不论如许高大上的技术,外围都是依赖于TCP/IP,而TCP/IP的具体实现接口就是TCP/IP SOCKET API 接口。咱们用的数据库,缓存,DOCKER,等各种编程语言写的利用。都离不开SOCKET。 过程与socket基础知识分享_北风之神Boreas-CSDN博客

April 3, 2021 · 1 min · jiezi

关于后端:rustjavagocphp-socket-系统调用syscall

https://www.bilibili.com/vide...

April 3, 2021 · 1 min · jiezi

关于php:本人基于PHP8开发了一款网络编程框架欢迎大家尝试感谢标星

Dce是一款基于PHP8开发的网络编程框架,反对传统Cgi式Web编程及命令行工具编程,也反对Swoole下常驻内存式Web编程与长连贯服务器编程,并且设计了一套通用的RCR架构解决所有类型网络编程,让你的利用我的项目放弃清晰整洁,助你轻松编写出易复用、好保护的代码。 Dce还有很多特色性能,其中最为重量级的是分库中间件,能够让你轻松实现分库查问。除此之外还提供有负载平衡连接池、近程过程调用、ID生成器、并发锁、会话管理器等特色性能,这些性能依赖Swoole,Dce作者也强烈推荐你在Swoole下应用Dce,配合其多过程协程模式,能够将你的服务器性能施展到极致。 当然,除了上述性能外,如模型、校验器、缓存器、事件、查询器、流动记录等这些惯例的功能模块也必不可能短少。 为了不便上手,作者为各功能模块编写了应用示例: 框架地址:我的项目阐明地址DCE库库我的项目,在DCE或者第三方利用我的项目中引入取得DCEhttps://github.com/idrunk/dceDCE利用DCE利用初始我的项目,通过本我的项目疾速初始化一个DCE利用https://github.com/idrunk/dce...DCE应用示例该分支下有作者编写的各种DCE功能模块的应用示例https://github.com/idrunk/dce...DCE文档官网文档站点https://drunkce.com创作不易,你的一颗星是对作者的莫大反对,在此谢过!

April 2, 2021 · 1 min · jiezi

关于php:互联网黑话生成器php版

<?php$stencil = '{n40}是{v0}{n41},{v1}行业{n30}。{n42}是{v2}{n20}{n43},通过{n31}和{n32}达到{n33}。{n44}是在{n45}采纳{n21}打法达成{n46}。{n47}{n48}作为{n22}为产品赋能,{n49}作为{n23}的评判规范。亮点是{n24},劣势是{n25}。{v3}整个{n410},{v4}{n26}{v5}{n411}。{n34}是{n35}达到{n36}规范。';$num = ['v' => 6, 'n2' => 7, 'n3' => 7, 'n4' => 12];# 二字动词$v = ['皮实', '复盘', '赋能', '加持', '积淀', '倒逼', '落地', '串联', '协同', '反哺', '兼容', '包装', '重组', '履约', '响应', '量化', '发力', '布局', '联动', '细分', '梳理', '输入', '减速', '共建', '共创', '撑持', '交融', '解耦', '聚合', '集成', '对标', '对齐', '聚焦', '抓手', '拆解', '拉通', '形象', '摸索', '提炼', '买通', '吃透', '迁徙', '散发', '分层', '封装', '辐射', '围绕', '复用', '浸透', '扩大', '开辟', '给到', '死磕', '破圈'];# 二字名词$n2 = ['漏斗', '中台', '闭环', '打法', '纽带', '矩阵', '刺激', '规模', '场景', '维度', '格局', '状态', '生态', '话术', '体系', '认知', '玩法', '体感', '感知', '调性', '心智', '战斗', '合力', '赛道', '基因', '因子', '模型', '载体', '横向', '通道', '补位', '链路', '试点'];# 三字名词$n3 = ['新生态', '感知度', '颗粒度', '方法论', '组合拳', '引爆点', '点线面', '精细化', '差异化', '平台化', '结构化', '影响力', '耦合性', '易用性', '便捷性', '一致性', '端到端', '短平快', '护城河'];# 四字名词$n4 = ['底层逻辑', '顶层设计', '交付价值', '生命周期', '价值转化', '强化认知', '资源歪斜', '欠缺逻辑', '抽离透传', '复用打法', '商业模式', '疾速响应', '定性定量', '要害门路', '去中心化', '后果导向', '垂直畛域', '归因剖析', '体验度量', '信息屏障'];$randoms = [ 'v' => randWords($v, $num['v']), 'n2' => randWords($n2, $num['n2']), 'n3' => randWords($n3, $num['n3']), 'n4' => randWords($n4, $num['n4'])];foreach ($randoms as $k => $words) { foreach ($words as $wk => $word) { $pos = '{' . $k . $wk . '}'; $stencil = str_replace($pos, $word, $stencil); }}echo $stencil;/** * @param $words * @param $num */function randWords($words, $num){ $keys = array_rand($words, $num); $values = []; foreach ($keys as $key) { $values[] = $words[$key]; } return $values;}生成示例: ...

April 2, 2021 · 2 min · jiezi

关于php:我们也有自带的缓存系统PHP的APCu扩展

想必大家都应用过 memcached 或者 redis 这类的缓存零碎来做日常的缓存,或者用来抗流量,或者用来保留一些罕用的热点数据,其实在小我的项目中,PHP 也曾经为咱们筹备好了一套简略的缓存零碎,齐全可能应酬咱们日常一般规模站点的开发。这一套扩大就是 APCu 扩大。 APCu 扩大APCu 扩大是 APC 扩大的降级,APC 扩大曾经不保护了。这两套扩大其实都是基于 opcode caching 。也就是 PHP 本身的 opcode 来实现的缓存能力。 APCu 的装置就和一般的 PHP 扩大一样,非常简单,最次要的是这个扩大还十分的小。不论下载还是装置都是秒级能够实现的。所以说可能十分不便的利用于小规模的我的项目,而且是 PHP 原生反对的,不须要额定的端口之类的配置。 办法阐明缓存零碎个别都会有的减少、删除、查问、自增等性能都在 APCu 扩大中有对应的实现。 apcu_add — 创立一个新的缓存apcu_cache_info — 查看 APCu 的全副缓存信息apcu_cas — 更新一个缓存的值为新值apcu_clear_cache — 革除全副的缓存apcu_dec — 自减缓存值apcu_delete — 删除一个缓存的内容apcu_enabled — 以后环境下是否启用 APCu 缓存apcu_entry — 原子地生成一个缓存实体apcu_exists — 查看缓存是否存在apcu_fetch — 查问缓存apcu_inc — 自增缓存值apcu_sma_info — 查问缓存的共享内存信息apcu_store — 保留一个缓存应用演示apcu_add("int", 1);apcu_add("string", "I'm String");apcu_add("arr", [1,2,3]);class A{ private $apc = 1; function test(){ echo "s"; }}apcu_add("obj", new A);var_dump(apcu_fetch("int"));var_dump(apcu_fetch("string"));var_dump(apcu_fetch("arr"));var_dump(apcu_fetch("obj"));失常的应用都是比较简单的,咱们增加各种类型的数据都能够失常存入缓存。不过须要留神的是,咱们能够间接保留对象进入 APCu 缓存中,不须要将它序列化或者JSON成字符串,零碎会主动帮咱们序列化。 ...

April 2, 2021 · 1 min · jiezi

关于php:PHP如何使用DsQueue-pop函数用法代码实例

DsQueue::pop()PHP中的函数用于删除并返回呈现在队列顶部的值。换句话说, 它返回呈现在队列后面的值, 并将其从队列中删除。 语法如下: mixed public DsPriorityQueue::pop ( void )参数:该函数不承受任何参数。 返回值:此函数返回Queue顶部的现值。函数的返回类型是混合的, 并且取决于存储在队列中的值的类型。 例外留神:如果Queue为空, 则此函数引发UnderflowException。 上面的程序阐明了DsQueue::pop()PHP中的性能: 程序1: <?php // Declare new Queue $q = new DsQueue(); // Add elements to the Queue$q ->push( "One" );$q ->push( "Two" );$q ->push( "Three" ); echo "Initial Queue is: n" ;print_r( $q ); // Pop an elementecho "nPopped element is: " ;print_r( $q ->pop()); echo "nnFinal Queue is: n" ;print_r( $q ); ?>输入如下: Initial Queue is: DsQueue Object( [0] => One [1] => Two [2] => Three)Popped element is: OneFinal Queue is: DsQueue Object( [0] => Two [1] => Three)程式2: ...

April 1, 2021 · 1 min · jiezi

关于php:让PHP能够调用C的函数FFI扩展

在大型公司中,个别会有很我编程语言的配合。比如说让 Java 来做微服务层,用 C++ 来进行底层运算,用 PHP 来做中间层,最初应用 JS 展示成果。这些语言间的配合大部分都是通过 RPC 来实现,或者间接将数据入库再应用不同的语言来取用。那么,咱们 PHP 的代码是否间接调用这些语言呢?其实,PHP 还真为咱们筹备了一个能够间接调用 C 语言的扩大库,并且这个扩大库还是曾经默认内置在 PHP 中了,它就是 FFI 扩大。 什么是 FFIFFI , Foreign Function Interface,内部函数接口。这个扩大容许咱们加载一些公共库(.dll、.so),其实也就是能够调用一些 C 的数据结构及函数。它曾经是随 PHP 源码公布的一个扩大了,在编译的时候能够加上 --with-ffi 来间接编译到 PHP 程序中。 咱们这里曾经是编译好的 PHP ,所以咱们间接找到这个扩大,进行简略的扩大装置步骤就能够装置实现。 cd php-7.4.4/ext/ffi/phpize./configuremake && make install装置实现后记得在 php.ini 文件中关上扩大。对于这个扩大须要留神的一点是,它有一个配置项为 ffi.enable ,默认状况下这个配置项的值是 "preload" ,仅在 CLI SAPI 环境下启用 FFI 的能力。当然,咱们也能够批改为 "true" 或 "false" 来开启和敞开它。设定为 "true" 将使得这个扩大在任何环境下都启用。 应用 FFI 调用 C 的函数接下来,简略地看一下它是如何调用 C 的函数的。 // 创立一个 FFI 对象,加载 libc 并且导入 printf 函数$ffi_printf = FFI::cdef( "int printf(const char *format, ...);", // C 的定义规定 "libc.so.6"); // 指定 libc 库// 调用 C 的 printf 函数$ffi_printf->printf("Hello %s!\n", "world"); // Hello World// 加载 math 并且导入 pow 函数$ffi_pow = FFI::cdef( "double pow(double x, double y);", "libboost_math_c99.so.1.66.0");// 这里调用的是 C 的 pow 函数,不是 PHP 本人的echo $ffi_pow->pow(2,3), PHP_EOL; // 8咱们创立了两个对象,别离调用了 C 的 printf() 和 pow() 函数。FFI::cdef() 是用于创立一个 FFI 对象,它接管两个参数,一个是蕴含惯例C语言(类型、构造、函数、变量等)申明序列的字符串。实际上,这个字符串能够从C头文件复制粘贴。而另一个参数则是要加载并定义链接的共享库文件的名称。也就是咱们须要的 .dll 或 .so 文件,它与咱们申明字符串是对应的,比方在 libc.so.6 中并没有 pow() 这类的计算函数,所以咱们就要找到 math 相干的 C 语言计算函数库。 ...

April 1, 2021 · 2 min · jiezi

关于php:Tp5源码分析第五步框架执行流程

初始化利用的数据设置Thinkphp框架执行的时候,首先会执行入口文件,而后执行app的run()办法,在run办法外面,首先会进行初始化利用,调用initialize()办法。首先对initialized属性进行判断,是否本类中存在这个属性或者这个属性是否是true,如果存在或者是true就返回,如果不存在,就对这个属性赋值为true。而后去设置一系列属性,开始工夫,根目录门路,缓存文件门路,路由文件门路,配置文件门路等等。而后执行setInstance进行设置实例,把$this的属性放到这个实例外面。在入口文件外面,调用app的时候曾经进行实例化,然而没有传入属性,在这里二次调用的目标就是把属性放入到实例中去。而后调用instance办法,进行新的实例化并把app放入属性中去。下一步就是进行加载环境变量配置文件.env文件,如果存在就加载,不存在就进行config_ext.php加载。接着加载治理配置文件convention.php,它在thinkphp目录下。通过env实例,应用set进行设置门路环境变量。而后设置namespace,如果没有就设置默认的命名空间app。接着进行注册利用命名空间,通过Loader类的addNamespace办法进行注册。最初初始化利用init。首先开启类名后缀,而后利用调试模式。首先通过容器的env的类,对应的是think下的env.php文件,而后通过get形式获取,如果没有的话,就调用app.app_debug配置项,在config\app.php文件中,而后把这个值赋给环境变量app_debug。而后判断这个值是true还是false,如果是false,就批改ini配置文件里的display_errors为off,如果是true,就从新申请一块比拟大的buffer。接下来就是加载各种配置文件,根命名空间注册等等一系列操作。 初始化init剖析init办法在被调用的时候会被屡次调用,第一次在initialize办法的注册利用命名空间之后的时候,调用了init办法,第二次在run办法的路由监测的时候调用。咱们能够应用debug_backtrace()办法进行打印去找到这两个办法调用的地位。init办法首先去定位模块的目录,依据传入$module参数去查找。而后查找init.php文件是否在application目录,在的话间接加载;不在的话看runtime目录下有没有,而后加载init.php文件,如果没有的话进行各种配置文件加载。例如application目录下的common.php(公共文件)、provider.php(注册服务的容器对象实例)、config.php(配置文件)和thinkphp目录下的helper.php(助手函数文件)以及中间件文件middleware.php文件.下面执行之后,$dir就把所有加载的文件门路赋值进来,而后对它进行文件是否存在判断。接着进行后缀判断,看是否存在在configExt中,存在的话进行load办法解决。接着把$path传递给setModulePath办法。进行模块门路设置。最初对容器中的对象实例进行配置更新。首先获取config内容,而后注册异样解决类,而后获取各种配置信息。加载语言包,查看缓存。对之前获取的配置进行更新。 路由初始化简略剖析在initialize办法最初有一个路由初始化,调用了routeInit办法。咱们来看一下route文件夹下的route目录。它的执行逻辑就是援用Route,而后找到thinkphp\library\think目录下的Route,而后调用get办法,进行注册路由,不止有get,还有post、any、put等等。在这里进行路由监测,看一下在根目录下是否存在route目录,如果存在,就把route目录下的php文件全副获取到,而后进行遍历一个一个进行加载。 路由Route类中rule办法执行形式脑图 路由脑图

March 31, 2021 · 1 min · jiezi

关于php:PHP获取目录中的全部内容RecursiveDirectoryIterator

这次咱们来介绍一个SPL库中的目录迭代器,它的作用其实非常简单,从名字就可以看进去,就是获取指定目录下的所有内容。之前咱们要遍历目录获取目录及目录下的所有文件个别是须要进行递归遍历的,本人写这个代码说实话还是挺麻烦的,所以PHP为咱们筹备好了这一套内置API,当输出指定的目录后,间接返回该目录下所有子目录及文件内容。当然,并不是树型的,程序并不一定,想要组织成树型还须要咱们本人再进行解决。 话不多说,间接看代码: $path = $argv[1];// 获取目录下所有内容$dirs = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);foreach($dirs as $k=>$d){ echo 'key:'. $k, PHP_EOL; if($d->isDir()){ echo $d->getPathname(), PHP_EOL; }else{ echo $d->getFilename(), PHP_EOL; }}//执行 php PHP获取目录中的全部内容RecursiveDirectoryIterator.php ../// key:../.// ../.// key:../..// ../..// key:../source// ../source// key:../source/.// ../source/.// key:../source/..// ../source/..// key:../source/PHP获取目录中的全部内容RecursiveDirectoryIterator.php// PHP获取目录中的全部内容RecursiveDirectoryIterator.php// key:../source/PHP大文件读取操作.php// PHP大文件读取操作.php// key:../PHP大文件读取操作.md// PHP大文件读取操作.md// key:../PHP获取目录中的全部内容RecursiveDirectoryIterator.md// PHP获取目录中的全部内容RecursiveDirectoryIterator.md其实就一行代码,而后间接循环输入这个迭代器。从后果中咱们能够看出,先进入 source 目录遍历实现后再遍历内部的文件内容,依照目录、文件名的程序顺次获取了目录下的所有内容。是不是比咱们本人写递归函数要不便很多。 如果咱们想获取目录下的所有PHP文件,并且计算他们的文件总大小呢?应用这一套迭代器操作也能够非常简单的实现,咱们只须要减少一个正则迭代器对后面的迭代器内容进行一下过滤就好了: // 获取所有php文件$regIts = new RegexIterator($dirs, '/^.+\.php$/i');$fileSize = 0;foreach($regIts as $k=>$p){ echo $p->getSize() . ' ' . $k, PHP_EOL; $fileSize += $p->getSize();}echo 'Total ', $fileSize, PHP_EOL;// 622 ../source/PHP获取目录中的全部内容RecursiveDirectoryIterator.php// 869 ../source/PHP大文件读取操作.php// Total 1491感觉就和 ls -l 一样,能够不便的让咱们可能进行目录下的相干操作。这个类的应用就简略的介绍到这里,对于SPL库中还有许多值得咱们摸索的能力,缓缓学习缓缓实际,一直晋升咱们面向优雅编程的能力。 ...

March 31, 2021 · 1 min · jiezi

关于github:这款相见恨晚的开源商城真的能商用

 大家好,我是为宽广程序员兄弟操碎了心的小编,每天举荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节俭开发效率,实现不加班不熬夜不掉头发,是我的指标! 明天小编举荐一款轻量级、高性能、前后端拆散的电商零碎,反对微信小程序 + H5+ 公众号 + APP,前后端源码100%开源,看见及所得,完满反对二次开发,让您疾速搭建个性化独立商城。 技术架构:PHP7.2 + ThinkPHP6.0 + Uni-APP + Ant Design Vue,专一轻量可继续稳固的高可用零碎,可学习可商用。 开源协定 应用 Apache-2.0 开源许可协定 容许集体学习钻研应用,反对二次开发,容许商业用途(仅限自经营)。容许商业用途,但仅限自经营,如果商用必须保留版权信息,望自觉遵守。不容许对程序代码以任何模式任何目标的再发行或发售,否则将查究侵权者法律责任。链接地址 公众号【Github导航站】回复关键词【萤火】获取git地址 技术特点前后端齐全拆散 (互不依赖 开发效率高)采纳PHP7.2 (强类型严格模式)Thinkphp6.0.5(轻量级PHP开发框架)Uni-APP(开发跨平台利用的前端框架)Ant Design Vue(企业级中后盾产品UI组件库)RBAC(基于角色的权限管制治理)部署运行的我的项目体积仅30多MB(真正的轻量化)环境要求CentOS 7.0+Nginx 1.10+PHP 7.1+MySQL 5.6+页面展现 结尾 本期就分享到这里,我是小编南风吹,专一分享好玩乏味、离奇、实用的开源我的项目及开发者工具、学习资源!心愿能与大家独特学习交换,欢送关注我的公众号【Github导航站】。

March 31, 2021 · 1 min · jiezi

关于php:『转载』Laravel-中大型项目架构

初学者学习 Laravel 时候两种,一种是乖乖的将程式填入 MVC 架构內,导致 controller 与 model 异样的瘦小,日后一样很难保护;一种是经常不晓得程式改写在哪一个 class 內而犹豫不決,毕竟传统 PHP 都是一个页面一个档案。本文整顿出适宜 Laravel 的中大型项目架构,兼具容易保护、容易裁减与容易重复使用的特点,并且容易测试。 一个我的项目只有 MVC 是不够的,咱们须要更残缺的我的项目架构。 ## Controller 过于臃肿受RoR的影响,初学者常认为 MVC 架构就是 model ,view,controller : Model 就是资料库。Controller 负责与 HTTP 交互,调用 model 与 view。View 就是 HTML。如果按照这个定义,以下这些需要改写在哪里呢? 发送 Email,应用内部 API。应用 PHP 写的逻辑。依需要将显示格局作转换。依需要是否显示某些材料。依需要显示不同材料。其中 1, 2 属于商业逻辑,而 3, 4, 5 属于显示逻辑,若按照个别人对 MVC 的定义,model 是资料库,而 view 又是 HTML,以上这些需要都不能写在 model 与 view,只能勉强写在 controller。 因而初学者开始将大量程式写在 controller,造成 controller 的瘦小难以保护。 Model 过于臃肿既然逻辑写在 controller 不不便保护,那我将逻辑都写在 model 就好了? 当你将逻辑从 controller 搬到 model 后,尽管 controller 变瘦了,但却肥了 model,model 从本来代表资料库,現在变成还要负责商业逻辑与显示逻辑,后果更慘。 ...

March 31, 2021 · 1 min · jiezi

关于golang:问个-Go-问题字符串-len-0-和-字符串-有啥区别

若有任何问题或倡议,欢送及时交换和碰撞。我的公众号是 【脑子进煎鱼了】,GitHub 地址:https://github.com/eddycjy。大家好,我是煎鱼。 前几天在微信群看到几位大佬在探讨一个问题: ”字符串 len == 0 和 字符串 == "" ,有啥区别?“ 这是一个比拟小的细节点,同时也勾起了我的好奇心,因而明天这篇文章就和大家一起钻研一下他们两者有没有区别,谁的性能更好一些? 测试方法在测试的办法中,咱们别离申明了 Test1 和 Test2 办法: func Test1() bool { var v string if v == "" { return true } return false}func Test2() bool { var v string if len(v) == 0 { return true } return false}在办法外部仅做了简略的变量类型申明,别离以 字符串 == "" 和 字符串 len == 0 为判断根据。 测试用例编写两个办法的 Benchmark,用于后续的性能测试: func BenchmarkTest1(b *testing.B) { for i := 0; i < b.N; i++ { Test1() }}func BenchmarkTest2(b *testing.B) { for i := 0; i < b.N; i++ { Test2() }}后果剖析$ go test --bench=. -benchmemgoos: darwingoarch: amd64BenchmarkTest1-4 1000000000 0.305 ns/op 0 B/op 0 allocs/opBenchmarkTest2-4 1000000000 0.305 ns/op 0 B/op 0 allocs/opPASSok _/Users/eddycjy/go-application/awesomeProject/tests 0.688s从屡次测试的后果来看,两者比拟: ...

March 31, 2021 · 2 min · jiezi

关于php:PHP如何使用SplQueueconstruct函数示例

SplQueue::__construct()函数是PHP中的内置函数, 用于构建应用双链表实现的队列。 语法如下: void SplQueue::__construct(void)参数:此函数不承受任何参数。 返回值:此函数不返回任何值。 上面的程序阐明了SplQueue::__ construct()PHP中的函数: 程序1: <?php // Create a new empty queue$q = new SplQueue(); $q [] = 1;$q [] = 2;$q [] = 3; // Print the queue elementsecho $q [0] . "n" ;echo $q [1] . "n" ;echo $q [2] . "n" ;?>输入如下: 123程式2: <?php // Create some fixed size array$gfg = new SplQueue(); $gfg [] = 1;$gfg [] = 5;$gfg [] = 1;$gfg [] = 11;$gfg [] = 15;$gfg [] = 17; foreach ( $gfg as $elem ) { echo $elem . "n" ;}?>输入如下: ...

March 30, 2021 · 1 min · jiezi

关于php:PHP如何使用arraydiffukey函数代码示例

array_diff_ukey()函数是PHP中的内置函数。它用于应用用户定义的函数比拟键的两个或多个数组, 并返回一个数组, 该数组为array1, 并且不存在其余任何array2, array3或更多… 语法如下: array_diff_ukey($array1, $array2, $array3..., arr_diffukeyFunction)应用参数:此函数承受起码三个参数, 而所有三个参数都是必须的, 另一个是可选的。参数阐明如下: $ array1(强制性):该数组将与其余数组进行比拟(例如, 从array1比拟该数组)。$ array2(强制性): 数组与第一个数组相比。$ array3(可选): 数组与第一个数组相比。arr_diffukeyFunction(强制性): 这是必须的用户定义性能。定义可调用比拟性能的字符串。如果第一个参数大于第二个参数, 则比拟函数返回一个大于0的整数。返回值:返回一个数组, 其中蕴含array1中其余数组中不存在的条目, 例如:-( arra2, arra3, arar4….more)。如果所有值都存在于其余数组中, 则该函数返回NULL。返回值类型是一个数组。 范例1: Input: $arr1 = array("one"=>"C Program", "two"=>"PHP Program", "three"=>"Java Program ");$arr2 = array("one"=>"Java Program", "two"=>"C++ Program", "six"=>"Java Program");Output: Array( [three] => Java Program )Explanation: First two values of arr1 are matched with arr2 and last value not matched so the function returns last value.范例2: ...

March 30, 2021 · 3 min · jiezi

关于php:laravel命名空间自动加载

一、引子laravel这个优雅的框架很值得学习,特地是其中一些优良的设计,平时总会对其中某些性能的实现很好奇,这篇文章好奇的是如下: 二、概念laravel的根本主动加载性能蕴含了 命名空间、注册主动加载、蕴含文件。 1、命令空间 命令空间是php引入的一种个性,相似文件目录门路,将代码划分成不同空间,类名相互独立互不抵触,用于解决文件引入抵触;命令空间namespace须要申明在文件最后面;命令空间use个别是用来引入类,无奈引入函数,因为主动加载spl_autoload_register是在类未找到时触发,调用函数不触发;两个有命令空间的文件相互引入彼此的类,两头的桥梁是通过"注册主动加载、蕴含文件"。2、注册主动加载 new对象时,如果找不到类则主动调用全局函数__autoload()(高版本弃用),spl_autoload_register反对多种注册形式、批量注册3、蕴含文件 require、include、require_once、include_once,网上内容很多请自行搜寻。 三、逻辑导图 四、代码模仿a.php、b.php、c.php三个文件都在同一目录下,别离命令空间a、命名空间b、桥梁c。 c.php <?php//__autoload() is Deprecated,采纳spl_autoload_register注册主动加载spl_autoload_register(function($classname){ //$classname会主动加上以后的命名空间,laravel是将命令空间做为目录门路来加载类文件 include_once(explode('\\',$classname)[0].".php" ); });a.php <?phpnamespace a;include_once "c.php";class a{ function testA(){ echo "A"; }}/**********************************************************///这里引入buse b\b;$t = new b();echo $t->testB();b.php <?phpnamespace b; include_once "c.php";class b{ function testB(){ echo "B"; } }/**********************************************************///这里引入buse a\a;$t = new a();echo $t->testA();

March 30, 2021 · 1 min · jiezi

关于php:官方PHP-Git服务器受到威胁项目代码库可能被植入恶意软件

PHP官网的Git服务器曾经被入侵,入侵者可能的目标是在PHP我的项目的代码库中植入恶意软件。 周日,PHP编程语言的开发者和维护者Nikita Popov示意,在php-src仓库中呈现了两个以他和PHP创建者Rasmus Lerdorf的名字命名的歹意提交。 这些歹意提交,看起来是以Popov和Lerdorf的名字签订的,实际上是用简略排版谬误进行覆盖。 当贡献者仔细观察 "修复排版谬误 "的提交时,会发现如果一个字符串的结尾是与Zerodium相干的内容,那么恶意代码就会在useragent HTTP头中触发任意代码。 该代码仿佛旨在植入后门并创立一个可能进行近程代码执行(RCE)的计划。 Popov示意开发团队不确定确切的攻击方式,然而有迹象表明官网的git.php.net服务器可能受到了攻打,而不是仅限于单个Git帐户受到了攻打。 平安专家还发现,脚本中蕴含这条正文:REMOVETHIS: sold to zerodium, mid 2017(REMOVETHIS:2017年中发售给zerodium)。但没有迹象表明,该破绽卖家与此次网络攻击有任何关系。 Zerodium的首席执行官Chaouki Bekrar称真正的罪魁祸为“巨魔”,并公开示意:发现此破绽的钻研人员可能试图将其发售给许多实体,但没人违心购买...... 在将代码提交到上游,影响用户之前,官网已检测到它,并还原了提交。 目前正在对安全事件进行考察,并且团队正在搜查存储库中是否存在任何其余歹意流动迹象。然而与此同时,开发团队已决定当初是我的项目永恒迁徙到GitHub的适合工夫。 Popov说:咱们认为保护本人的git根底构造是不必要的平安危险,并且咱们将进行git.php.net服务器。以前仅是镜像的GitHub上的存储库将变得标准,这意味着更改应间接推送到GitHub而不是git.php.net。” 值得注意的是以前具备对该我的项目存储库写访问权的开发人员当初将须要退出GitHub上的PHP组。 此次安全事件能够形容为供应链攻打,其中威逼行动者针对开源我的项目,库或大用户群所依赖的其余组件。进行外围指标的毁坏,其恶意代码可能会下潜到宽泛的零碎中。 例如最近的一个例子中SolarWinds的惨败,该供应商的平安受到重大毁坏,被植入了Orion软件的歹意更新。在部署了该恶意软件后,包含Microsoft,FireEye和Mimecast在内的数以万计的组织都受到了威逼。 链接:https://github.com/php/php-src/commit/c730aa26bd52829a49f2ad284b181b7e82a68d7d

March 30, 2021 · 1 min · jiezi

关于php:BBBUG音乐聊天室的开发故事和架构设计

办公室有个小伙伴喜爱拿音响放歌,然而总放一些动次打次的广场舞DJ曲目,共事听了都头大,每次让人家切歌又不不便 于是某共事吐槽:“咱们点啥你放啥?”一天之后……“张三你刚说放啥来着?”“卧槽,我说的是刘德华的17岁,你这放的是谁的版本?” “17岁QQ音乐要会员,放不了。”…… 我切实看不下去了,要不写一个点歌平台? 说干就干,第一版俩小时搞定: 一个点歌端,爬虫爬各大平台,包含一些VIP歌曲也给爬下来,只能搜寻,点歌。一个导播端,能够看大伙点了什么歌,导播端能够插队播放,删除。 好,上线。 两天后……老板:“卧槽你们当办公室KTV呢?开音响听歌???”好吧,所有人默默带上了耳机,但点歌端不能播放音乐,只能点歌,这一版宣告凉凉。 …… 那就降级吧:这一版,不辨别点歌端和导播端,所有端都一样,做一个共享队列,大伙点,大伙本人带耳机听。 一天后……“你能不能让大家听到的歌进度保持一致?我还在听上一首,他们先进去的都曾经主动播下一首了……”OK,持续降级,加歌曲同步。 好家伙这一次,跟KTV没啥区别了。 这一版有点意思,还加上了“送啤酒”这个小互动,是不是更像KTV了? 好吧我抵赖,这种小互动貌似没什么用,于是起初的版本掐掉了。然而好景不长:“大厅这群人有毒吧?跟五条人杠上了?”“我切实是不敢恭维在座各位的歌单” “这都点的什么玩意歌啊……” “Mojito我切实是听得要吐了……” 好吧,那就安顿,本人开房间听歌。 于是有了多房间的版本,每个人都能够创立本人的房间,听本人的歌。 顺便加上一个二级域名和独立域名的绑定性能,于是有了上面的设计图: 这就很棒了,大伙都能够在大厅一起听,也能够去本人房间里点歌听。 好好好景不长,需要又来了~“本人的房间,能不能不点歌,自动播放本人点过的歌?”安安安顿!那就来一个电台模式吧,设置了就自动播放本人的歌,有人点歌的话让他排队吧。 这下能够了吧? 安安稳稳听歌一周后……“好无聊啊,光听歌,能让我听听相声小品吗?”安安安安安顿! 爬谁呢,就蜻蜓FM吧。 上线了小说故事模式…… 好好好好好景还是不长“这个UI好丑啊,能换换吗?”我也这么感觉,那就改吧,于是改成了这样 “红色是不是太晃了,出个暗黑模式呗?”“我TM……” 安安安安安安安顿! 感觉还挺棒, 本认为故事到这里就根本完结了,然而,嗯。 “网页好烦人啊,能出个Windows客户端吗?”安安安安安P,等下,C#我快忘洁净了。 花俩小时回顾了下C#,又花俩小时学习了下 WTF…… 安安安安安安安顿!于是有了这个Windows客户端 好家伙,写完了,公布了,理论统计了下应用数据,应用人数不超过3,WTF???? “你这大部分是程序员在用,要不出个vscode的插件呗。”我…… 故事快完结了吗? 天真。“出个APP吧!”我…… 好,安顿,就拿Uniapp整一套吧。 体验还挺不错,不过因为音乐版权问题,这里就没上架AppStore。 “App下载好麻烦,整一套小程序吧?”安安安安安安安安安安安安顿!整! 故事到这里就根本完结了,心累。 一口气把所有端的代码都开源了,欢送有趣味的小伙子给点点小星星呀。 Github https://github.com/HammCn Gitee https://gitee.com/bbbug_com 顺便附上整体的架构设计图 体验一下 www.bbbug.com

March 30, 2021 · 1 min · jiezi

关于php:PHP的HTTP验证

在日常开发中,咱们进行用户登录的时候,大部分状况下都会应用 session 来保留用户登录信息,并以此为根据判断用户是否已登录。但其实 HTTP 也提供了这种登录验证机制,咱们明天就来学习对于 HTTP 验证相干的常识。 HTTP Basicif (!isset($_SERVER['PHP_AUTH_USER'])) { header('WWW-Authenticate: Basic realm="My Realm"'); header('HTTP/1.0 401 Unauthorized'); echo 'Text to send if user hits Cancel button'; exit;} else { echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>"; echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";}// Authorization: Basic YWFhOmFhYQ==echo base64_decode('YWFhOmFhYQ==');// aaa:aaa 等于明文还是间接就从代码动手,下面的代码就是最简略的一种 HTTP 认证形式,如果 $_SERVER['PHP_AUTH_USER'] 不存在,那么咱们就向浏览器发送一个 401 响应头,就是通知浏览器咱们须要登录验证。当浏览器收到这个响应头时,就会弹出一个浏览器自带的验证框并要求输出用户名和明码。 当咱们填写了用户名和明码后,浏览器会在申请头中带上 Authorization 字段,并且将 base64 之后的用户名和密码发送过去。同时,PHP将会别离把用户名和明码解析到 \$_SERVER['PHP_AUTH_USER'] 和 $_SERVER['PHP_AUTH_PW'] 中。 上述这种认证形式就是最简略的 HTTP Basic 认证,能够看出,这种形式进行验证的用户名和明码其实是相当于明文传输的,因为 base64 很容易就能够反向解析进去。所以这种形式是十分不平安的。那么有没有更简单一些的形式呢? HTTP Digest既然这么写了,那必定是有更好的形式啦,那就是 HTTP Digest 形式的 HTTP 认证。 ...

March 30, 2021 · 2 min · jiezi

关于php:PHP如何使用mysqlirealescapestring函数用法示例

mysqli_real_escape_string()函数是PHP中的内置函数, 用于本义所有特殊字符以用于SQL查问。在将字符串插入数据库之前应用它, 因为它删除了可能烦扰查问操作的任何特殊字符。 当应用简略的字符串时, 它们中可能蕴含特殊字符, 例如反斜杠和撇号(尤其是当它们间接从输出了此类数据的表单中获取数据时)。这些被认为是查问字符串的一部分, 并且会烦扰其失常运行。 <?php $connection = mysqli_connect( "localhost" , "root" , "" , "Persons" ); // Check connection if (mysqli_connect_errno()) { echo "Database connection failed." ; } $firstname = "Robert'O" ;$lastname = "O'Connell" ; $sql ="INSERT INTO Persons (FirstName, LastName) VALUES ( '$firstname' , '$lastname' )"; if (mysqli_query( $connection , $sql )) { // Print the number of rows inserted in // the table, if insertion is successful printf( "%d row inserted.n" , $mysqli ->affected_rows);}else { // Query fails because the apostrophe in // the string interferes with the query printf( "An error occurred!" );} ?>在下面的代码中, 查问失败, 因为应用mysqli_query()执行撇号时, 会将撇号视为查问的一部分。解决方案是在查问中应用字符串之前应用mysqli_real_escape_string()。 ...

March 29, 2021 · 1 min · jiezi

关于php:PHP如何上传文件详细实现代码

你是否想过网站如何应用PHP构建其文件上传零碎?在这里, 咱们将理解文件上传过程。你可能会想到一个问题-"咱们是否能够通过该零碎上传任何类型的文件?"。答案是能够的, 咱们能够上传具备不同扩展名的文件。 让咱们制作一个HTML表单, 用于将文件上传到服务器。 index.html <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>File Upload Form</title></head><body> <form action="file-upload-manager.php" method="post" enctype="multipart/form-data"> <!--multipart/form-data ensures that form data is going to be encoded as MIME data--> <h2>Upload File</h2> <label for="fileSelect">Filename:</label> <input type="file" name="photo" id="fileSelect"> <input type="submit" name="submit" value="Upload"> <!-- name of the input fields are going to be used in our php script--> <p><strong>Note:</strong>Only .jpg, .jpeg, .png formats allowed to a max size of 2MB.</p> </form></body></html>当初, 该写一个可能解决文件上传零碎的php脚本了。 file-upload-manager.php <?php// Check if the form was submittedif ( $_SERVER [ "REQUEST_METHOD" ] == "POST" ){ // Check if file was uploaded without errors if (isset( $_FILES [ "photo" ]) && $_FILES [ "photo" ][ "error" ] == 0) { $allowed_ext = array ( "jpg" => "image/jpg" , "jpeg" => "image/jpeg" , "gif" => "image/gif" , "png" => "image/png" ); $file_name = $_FILES [ "photo" ][ "name" ]; $file_type = $_FILES [ "photo" ][ "type" ]; $file_size = $_FILES [ "photo" ][ "size" ]; // Verify file extension $ext = pathinfo ( $filename , PATHINFO_EXTENSION); if (! array_key_exists ( $ext , $allowed_ext )) die ( "Error: Please select a valid file format." ); // Verify file size - 2MB max $maxsize = 2 * 1024 * 1024; if ( $file_size > $maxsize ) die ( "Error: File size is larger than the allowed limit." ); // Verify MYME type of the file if (in_array( $file_type , $allowed_ext )) { // Check whether file exists before uploading it if ( file_exists ( "upload/" . $_FILES [ "photo" ][ "name" ])) echo $_FILES [ "photo" ][ "name" ]. " is already exists." ; else { move_uploaded_file( $_FILES [ "photo" ][ "tmp_name" ], "uploads/" . $_FILES [ "photo" ][ "name" ]); echo "Your file was uploaded successfully." ; } } else { echo "Error: Please try again." ; } } else { echo "Error: " . $_FILES [ "photo" ][ "error" ]; }}?>在下面的脚本中, 一旦咱们提交了表单, 当前咱们就能够通过PHP超全局关联数组$ _FILES访问信息。除了应用$ _FILES数组的模式外, 许多内置函数也起着次要作用。上传完文件后, 在脚本中咱们将查看服务器的申请办法, 如果它是POST, 则它将持续进行, 否则零碎将引发谬误。稍后, 咱们拜访了$ _FILES数组以获取文件名, 文件大小和文件类型。一旦取得了这些信息, 就能够验证文件的大小和类型。最初, 咱们在要上传文件的文件夹中搜寻, 以查看文件是否曾经存在。如果没有, 咱们曾经应用move_uploaded_file()将文件从长期地位挪动到服务器上的所需目录, 咱们就实现了。 ...

March 29, 2021 · 2 min · jiezi

关于php:PHP如何使用datecreatedateformatdateadd函数示例

在某个工夫点上, 咱们须要在日期和工夫中增加一些天, 月, 年, 小时, 分钟和秒。 PHP为咱们提供了几个内置函数来实现此目标。咱们将在此处探讨的一些内置函数是date_create(), date_format()和date_add()。 date_create()函数此函数用于通过应用日期/工夫字符串和时区来创立DateTime对象。日期/工夫字符串的默认值为以后日期/工夫。 语法如下: DateTime date_create(time, timezone);参数:此函数承受两个参数: 工夫 :(可选)指定日期/工夫字符串。 NULL或默认值批示以后日期/工夫。你能够参考这个连结在PHP中反对的日期和工夫格局。时区 :(可选)工夫的时区。返回值:此函数返回一个新的DateTime对象, 该对象指定一个日期。 date_format()函数date_format()函数格式化给定日期。该日期作为DateTime实例提供, 通常由date_create()函数返回, 并且format是一个字符串, 咱们要依据该字符串格式化日期。 语法如下: string date_format(object, format);参数:该函数承受两个参数, 所有这些参数都是必须提供的。 对象:指定date_create()返回的DateTime对象格局:指定日期格局。它承受PHP中date()函数反对的格局。示例– H(24小时格局), h(12小时格局), i(分钟:00到59), s(秒:00到59)等。返回值:date_format()函数返回一个字符串, 该字符串示意胜利格式化后依据指定格局格式化的日期, 否则返回false。 <?php // using date_create() function to create// DateTime object$date =date_create( "2018-03-15" ); // using date_format() function to format dateecho date_format( $date , "Y/m/d H:i:s" ); ?>输入如下: 2018/03/15 00:00:00date_add()函数date_add()函数用于将日期, 月份, 年份, 小时, 分钟和秒增加到日期。 Date作为DateTime对象提供给date_add()函数, 而咱们要增加到Date中的距离作为DateInterval对象提供。 语法如下: ...

March 29, 2021 · 1 min · jiezi

关于php:PHP大文件读取操作

简略的文件读取,个别咱们会应用 file_get_contents() 这类形式来间接获取文件的内容。不过这种函数有个重大的问题是它会把文件一次性地加载到内存中,也就是说,它会受到内存的限度。因而,加载大文件的时候是相对不能应用这种形式的。咱们还是先看看这种形式加载的例子。 // 一般的文件读取 一个2.4G的SQL导出文件$fileName= './2020-02-23.sql';// file_get_contents$fileInfo = file_get_contents($fileName);// Fatal error: Allowed memory size of 134217728 bytes exhausted// file$fileInfo = file($fileName);// Fatal error: Allowed memory size of 134217728 bytes exhausted// fopen + fread$fileHandle = fopen($fileName, 'r');$fileInfo = fread($fileHandle, filesize($fileName));// Fatal error: Allowed memory size of 134217728 bytes exhausted上述三种模式的文件加载读取形式都是不能加载这么大的文件的,当然,你也能够批改 php.ini 中的相干配置让他们可能加载胜利,但咱们并不举荐这样应用,毕竟内存资源相比硬盘资源还是要贵重的多。 以下的形式是能够间接读取这种大文件的: // readfile 只能间接输入echo readfile($fileName);// fopen + fgetc 如果单$fileHandle = fopen($fileName, 'r');// 输入单字符直到 end-of-filewhile(!feof($fileHandle)) { echo fgetc($fileHandle);}fclose($fileHandle);// SplFileObject$fileObject = new SplFileObject($fileName, 'r');while(!$fileObject->eof()){ echo $fileObject->fgetc();}第一个 readfile() ,读取文件后就间接打印了,不能进行其余操作,实用于间接显示大文件内容时应用。 ...

March 29, 2021 · 1 min · jiezi

关于后端:PHP-的迭代器Iterator

前沿上回咱们探讨了PHP的生成器,明天咱们来看看PHP的迭代器。 区别生成器和迭代器有什么区别呢? 一句话:生成器只是简略的迭代器。 与规范的PHP迭代器不同,PHP生成器不要求类实现Iterator接口,从而加重了类的累赘。生成器会依据需要计算并产出要迭代的值。这对利用的性能有重大影响。试想一下,如果规范的PHP迭代器常常在内存中执行迭代操作,这要事后计算出数据集,性能低下;如果要应用特定的形式计算大量数据,对性能的影响更甚。此时咱们能够应用生成器,即便计算并产出后续值,不占用贵重的内存资源。 作用迭代器有什么作用呢? 让对象变得可迭代并体现得像对象汇合。 咱们来看一道腾讯面试题 使对象能够像数组一样进行foreach循环,要求属性必须是公有。这题其实就是考查到了迭代器了 咱们先看看迭代器的接口 Iterator extends Traversable {/* 办法 */ abstract public current ( ) : mixed abstract public key ( ) : scalar abstract public next ( ) : void abstract public rewind ( ) : void abstract public valid ( ) : bool}外面定义了5个形象办法 来看看最初的答案 class sample implements Iterator{ private $_items = array(1,2,3,4,5,6,7); public function __construct() { } //重置到到第一个元素 public function rewind() { reset($this->_items); } //返回以后元素 public function current() { return current($this->_items); } //返回以后元素到键 public function key() { return key($this->_items); } //返回下一个元素 public function next() { return next($this->_items); } //查看以后元素是否无效 public function valid() { return ( $this->current() !== false ); }}$sa = new sample();foreach($sa as $key => $val){ print $key . "=>" . $val;}//输入0=>1 1=>2 2=>3 3=>4 4=>5 5=>6 6=>7咱们通过foreach 遍历对象的时候,外部会顺次调用 ...

March 29, 2021 · 1 min · jiezi

关于php:PHP如何使用DsVector-copy函数代码示例

DsVector::copy()函数是PHP中的内置函数, 用于创立给定向量的正本。 语法如下: DsVector public DsVector::copy( void )参数:此函数不承受任何参数。返回值:此函数返回向量的浅表正本。上面的程序阐明了DsVector::copy()PHP中的函数的用法: 程序1: <?php // Create a vector array$arr1 = new DsVector([1, 2, 3, 5]); // Use copy() function to copy// the vector array$arr2 = $arr1 -> copy (); echo ( "Original Array n" ); // Display the original arrayprint_r( $arr1 ); echo ( "Copied Array n" ); // Display the copied arrayprint_r( $arr2 ); ?>输入如下: Original Array DsVector Object( [0] => 1 [1] => 2 [2] => 3 [3] => 5)Copied Array DsVector Object( [0] => 1 [1] => 2 [2] => 3 [3] => 5)程序2: ...

March 27, 2021 · 1 min · jiezi

关于php:PHP操作用户提交内容时需要注意的危险函数

对于咱们的程序开发来说,用户的输出是解决安全性问题的第一大入口。为什么这么说呢?不论是SQL注入、XSS还是文件上传破绽,全副都和用户提交的输出参数无关。明天咱们不讲这些问题,咱们次要探讨上面对用户的输出,有一些危险的函数在未经验证的状况下是不能间接应用这些函数来进行操作的,比方: include($g);假如这个 $g 是用户提交的内容,咱们在未经验证的状况下间接应用这个参数来蕴含文件,咱们传递的参数为 ?g=/etc/passwd ,那么服务器上所有的用户帐号信息就很可能就间接泄露了。 另外,一些执行 shell 命令的函数还是极度危险的。 echo system($g);当咱们传递的参数是 ?g=ls -la / 时,同样的服务器目录也展现了进去,这还仅仅是显示目录构造,如果应用其它更恐怖的命令结果将不堪设想。 同理,咱们常常会依据一些id或指定的文件名来操作文件,特地是在删除文件的时候,如果未加判断,那么也可能间接去删除某些十分重要的文件。 unlink('./' . $g);咱们持续将 $g 结构为 ?g=../../../xxxx ,如果在权限容许的状况下,就能够删除各种系统文件。 对这些内容,其实在 PHP 的官网手册中就曾经给出了一些很好的倡议,咱们无妨来间接看看 PHP 手册中是如何说的。 很多 PHP 程序所存在的重大弱点并不是 PHP 语言自身的问题,而是编程者的安全意识不高而导致的。因而,必须时时留神每一段代码可能存在的问题,去发现非正确数据提交时可能造成的影响。 必须时常注意你的代码,以确保每一个从客户端提交的变量都通过适当的查看,而后问本人以下一些问题: 此脚本是否只能影响所预期的文件?非正常的数据被提交后是否产生作用?此脚本能用于计划外的用处吗?此脚本是否和其它脚本联合起来做好事?是否所有的事务都被充沛记录了?还能够思考敞开 register_globals,magic_quotes 或者其它使编程更不便但会使某个变量的合法性,起源和其值被搞乱的设置。在开发时,能够应用 error_reporting(E_ALL) 模式帮忙查看变量应用前是否有被查看或被初始化,这样就能够避免某些非正常的数据的挠乱了。 其实,只有能恪守这些倡议,大部分的平安问题都能失去解决。还是那句话,不能置信用户的任何输入,在测试的时候请做好各种验证,包含但不限于边界值、特殊符号、非凡命令、越界值、目录权限等。在非必要的状况下不要应用用户的输出作为蕴含文件、执行脚本及文件操作的间接参数,如果肯定要用的话千万要进行各种模式的过滤验证。 测试代码:[https://github.com/zhangyue05... 参考文档: https://www.php.net/manual/zh/security.variables.php各自媒体平台均可搜寻【硬核项目经理】

March 27, 2021 · 1 min · jiezi

关于后端:PHP如何使用strval函数用法和代码示例

strval()函数是PHP中的内置函数, 用于将任何标量值(字符串, 整数或双精度)转换为字符串。咱们不能在数组或对象上应用strval(), 如果利用了该函数, 则此函数仅返回要转换的值的类型名称。 语法: strval( $variable )参数:此函数承受单个参数$变量。此参数示意咱们要转换为字符串的值 返回值:此函数返回一个字符串。该字符串是通过类型转换作为参数传递给它的变量的值生成的。 上面的程序阐明了strval()函数。 程序1: <?php $var_name = 32.360; // prints the value of above variable // as a stringecho strval ( $var_name ); ?>输入如下: 32.36程序2: <?php class lsbin{ public function __toString() { // returns the class name return __CLASS__ ; }} // prints the name of above class as// a stringecho strval ( new lsbin); ?>输入如下: lsbin程序3: <?php// Program to illustrate the strval() function// when an array is passed as parameter // Input array$arr = array (1, 2, 3, 4, 5); // This will print only the type of value// being converted i.e. 'Array'echo strval ( $arr ); ?>参考:http://php.net/manual/en/func... ...

March 26, 2021 · 1 min · jiezi

关于php:Tp5源码分析第四步容器类和门面类

一、container容器类分析Countable巧用Container容器类文件是在thinkphp\library\think目录下的,我认为它是框架的一个精华,它可能很不便的治理框架的类,不便咱们应用。在Container中,它用到了很多类,还有反射机制,所以反射机制是须要咱们去理解的一个货色。其中Countable是php内置的一个类,接下来咱们进行对它的演示。首先在extend目录下创立一个TestCountable类,而后它继承Countable,因为是继承的Countable,须要把其中的count办法定义进去,不然会报错,而后在count外面轻易返回内容。接着在控制器index.php中创立办法去调用这个类,然而它的调用和其余的有点区别,惯例调用是这样的,$obj=new TestCountable(); $a = $obj->count(); 而Countable是这样的$obj = new TestCountable(); $a = count($obj);。这就是它的区别。 获取容器内的实例剖析$this->instance 获取容器对象实例$this->bind 容器绑定标识$this->name 容器标识别名[APP] => think\App[log] => think\Log相似于容器绑定标识的内容$this->instances容器中的对象的实例[think\App] => think\App Object[think\Config] => think\Config Object等等。 那么咱们如何去学习容器呢,咱们还是联合框架代码来进行剖析。首先咱们定位到入口文件index.php这里它用了Container的get办法,并传入了一个app参数,咱们来看一下get办法的逻辑。get办法是获取容器中的对象实例。这里它传入了三个参数,三个参数各是什么意思,正文下面有,传入的app对应的就是think\App,而后它用了单例模式,getInstance就是一个单例,而后调用make办法。首先会对$vars进行判断,如果是true,就把它置空,让$newInstace为true。接下来进行判断$this->name[$abstract],因为传入参数是app,$abstract => app。而后判断$abstract有没有实例,默认是没有的,就返回一个实例。而后接着就是容器绑定标识,$concrete对应的就是think\App。接着如果它是闭包的话,就会走到invokeFunction,如果不是,就设置容器标识别名,相当于$this->name["app"] = think\App 。而后再去调用make办法,这个时候,传的参数就不一样了,第一个参数就成为think\App,这个时候两个isset都是没有的,就不会走这两个逻辑。间接跳到invokeClass办法,这个时候会返回一个对象。而后把这个对象放入容器中的对象实例,最初返回这个对象。invokeClass办法当初咱们讲一下invokeClass办法,这个办法传入了两个参数,第一是类名,第二是它的参数。而后实例化反射类ReflectionClass,而后判断这个类外面是否有__make办法,如果有的话就获取到这个类,接着判断这个类的属性是不是public或者static,如果是的,就进行实例化,而后返回。而__make办法在Config类里是存在的,所以这里实例化的是一个Config类。 容器类的应用场景容器类能够这样应用,这种是应用的Facade门面的办法来应用的。第二种能够这样应用,相似入口文件那样。这两种都能打印出app的config配置。咱们还有另外一种应用场景的,这种场景咱们应用到了php的助手函数,在helper.php中的app办法中。咱们能够这样用,间接app("config);,这样能够间接拿到配置。 二、Facade门面模式门面为容器中的类提供了一个动态调用接口,相比于传统的静态方法调用,带来了更好的可测试性和扩展性。接下来还是通过代码来理解。在thinkphp\library\think目录下有一个Facade文件,它相当于门面的一个父类,子类在think\facade目录下,外面有许多的类,它们都须要继承Facade父类。这些子类中都只有一个办法,getFacadeClass办法,外面逻辑就是返回绑定的标识。它的作用是在Facade外面体现的。这里获取到这个标识,而后判断有没有这个标识,如果有就返回这个实例,如果没有,就绑定到标识中去。 咱们接下来通过演示来剖析一下Facade代码。咱们在index控制器外面创立一个facade办法,而后打印Config::get("app");,它是怎么走的呢,它会找到think\facade\Config.php这个文件,然而在这个文件外面是没有get办法的,而且在它的父类Facade外面也没有get办法,那么它是怎么执行的呢。因为Facade外面没有get办法,那么它会走到__callStatic办法,而后去创立一个get办法。接下来咱们来具体解说一下__callStatic办法。咱们创立一个Test类,在Test类外面增加__callStatic办法,而后打印一下传入的参数,在应用层index.php去调用一下这个类,代码如下:咱们调用的abcd办法在Test外面是不存在的,咱们看一下打印的参数是什么。咱们持续看Facade类的__callStatic办法,在这里会执行createFacade办法,这个办法咱们在下面解释过了,所以最终会把get放入$this->[name]标识外面去。最终返回的是一个实例。 联合下面的形容,facade办法就是依据容器外面是否有静态方法get,如果有调用,如果没有就进行实例化,进行调用。 Facade图例 Facade实战Facade有两个应用场景,第一个:咱们在app目录下创立common和facade文件夹,而后别离在两个目录下创立Test文件,common下的Test外面创立test办法,并输入内容。facade目录下须要继承Facade门面类,而后调用getFacadeClass办法,而后返回common下Test的门路,而后在应用层去调用appfacadeTest::test();第二种:facade目录下的Test文件不再写办法,而后在控制器外面这样应用。Facade::bind('app\facade\Test','app\common\Test'); app\facade\Test::test();

March 26, 2021 · 1 min · jiezi

关于php:酷瓜云课堂v130发布开源在线教育解决方案

v1.3.0(2021-03-26)更新内容课程减少面授模型重构前台群组成员治理后盾减少群组成员治理重构订单存储商品详情数据结构调整用户和群组列表等UI我的项目介绍酷瓜云课堂,依靠腾讯云根底服务架构,采纳C扩大框架Phalcon开发,GPL-2.0开源协定,100%开源在线教育解决方案。 零碎性能实现了点播、直播、专栏、面授、会员、群组、积分商城、秒杀等,全功能无阉割,开箱可用。 托管仓库gitee仓库github仓库意见反馈在线反馈(举荐)官方论坛(举荐)开源助力毫无保留的真开源不容易,如果对你有帮忙,请给咱们 STAR !!!

March 26, 2021 · 1 min · jiezi

关于php:HeartbeatOne-一个由PHP实现的MySql主服务器复制MasterSlave延迟时间检查器工具

HeartbeatOne一个由PHP实现的MySql主服务器复制(Master/Slave)延迟时间查看器工具,原理同pt-heartbeat相似。 工具截图(命令行执行运行示例) (日志文件内容示例) 装置&应用装置下载本工具脚本源码,部署至您的具备PHP运行环境并可连贯通被监控MySQL的服务器。 设置依据您的理论状况批改配置文件 <?php/** * Default setting sample * */return [ 'mysqlMasterHost' => '', // Write server host 'mysqlMasterUser' => '', 'mysqlMasterPwd' => '', 'mysqlSlaveHosts' => [], // Slaves host of the master 'mysqlSlaveUser' => '', // Read server username 'mysqlSlavePwd' => '', 'interval' => 1, // Frequency for update monitor time in seconds 'averages' => [1, 5, 30], // Latest period slave lagging average time in seconds, can be more than three and even more, su as [1, 5, 30, 60 ...] 'logFilePath' => '/val/logs/', 'logFileName' => 'HeartbeatOne-Monitor', 'mysqlDriver' => 'mysqli', // Only support `mysqlli` or `PDO` driver];初始化监控数据库导入 heartbeat.sql 文件至您的 MySQL 主(Master)服务器,实现初始化。 ...

March 26, 2021 · 1 min · jiezi

关于管理后台:☘-gMIS吉密斯升级多IPRoaming漫游改进和Cache缓存优化

“实现大事业的惟一办法,但从基本上一步一步、一点一点地做起,这是行为学所器重的一个事实。”—-米塞斯 Mises《人的行为 Human Action》,https://ufqi.com/news/ulongpa...  gMIS吉密斯 作为治理后盾系统软件,始终默默工作在后端,鲜有出头露面的机会。其实gMIS也在一直的优化改良,间隔上次:☘ gMIS吉密斯降级:点选Pickup2.0和平安及权限零碎等,曾经差不多快一年没更新gMIS Blog,趁着最近一次版本的更新,记录如下,以资参考备查。 1. 单用户多IP-Roaming漫游平安鉴权改良 网络的飞速发展使得,单网络同时用户领有和应用多个IP成为可能,比方咱们在去年就针对同一个用户同时具备IPv4和IPv6两个地址的状况进行了优化改良:gMIS吉米斯降级反对IPv4/IPv6双栈网络模式。此外,挪动设施的改良和挪动带宽的晋升,使得挪动办公——就是在前进中——成为可能,而同一个用户可能在一个很短的工夫内从地点A挪动到地点B,在通信层就是用户漫游过多个基站,所以其IP也会变化多端。 也就是说位移动态单用户可能有多个IP,而位移进行中的用户更有可能是多个IP,再而三的多IP多通道并发通信也日渐成熟——一次下层的HTTP申请,可能其中的Packets别离由不同的IP“同时”传送而来的。这在应用层或感知不到,但也要在将来思考到这种状况。 回到这个单用户多IP漫游的状况,如果持续应用此前的策略,将用户从零碎登录状态弹出而后请用户再登录一次,从而造成新IP下的鉴权,显然是不适合的。有没有更好的方法来实现既能保障平安,也同时升高因为多IP变动引起的频繁登录?梳理一下面临的新状况:1)  一个用户单地点可能同时有多个IP,如 IPv4、IPv62)  一个用户挪动中可能拜访多个基站,会经验多个IP,这些基站IP可能同时也有IPv4和IPv6.综上,一个已登录的用户,在单一个回话期间,其IP变更将是大概率事件。 然而作为网络安全防备的次要利器之一IP在用户鉴权方面短期内看,又是不可或缺的。或者将SID视为Token来解决将是一个新思路。每一次胜利鉴权之后,将已受权的SID赋予Token的含意,在后续行为中如果持有一个非法的TOken则视为非法的拜访,作为鉴权IP失败后的补救措施。 借助于服务器端的缓存机制,咱们设计到一种新办法,基于此能够实现在单用户多IP或者多IP漫游的状况下,使得用户能免于从新登录。该办法的思路是:1) 维持现有登录机制不变,2) 当用户登录胜利后,在服务器端缓存用户下次鉴权的SID值,3) 当下次用户进行拜访时,如果IP没有产生扭转,则应用此前的鉴权获得成功,持续,4) 此时,如果用户切换(IPv4/IPv6) 或者漫游到新IP时,读取在服务端的缓存SID,如果是非法无效的,则视为已鉴权的用户,持续,5) 如果应用IP未鉴权胜利,也未检测到SID为非法的,则视为非法,拒绝请求并跳转到登录页面。 这个策略能够视为对去年IPv4/IPv6双栈网络模式的扩大和降级,无论后续单用户再切换多少IP,如果其持有一个经非法鉴权的SID,则能够在该SID有效期内(数分钟、数小时或者至少一天)继续应用零碎服务。 如此以来,则能够持续欢快地的游玩了。这一降级改良次要波及到内容有:1) class/user.class 中减少 setSidToken / getSidToken 两个办法,2) 改良 extra/signupin: 登录胜利后,调用 $user->setSidToken ,将已受权SID 缓存起来,3) 改良 user->getUserBySession: 在拜访鉴权的时候,减少对现有SID的读取,通过 $user->getSidTOken读取. 等等,这里如同又埋下了隐患,原本一把钥匙(SID)开一个门(IP),当初是一把钥匙能开很多门了,这是万能钥匙吗?如果中间人攻打,取得一个已受权的SID,在别处也能够自在的应用,这显然与最早的SID平安机制设计有抵触的中央。有鉴于此,咱们将这个繁多SID容许多IP的性能设置为可选项,仅在对安全性要求不高的场景下应用,或者在绝对隔离的。 4) 批改 inc/config: 减少 Single_Sid_Allow_Multiple_IP 的开关,如果是 true 则启用上述性能,如果 false 则不容许。 默认是 false.$conf[‘single_sid_multiple_ip’] = true; # lower security higher convenience if true, vice versa. 13:12 2021-03-23 从实质上说,平安与便当有很多时候须要做取舍,而技术的提高则使得两者更好地均衡。 2. Cache优化改良键值Key的设置 ...

March 26, 2021 · 2 min · jiezi

关于linux:linux进程常见信号

应用swoole进行过程相干编程时,常常会遇到对于过程信号的问题,在这里做一个整顿 SIGCHLD(17)子过程退出的时候会向其父过程发送一个SIGCHLD信号 Swoole\Process::signal(SIGCHLD, function ($sig) { //必须为false,非阻塞模式 while ($ret = Swoole\Process::wait(false)) { echo "PID={$ret['pid']}\n"; }});swoole监听SIGCHLD信号,设置回调函数对子过程进行非阻塞回收 SIGTERM(15)失常完结的信号,kill命令默认信号. // 默认发送信号 SIGTERMSwoole\Process::kill(int $pid, int $signo = SIGTERM): bool

March 26, 2021 · 1 min · jiezi

关于php:使用策略模式和简单工厂模式重写支付模块

最近接到一个波及领取的需要,旧代码看的有拍板大,所以捋了捋逻辑,看了下工夫,还是足够的,所以就重写了一遍领取模块,抽空记录一下过程。 问题所在全副领取走对立的二维码生成接口,导致须要通过 type 辨别接管不同的字段,随着领取形式越来越多,参数判断越来越多,难以保护代码解构凌乱,一个 $data 变量贯通整个办法,导致最初不晓得 $data 变量外面什么数据,开发、排错越来越简单异样解决,业务代码处处抛出 \Exception 和捕捉 \Exception ,导致如果程序遇到了零碎异样也不能及时的告诉谬误革新前的一段伪代码所有业务逻辑谬误也抛出 \Exception 异样,捕捉 \Exception 后返回 下单失败 导致如果程序遇到真正谬误时,无奈及时排查谬误单看 checkVerifyType() 办法名会认为只是查看领取 type 是否正确, 但却不是,这个办法把所有该干不该干的事都干完了传参用 0 ,1 也不能明确晓得是代表什么货色qrcode 接口参数也很简单,例:type = 1时,必须要 code 参数; type = 2 时,必须要 price 参数;type = 3 时 ....$data 外面各种数据,有:申请数据,订单长期数据,订单预览数据,依据购买商品的不同又放入不同的数据,后果 $data 就是个大杂烩,批改起来切实一言难尽// 所有购买入口获取二维码的入口public function qrcode(Request $request){ try { // ... $key = $this->checkVerifyType(0, 1); // ... return $key; } catch (\Exception $e) { return '下单失败'; }}*/Service/PayService.php public function checkVerifyType($payType1 = 0, $payType2 = 0){ $data = request()->all(); if (!ctype_digit(strval($data['type']))) { throw new \Exception('type err'); } // ..... 还有一堆的参数验证 switch ($data['type']) { case 'vip': // ... 验证 $data['vip_info'] = Vip::where('code', $data['code'])->first(); break; case 'recharge': // ... 验证 $data['money'] = $data['money']; break; // case... } // 优惠券判断 if ($data['coupon_id']) { $money = Coupon::where('id', $data['coupon_id'])->value("money"); $data['reduce'] = $money; // .... } // 订单预览信息 $data['show_title'] = "购买一个会员"; $data['show_money'] = 100; $key = "abcdefg"; Redis::set($key, $data); return $key;}着手革新波及领取的模块有:开明会员、充值、购买单个商品等开发领取流程: ...

March 26, 2021 · 5 min · jiezi

关于php:在PHP中检测一个类是否可以被foreach遍历

在PHP中,咱们能够非常简单的判断一个变量是什么类型,也能够十分不便的确定一个数组的长度从而决定这个数组是否能够遍历。那么类呢?咱们要如何晓得这个类是否能够通过 foreach 来进行遍历呢?其实,PHP曾经为咱们提供了一个现成的接口。 class Obj1{ public $v = 'V:Obj1'; private $prv = 'prv:Obj1';}$obj1 = new Obj1();echo $obj1 instanceof Traversable ? 'yes' : 'no', PHP_EOL; // noclass Obj2 implements IteratorAggregate{ public $v = 'V:Obj2'; private $prv = 'prv:Obj2'; public function getIterator() { return new ArrayIterator([ 'v' => $this->v, 'prv' => $this->prv, ]); }}$obj2 = new Obj2();echo $obj2 instanceof Traversable ? 'yes' : 'no', PHP_EOL; // yes从下面的例子中能够看出,每一个 \$obj1 无奈通过 Traversable 判断,所以它是不能被遍历的。而第二个 $obj2 则是实现了迭代器接口,这个对象是能够通过 Traversable 判断的。在PHP手册中,Traversable 接口正是用于检测一个类是否能够被 foreach 遍历的接口。 ...

March 26, 2021 · 1 min · jiezi

关于github:推荐一款开源在线网课系统

 大家好,我是为宽广程序员兄弟操碎了心的小编,每天举荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节俭开发效率,实现不加班不熬夜不掉头发,是我的指标! 明天小编举荐一款开源在线教育解决方案,依靠腾讯云根底服务架构,采纳C扩大框架Phalcon开发,致力开源网课零碎,开源网校零碎,开源在线教育零碎。 开源协定 应用 GPL-2.0开源协定 链接地址 公众号【Github导航站】回复关键词【酷瓜云】获取git地址 零碎性能实现了点播、直播、专栏、会员、微聊等,是一个残缺的产品,具体性能我也不想写一大堆,本人体验吧! 情谊提醒: 系统配置低(1核 1G 1M 跑多个容器),切莫压测课程数据来源于网络(无本质内容),切莫购买治理后盾已禁止数据提交,私密配置已过滤多端反对:反对 PC,H5,微信小程序,安卓,苹果等终端。PC前端演示 挪动端前端 治理后盾 结尾 本期就分享到这里,我是小编南风吹,专一分享好玩乏味、离奇、实用的开源我的项目及开发者工具、学习资源!心愿能与大家独特学习交换,欢送关注我的公众号【Github导航站】。

March 26, 2021 · 1 min · jiezi

关于php:再次学习方法参数类型声明

不论从事什么行业,当初都是活到老学到老的趋势,特地是咱们这堆码农。这回也不用说新技术用不上,光光是PHP文档的学习都会发现十分多的知识点其实本人并没有真正的把握,比如说这个办法参数的类型申明。上次文章中,对于PHP的办法参数类型束缚,咱们说过办法参数的类型束缚仅限于类、接口、数组或者callable回调函数,其实这是不谨严的,PHP中也有一个严格模式的定义,如果指定了严格模式的话,一般的为办法参数类型指定一般的标量类型也是有成果的。 严格模式的定义: declare (strict_types = 1);int 类型function testInt(int $a){ echo $a, PHP_EOL;}testInt(1);// testInt(1.1); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int// testInt('52AABB'); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int// testInt(true); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int在严格模式下,很显著地看出当初这个办法的参数只能接管 int 类型的值了,其余的类型都无奈接管,当然也不会像之前文章说过的那样会产生强制转换。 float 类型function testFloat(float $a){ echo $a, PHP_EOL;}testFloat(1);testFloat(1.1);// testFloat('52AABB'); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int// testInt(true); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int这里须要留神的是,PHP只有 int 和 float,而且 float 是 int 的超集,所以这里是能够传整数过去的,不过下面的 testInt(int $a) 则不能接管 1.1 这样的 float 值。这就波及到了高低转换的问题,向超集转换是OK的,然而超集向子集转换是就不OK了。 ...

March 25, 2021 · 2 min · jiezi

关于laravel:laraveladmin的图片上传bug

最近的我的项目用laravel-admin做开发,版本是1.8.11,发现了一个图片上传的问题,搜了一下好多人也遇到然而也没什么人贴解决方案,贴一下我的解决办法。我遇到的问题就是: 增加一条记录的时候能够失常增加,图片也能失常保留。第二次要批改这条记录时,无论改没改这个图片,都无奈保留。弹出来的谬误提醒是 Argument 1 passed to Encore\Admin\Form\Field\File::getStoreName() must be an instance of Symfony\Component\HttpFoundation\File\UploadedFile, null given, called in XXXX\vendor\encore\laravel-admin\src\Form\Field\Image.php on line XXX大略就是说须要传一个对象,却给了字符串。 一看到是在encore外面报进去的谬误,然而我的代码很简略,不太可能是调用出了问题。另外有很多人在论坛上吐槽这个问题,所以我预计这是一个bug. $form->UEditor('title','题目');$form->image('logo', '图标');$form->UEditor('content', '内容');$form->number('order', '排序');$form->text('typesetting', '布局');解决办法其实说进去也挺无奈的 1.升高版本 办公室的共事一个是1.7 一个是1.4 他们没有呈现过个bug2.本人写一个image拓展写拓展之前首先要解决掉这个bug 我找到源码外面的image.php,给报错的中央加了个is_string的判断。 if(!is_string($image)){ $this->name = $this->getStoreName($image); $this->callInterventionMethods($image->getRealPath()); $path = $this->uploadAndDeleteOriginal($image); $this->uploadAndDeleteOriginalThumbnail($image); return $path;}else{ return $image;}运行之后没有问题 接着就是拓展了复制整个文件Image.php,而后我把它放到App\Extension\Form上面,因为我加过uEditor的拓展,所以有这个目录,没有的能够本人建。放进去之后改一下namespace和use 因为Image这个拓展是有其余依赖的,所以也要确保依赖引入是正确的。改完如下: <?phpnamespace App\Admin\Extension\Form;use Encore\Admin\Form\Field\File;use Encore\Admin\Form\Field\ImageField;use Symfony\Component\Http\Foundation\File\UploadedFile;class Image extends File{ use ImageField; /** * {@inheritdoc} */ protected $view = 'admin::form.file'; /** * Validation rules. * * @var string */ protected $rules = 'image'; /** * @param array|UploadedFile $image * * @return string */ public function prepare($image) { if ($this->picker) { return parent::prepare($image); } if (request()->has(static::FILE_DELETE_FLAG)) { return $this->destroy(); } if(!is_string($image)){ $this->name = $this->getStoreName($image); $this->callInterventionMethods($image->getRealPath()); $path = $this->uploadAndDeleteOriginal($image); $this->uploadAndDeleteOriginalThumbnail($image); return $path; }else{ return $image; } } /** * force file type to image. * * @param $file * * @return array|bool|int[]|string[] */ public function guessPreviewType($file) { $extra = parent::guessPreviewType($file); $extra['type'] = 'image'; return $extra; }}接着App\Admin\bootstrap.php改一下配置 ...

March 24, 2021 · 1 min · jiezi

关于php:Laravel-Seeder-生成百万模拟数据

Laravel 集成了 Faker 库,并提供了 Seeder 能够帮忙咱们轻松地生成模仿数据。 先书写数据仓库和数据填充代码 数据仓库代码 use App\Models\Topic;use Faker\Generator as Faker;$factory->define(Topic::class, function (Faker $faker) { $sentence = $faker->sentence(); // 随机取一个月以内的工夫 $updated_at = $faker->dateTimeThisMonth(); // 传参为生成最大工夫不超过,因为创立工夫永远比更改工夫要早 $created_at = $faker->dateTimeThisMonth($updated_at); return [ 'title' => $sentence, 'body' => $faker->text(), 'excerpt' => $sentence, 'created_at' => $created_at, 'updated_at' => $updated_at, ];});数据填充代码 class TopicsTableSeeder extends Seeder{ /** * Run the database seeds. * * @return void */ public function run() { // 所有用户ID数组,如:[1,2,3,4] $user_ids = User::all()->pluck('id')->toArray(); // 所有分类 ID 数组,如:[1,2,3,4] $category_ids = Category::all()->pluck('id')->toArray(); // 获取 Faker 实例 $faker = app(Faker\Generator::class); $topics = factory(Topic::class) ->times(1000) ->make() ->each(function ($topic, $index) use ($user_ids, $category_ids, $faker){ // 从用户 ID 数组中随机取出一个并赋值 $topic->user_id = $faker->randomElement($user_ids); // 话题分类,同上 $topic->category_id = $faker->randomElement($category_ids); }); // 将数据汇合转换为数组,并插入到数据库中 Topic::insert($topics->toArray()); }}咱们通过是 times() 设置了填充的次数,执行数据填充命令,能够将 1000 条数据填充至 topics 表中,这很不便。 ...

March 24, 2021 · 1 min · jiezi

关于php:使用Serializable接口来自定义PHP中类的序列化

对于PHP中的对象序列化这件事儿,之前咱们在很早前的[]()文章中曾经提到过 __sleep() 和 __weakup() 这两个魔术办法。明天咱们介绍的则是另外一个能够管制序列化内容的形式,那就是应用 Serializable 接口。它的应用和上述两个魔术办法很相似,但又稍有不同。 Serializable接口class A implements Serializable { private $data; public function __construct(){ echo '__construct', PHP_EOL; $this->data = "This is Class A"; } public function serialize(){ echo 'serialize', PHP_EOL; return serialize($this->data); } public function unserialize($data){ echo 'unserialize', PHP_EOL; $this->data = unserialize($data); } public function __destruct(){ echo '__destruct', PHP_EOL; } public function __weakup(){ echo '__weakup', PHP_EOL; } public function __sleep(){ echo '__destruct', PHP_EOL; } }$a = new A();$aSerialize = serialize($a);var_dump($aSerialize);// "C:1:"A":23:{s:15:"This is Class A";}"$a1 = unserialize($aSerialize);var_dump($a1);这段代码就是应用 Serializable 接口来进行序列化解决的,留神一点哦,实现了 Serializable 接口的类中的 __sleep() 和 __weakup() 魔术办法就有效了哦,序列化的时候不会进入它们。 ...

March 24, 2021 · 2 min · jiezi

关于php:Laravel-的用户授权

简介Gates 是用来判断用户是否有权限执行某个动作的闭包函数。 定义Gates 通常在 App\Providers\AuthServiceProvider 中定义。 Gates 的第一个参数为用户实例,反对可选参数,如 Eloquent 模型: public function boot(){ $this->registerPolicies(); // 定义编辑设置的权限 Gate::define('edit-settings', function ($user) { return $user->isAdmin; }); // 定义更新文章的权限 Gate::define('update-post', function ($user, $post) { return $user->id === $post->user_id; });}public function boot(){ $this->registerPolicies(); Gate::define('update-post', 'App\Policies\PostPolicy@update');}应用if (Gate::allows('edit-settings')) { // 以后用户能够编辑设置}if (Gate::allows('update-post', $post)) { // 以后用户能够更新文章}if (Gate::denies('update-post', $post)) { // 以后用户不能更新文章}if (Gate::forUser($user)->allows('update-post', $post)) { // 指定用户能够更新文章}if (Gate::forUser($user)->denies('update-post', $post)) { // 指定用户不能更新文章}参数上下文Gate::define('create-post', function ($user, $category, $extraFlag) { return $category->group > 3 && $extraFlag === true;});if (Gate::check('create-post', [$category, $extraFlag])) { // The user can create the post...}受权响应use Illuminate\Support\Facades\Gate;use Illuminate\Auth\Access\Response;Gate::define('edit-settings', function ($user) { return $user->isAdmin ? Response::allow() : Response::deny('You must be a super administrator.');});// inspect 获取 Gate 返回的残缺受权响应$response = Gate::inspect('edit-settings', $post);if ($response->allowed()) { // 以后行为已受权...} else { echo $response->message();}受权拦挡// 在所有其余受权查看之前执行Gate::before(function ($user, $ability) { if ($user->isSuperAdmin()) { return true; }});// 在所有其余受权查看后执行Gate::after(function ($user, $ability, $result, $arguments) { if ($user->isSuperAdmin()) { return true; }});

March 23, 2021 · 1 min · jiezi

关于php:php代码片段-sendFilevideoStreamsendEmailphpexcelffmpegzip

sendFile发送文件<?php$doc = filter_input(INPUT_GET, 'file');if ($doc) { // decode requested file path $docPath = base64_decode($doc); // check file path if ($docPath !== false && file_exists($docPath)) { $mimeType = Utils::get_mime_type($docPath); if (stripos($mimeType, 'audio/') !== false || stripos($mimeType, 'video/') !== false) { // streaming media $stream = new VideoStream($docPath); $stream->start(); } else { // output document $fName = basename(filter_input(INPUT_SERVER, 'PATH_INFO')); $fSize = filesize($docPath); if (strpos($fName, '.') === false && strrpos(basename($docPath), '.') !== false) { $ext = substr(basename($docPath), -strrpos(basename($docPath), '.')); $fName .= $ext; } header('Content-type: ' . $mimeType); header('Content-disposition: filename="' . $fName . '"'); header('Content-Length: ' . $fSize); flush(); $fHandle = fopen($docPath, 'r'); while (!feof($fHandle)) { // send the current file part to the browser print fread($fHandle, 8192); // flush the content to the browser flush(); } fclose($fHandle); } } else { header('HTTP/1.0 401 Unauthorized'); echo 'Unauthorized access'; // log $fh = @fopen('getDoc.log', 'a'); if ($fh !== false) { $msg = 'Try to access not existing file'; fwrite($fh, PHP_EOL . date('Y-m-d H:i:s') . ' *** ' . $msg . ' ' . $docPath); fclose($fh); } }}videoStream发送视频流<?phpclass VideoStream { private $path = ''; private $stream = null; private $buffer = 102400; private $start = -1; private $end = -1; private $size = 0; /** * @param string $filePath */ public function setPath($filePath) { $this->path = $filePath; } /** * Open stream */ private function open() { if (!($this->stream = fopen($this->path, 'rb'))) { die('Could not open stream for reading'); } } /** * Set proper header to serve the video content */ private function setHeader() { ob_get_clean(); $mimeType = \Utils::get_mime_type($this->path); header("Content-Type: " . $mimeType); header("Cache-Control: max-age=2592000, public"); header("Expires: " . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT'); header("Last-Modified: " . gmdate('D, d M Y H:i:s', @filemtime($this->path)) . ' GMT'); $this->start = 0; $this->size = filesize($this->path); $this->end = $this->size - 1; header("Accept-Ranges: 0-" . $this->end); if (isset($_SERVER['HTTP_RANGE'])) { $c_end = $this->end; list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2); if (strpos($range, ',') !== false) { header('HTTP/1.1 416 Requested Range Not Satisfiable'); header("Content-Range: bytes $this->start-$this->end/$this->size"); exit; } if ($range == '-') { $c_start = $this->size - substr($range, 1); } else { $range = explode('-', $range); $c_start = $range[0]; $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $c_end; } $c_end = ($c_end > $this->end) ? $this->end : $c_end; if ($c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size) { header('HTTP/1.1 416 Requested Range Not Satisfiable'); header("Content-Range: bytes $this->start-$this->end/$this->size"); exit; } $this->start = $c_start; $this->end = $c_end; $length = $this->end - $this->start + 1; fseek($this->stream, $this->start); header('HTTP/1.1 206 Partial Content'); header("Content-Length: " . $length); header("Content-Range: bytes $this->start-$this->end/" . $this->size); } else { header("Content-Length: " . $this->size); } } /** * close currently opened stream */ private function end() { fclose($this->stream); exit; } /** * perform the streaming of calculated range */ private function stream() { $i = $this->start; set_time_limit(0); while (!feof($this->stream) && $i <= $this->end) { $bytesToRead = $this->buffer; if (($i + $bytesToRead) > $this->end) { $bytesToRead = $this->end - $i + 1; } $data = fread($this->stream, $bytesToRead); echo $data; flush(); $i += $bytesToRead; } } /** * Start streaming video content */ public function start() { $this->open(); $this->setHeader(); $this->stream(); $this->end(); }}sendEmail发送邮件<?php$transport = new \Zend\Mail\Transport\Sendmail();$attachment = array();// add properties$msg = new \Zend\Mail\Message();$msg->addFrom('fromEmail', 'fromName') ->addTo('toEmail') ->setSubject('subject') ->addCc('ccEmail') ->addBcc('bccEmail');if (count($attachment) > 0) { // new MIME message $mimeMessage = new \Zend\Mime\Message(); // add body $text = new \Zend\Mime\Part(nl2br('body')); $text->type = \Zend\Mime\Mime::TYPE_HTML; $text->charset = 'utf-8'; $mimeMessage->addPart($text); // add attachment foreach ($attachment as $fPath) { if (file_exists($fPath)) { $attachment = new \Zend\Mime\Part(fopen($fPath, 'r')); $attachment->type = \Zend\Mime\Mime::TYPE_OCTETSTREAM; $attachment->filename = basename($fPath); $attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT; $attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64; $mimeMessage->addPart($attachment); } } $msg->setBody($mimeMessage);} else { $msg->setBody('body');}$transport->send($msg);phpexcel电子表格解决<?phpclass Exporter { /** @var string */ public $filename; /** @var string */ public $creator; /** @var string */ public $title; /** @var string */ public $description; /** @var string */ public $subject; /** @var string */ public $keywords; /** @var boolean */ public $boldTitle; /** @var boolean */ public $autoSizeText; /** * @var array * array(<sheet_index> => array('selector' => <cell_selector>,'style' => <PHPExcel_style_array>)) */ public $cellStyles; public function __construct() { $this->filename = date('Y_m_d_H_i_s', time()) . '.xlsx'; $this->creator = ''; $this->title = ''; $this->description = ''; $this->subject = ''; $this->keywords = ''; $this->boldTitle = false; $this->autoSizeText = false; $this->cellStyles = array(); } /** * @param string */ public function setFilename($fullFilename) { $this->filename = $fullFilename; } /** * @param string */ public function setCreator($creator) { $this->creator = $creator; } /** * @param string */ public function setTitle($title) { $this->title = $title; } /** * @param string */ public function setDescription($description) { $this->description = $description; } /** * @param string */ public function setSubject($subject) { $this->subject = $subject; } /** * @param string */ public function setKeywords($keywords) { $this->keywords = $keywords; } /** * @param boolean */ public function setBoldTitle($boldTitle) { $this->boldTitle = $boldTitle; } /** * @param boolean */ public function setAutoSizeText($autoSizeText) { $this->autoSizeText = $autoSizeText; } /** * @param array */ public function setCellStyles($cellStyles) { $this->cellStyles = $cellStyles; } /** * * @param array $sheetItems * @return string filename */ public function export($sheetItems) { //Generate PHPExcel $excel = new \PHPExcel(); $excel->getProperties() ->setCreator($this->creator) ->setTitle($this->title) ->setDescription($this->description) ->setSubject($this->subject) ->setKeywords($this->keywords); $idxSheet = 0; $lastColumn = null; foreach ($sheetItems as $sheetName => $items) { if ($idxSheet > 0) { $excel->createSheet($idxSheet); } $currSheet = $excel->setActiveSheetIndex($idxSheet); $currSheet->setTitle(mb_substr($sheetName, 0, 31)); //Fill data $idxRow = 1; foreach ($items as $subDatas) { $idxCol = 0; foreach ($subDatas as $itemValue) { $coords = \PHPExcel_Cell::stringFromColumnIndex($idxCol) . $idxRow; $currSheet->setCellValueExplicit($coords, $itemValue, \PHPExcel_Cell_DataType::TYPE_STRING); $idxCol++; } $idxRow++; } //Style: title bold if ($this->boldTitle) { $lastColumn = $currSheet->getHighestColumn(); $currSheet->getStyle('A1:' . $lastColumn . '1')->applyFromArray(array('font' => array('bold' => true))); } //Style: wrap and autosize text if ($this->autoSizeText) { $lastColumn = ($lastColumn) ? : $currSheet->getHighestColumn(); $currSheet->getStyle('A2:' . $lastColumn . $idxRow)->getAlignment()->setWrapText(true); $iterator = $lastColumn; $iterator++; for ($column = 'A'; $column != $iterator; $column++) { $currSheet->getColumnDimension($column)->setAutoSize(true); } } //Style cells if (count($this->cellStyles) > 0 && isset($this->cellStyles[$idxSheet])) { foreach ($this->cellStyles[$idxSheet] as $row) { $currSheet->getStyle($row['selector'])->applyFromArray($row['style']); } } $currSheet->garbageCollect(); $idxSheet++; } //Save $excel->setActiveSheetIndex(0); $writer = \PHPExcel_IOFactory::createWriter($excel, 'Excel2007'); $writer->save($this->filename); return $this->filename; }}ffmpeg图片批改<?php/** * exp: Convert video to mp4 * $ffmpeg = new FFMpeg(); * $ffmpeg->open('xxx'); * $ffmpeg->setVcodec('libx264'); * $ffmpeg->setVquality('28'); * $ffmpeg->setAcodec('aac'); * $ffmpeg->setAquality('128k'); * $ffmpeg->setDuration('30'); * $success = $ffmpeg->save('xxx.mp4'); *//** * exp: Convert audio to mp3 * $ffmpeg = new FFMpeg(); * $ffmpeg->setAcodec('libmp3lame'); * $ffmpeg->setAquality('6'); * $ffmpeg->setDuration('30'); * $success = $ffmpeg->save('xxx.mp3'); *//** * exp: Export screenshot * $ffmpeg = new FFMpeg(); * $ffmpeg->open('xxx.mp4'); * $ffmpeg->setPosition('10'); * $ffmpeg->exportScreenshot('test.png'); *//** * exp: avconv -i source_path -codec:v libx264 -crf 28 -codec:a aac -b:a 128k -strict experimental dest_path *//** * Class FFMpeg */class FFMpeg{ /** * @var bool * Overwrite output files without asking. */ private $overwrite = true; /** * @var string * file path of (input) */ private $path = ''; /** * @var string * video codec (output) */ private $vcodec = ''; /** * @var string * audio codec (output) */ private $acodec = ''; /** * @var string * duration (output) * * Stop writing the output after its duration reaches duration. * duration may be a number in seconds, or in hh:mm:ss[.xxx] form. */ private $duration = ''; /** * @var string * quality (output audio) * FOR libmp3lame: 0-9 (a lower value is a higher quality * 0-3 will normally produce transparent results, * 4 (default) should be close to perceptual transparency, * 6 produces an "acceptable" quality.) * FOR OTHERS: bitrate (in bits/s) 128k, 256k */ private $aquality = ''; /** * @var string * quality (output video) * FOR libx264: 0-51 (0: lossless, 23: default, 51: rubbish, * A value of 18-28 is considered "sane" with 18 being "visually lossless".) * FOR OTHERS: bitrate (in bits/s) 800k, 1000k */ private $vquality = ''; /** * @var string * position may be either in seconds or in hh:mm:ss[.xxx] form. (input video) */ private $position = '3'; /** * @var string * This will scale to your desired width * and the height will be automatically scaled to the appropriate value to preserve aspect. */ private $width = ''; /** * @param string $filePath */ public function __construct($filePath = '') { $this->path = $filePath; } /** * @param boolean $overwrite */ public function setOverwrite($overwrite) { $this->overwrite = $overwrite; } /** * @param string $aquality */ public function setAquality($aquality) { $this->aquality = $aquality; } /** * @param string $vquality */ public function setVquality($vquality) { $this->vquality = $vquality; } /** * @param string $duration */ public function setDuration($duration) { $this->duration = $duration; } /** * @param string $filePath */ public function open($filePath) { $this->path = $filePath; } /** * @param string $acodec */ public function setAcodec($acodec) { $this->acodec = $acodec; } /** * @param string $vcodec */ public function setVcodec($vcodec) { $this->vcodec = $vcodec; } /** * @param string $position */ public function setPosition($position) { $this->position = $position; } /** * @param string $width */ public function setWidth($width) { $this->width = $width; } /** * @param string $filename * @return bool * @throws \Exception */ public function save($filename) { if (!file_exists($this->path)) { return false; } //Do ffmpeg command $cmdLine = 'avconv -i ' . str_replace(' ', '\ ', $this->path); if ($this->overwrite) { $cmdLine .= ' -y'; } // video codec if ($this->vcodec !== '') { $cmdLine .= ' -codec:v ' . $this->vcodec; } // video quality if ($this->vcodec !== '' && $this->vquality !== '') { if (stripos($this->vcodec, 'libx264') !== false || stripos($this->vcodec, 'h264') !== false) { if ($this->vquality >= 0 && $this->vquality <= 51) { $cmdLine .= ' -crf ' . $this->vquality; //h264 use -crf } else { throw new \Exception('quality of video: invalid argument (0-51)'); } } else { if (stripos($this->vquality, 'k') !== false) { $cmdLine .= ' -b:v ' . $this->vquality; // others can user -b:v (bitrate) } else { throw new \Exception('quality of video: invalid argument (128k, 256k...)'); } } } // audio codec if ($this->acodec !== '') { $cmdLine .= ' -codec:a ' . $this->acodec; } // audio quality if ($this->acodec !== '' && $this->aquality !== '') { if (stripos($this->acodec, 'libmp3lame') !== false || stripos($this->acodec, 'mp3') !== false) { if ($this->aquality >= 0 && $this->aquality <= 9) { $cmdLine .= ' -q:a ' . $this->aquality; //mp3 use -qscale:a } else { throw new \Exception('quality of audio: invalid argument (0-9)'); } } else { if (stripos($this->aquality, 'k') !== false) { $cmdLine .= ' -b:a ' . $this->aquality; // others can user -b:a (bitrate) } else { throw new \Exception('quality of audio: invalid argument (128k, 256k...)'); } } } // ouput maximium duration if ($this->duration !== '') { $cmdLine .= ' -t ' . $this->duration; } // strict mode $cmdLine .= ' -strict experimental ' . str_replace(' ', '\ ', $filename); $exec = shell_exec($cmdLine); return ($exec === null); } /** * @param string $imagename * @return bool */ public function exportScreenshot($imagename) { if (!file_exists($this->path)) { return false; } //Do ffmpeg command $cmdLine = 'avconv -i ' . str_replace(' ', '\ ', $this->path); if ($this->overwrite) { $cmdLine .= ' -y'; } if ($this->position) { $cmdLine .= ' -ss ' . $this->position; } if ($this->width) { $cmdLine .= ' -filter:v scale=' . $this->width . ':-1 '; } $cmdLine .= ' -frames:v 1 ' . str_replace(' ', '\ ', $imagename); $exec = shell_exec($cmdLine); return ($exec === null); }}zip压缩包<?phpclass Zip{ /** @var string */ protected $_encoding; /** @var string */ public $filename; /** * Zip constructor. */ public function __construct() { $this->setEncoding('CP437//IGNORE//TRANSLIT'); $this->filename = time() . '.zip'; } /** * @param string $enc */ public function setEncoding($enc = null) { $this->_encoding = $enc; } /** * @param string $fullFilename */ public function setFilename($fullFilename) { $this->filename = $fullFilename; } /** * * @param array $paths string[] * @return boolean TRUE on success, FALSE on failure */ public function compress($paths) { if (!is_array($paths)) { return false; } // TODO: rename file $cleanPaths = array(); foreach ($paths as $path) { $bName = basename($path); if ($this->_encoding !== null) { $bName = iconv('UTF-8', $this->_encoding, $bName); } $cleanPaths[$path] = $bName; } if (shell_exec('which zip') !== null) { $success = $this->_compressShell($cleanPaths); } else { $success = $this->_compressZipArchive($cleanPaths); } return $success; } /** * @param array $cleanPaths Files to archive. * key: full file path, value: new file name * @return boolean TRUE on success or FALSE on failure. */ protected function _compressShell($cleanPaths) { // create temporary working folder $tmpDir = basename($this->filename, '_tmpDir') . '/'; if (is_dir($tmpDir)) { if (!$this->_deleteDir($tmpDir)) { return false; } } if (!mkdir($tmpDir, 0777, true)) { return false; } // copy files to temporary working folder foreach ($cleanPaths as $path => $cleanPath) { copy($path, $tmpDir . $cleanPath); } // zip, 1->compress faster, j->junk (don't record) directory names, q->quiet operation $cmd = 'zip -1jq ' . $this->filename . ' ' . $tmpDir . '*'; $output = array(); exec($cmd, $output, $return); // delete temporary working folder $this->_deleteDir($tmpDir); // return will return non-zero upon an error if (!$return) { return true; } else { return false; } } /** * @param array $cleanPaths Files to archive. * key: full file path, value: new file name * @return boolean TRUE on success or FALSE on failure. */ protected function _compressZipArchive($cleanPaths) { $zip = new \ZipArchive(); // open zip file $zip->open($this->filename, \ZipArchive::CREATE); // add files, // TODO: improve performance foreach ($cleanPaths as $path => $cleanPath) { $zip->addFile($path, $cleanPath); } // close zip return $zip->close(); } /** * @param $dirPath * @return boolean */ protected function _deleteDir($dirPath) { if (!is_dir($dirPath)) { return false; } if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') { $dirPath .= '/'; } foreach (glob($dirPath . '*', GLOB_MARK) as $file) { if (is_dir($file)) { $this->_deleteDir($file); } else { unlink($file); } } return rmdir($dirPath); } /** * @param string $destination * @param array $entries * @return boolean */ public function deCompress($destination, $entries = null) { $zip = new \ZipArchive(); $zip->open($this->filename, \ZipArchive::CREATE); $res = $zip->extractTo($destination, $entries = null); $zip->close(); return $res; }}utils工具函数<?php/** * Get memory usage * @return string */public staticfunction get_memory_usage() { $mem_usage = memory_get_peak_usage(true); if ($mem_usage < 1024) { return $mem_usage . " bytes"; } elseif($mem_usage < 1048576) { return round($mem_usage / 1024, 2) . " KB"; } else { return round($mem_usage / 1048576, 2) . " MB"; }}/** * Detemine is JSON and decode JSON * @param string $json * @param bool $return_data * @return mixed the formed array or true on success, or false on failure */public static function is_json($json, $return_data = false) { $data = json_decode($json, true); return (json_last_error() == JSON_ERROR_NONE) ? ($return_data ? $data : TRUE) : FALSE;}/** * Set ini memory limit * @param mixed $newV string '1024M' or int 1024 * @return string the old value on success, false on failure. */public static function ini_set_memory_limit($newV) { $newVInt = (int)str_ireplace('M', '', (string)$newV); $oldV = ini_get('memory_limit'); $oldVInt = (int)str_ireplace('M', '', (string)$oldV); if ($oldVInt < $newVInt) { return ini_set('memory_limit', $newVInt . 'M'); } return $oldV;}/** * Get mine type of file * @param string $filename * @return mixed the mine type on success, or false on failure */public static function get_mime_type($filename) { $realpath = realpath($filename); if($realpath) { if (function_exists('finfo_file') && function_exists('finfo_open') && defined('FILEINFO_MIME_TYPE')) { $finfo = finfo_open(FILEINFO_MIME_TYPE); $mimetype = finfo_file($finfo, $realpath); finfo_close($finfo); return $mimetype; } if (function_exists('mime_content_type')) { return mime_content_type($realpath); } } return false;}

March 23, 2021 · 12 min · jiezi

关于后端:30岁转行程序员晚了吗分享30岁转行的经历

按常规,先说下我根本状况。我是85年的,计算机专业一般本科毕业。在一个二线城市,毕业后因为本身能力问题、认知程度问题,再加上运气不好,换过多份工作,每份工作都干不长。导致我30多岁时,还一事无成,也简直没有积攒到什么教训技术、行业常识等。甚至还一度去开过网约车,送过外卖。 转行做程序员前,我每个月支出仅三四千元。2017年下定决心,筹备转行!我晓得本人最大的劣势就是年龄太大了,但思考再三,因为以下几个起因,我还是决定走这条路: 我目前的状况曾经算是城市里的底层了。我不会做生意,没其它教训和技能,性情偏外向,销售和交际也不太善于。所以我不怕失去什么,因为我也没有什么可失去的。我想学个谋生技能从新开始,而学开发最适宜我。因为我并非0根底,毕竟大学时学的这个业余,而且本人也已经很喜爱编程。我对待遇的要求不高,只有工资在5k以上就行。如果能有6、7 那我就太称心了。过后我的瞎推断:因为国内出生率特地低,当前可能没那么多年轻人供雇主筛选,所以咱们这些中老年人,也有肯定的机会。受到一些心灵鸡汤的激励,比方什么种一颗树最好的机会是十年前,其次,就是当初! 我辞去工作,开始在家自学web开发。次要的学习形式就是在网上看视频教程。那些视频教程,高级的基本上收费。中高级的有些会免费,大略50-300元左右一套。反正“学费”上我没花什么钱,总共不到一千元吧。 先是学了些前端根底。在学后端时,犹豫了下学PHP还是JAVA。在我读书时是学过JAVA的,尽管已记得不多了。于是我就想学个新的吧!还因为PHP比JAVA简略,更适宜中小型我的项目。我这个状况,必定进不了大厂,做不了大我的项目了。所以就决定学PHP。(当初有点小悔恨了) 学完前后端根底后,我还跟着视频教程,本人做了两三个简略的我的项目。在我学习过程中,让我比拟有自信的是——没遇到什么挫折。当然,必定遇到过各种问题被卡住,但本人都去百度解决了。 接下来开始筹备找工作,第一个难点就是简历。快32岁的人了,如果诚实说刚自学进去没任何理论工作教训,必定是没人要的。没方法,只好去包装简历,说成有两年开发教训。瞎编简历的过程还是很艰难的。以前呆的哪家公司,做了什么我的项目,齐全凭想像去假造。 而后海量投简历,艰巨地面试,一直地被淘汰......过后我的信念就是,大不了我花一年工夫去找工作,找不到就持续学,直到找到为止!最终我花了近两个月工夫,可能加入了20次的面试,才勉强找到份工作。 因为没有理论工作教训,造假的简历,是很容易被发现的。只有稍有教训的面试官,多诘问你几个细节,就露馅了。因为你并没有做过,不可能编造出全副的细节。所以面试过程很艰巨。说几次印象粗浅的: 1、一家特地小的公司,还是与人合租的办公室,我过后见到的员工,仿佛只有两个人。与技术面试官简略交换了几句后,他当场决定录用我,让我今天来下班,并且说稍后会发短信给我确认。但不晓得为什么,起初没再分割我了。 2、另一家小公司,还是在居民小区里办公,不过办公环境还不错,约有七八个人的样子。与面试官交换的地点是在生存阳台上,面试官坐着一个繁难塑料板凳,旁边是个洗衣机。和他聊了较长时间,自认为他问的所有问题,我答复得都不错,也很心愿拿到这个offer。满心期待的回家等了好几天,后果也没下文了。 3、也是一家在居民楼里办公的小公司,办公环境给人压抑的感觉。去的时候就遇上,老板模样的人,在对开发人员大发脾气,那些开发人员都不敢吱声。而后那老板看待咱们这些面试者,态度特地粗鲁,埋怨咱们为什么早到了10分钟?口试的内容甚至蕴含间接给他们现有我的项目找bug,和改bug。我心中怄气,中途来到了。 4、最初能找到工作,通过面试,次要是运气。是老板间接跟我聊的,没通过技术面试官。老板感觉我有相干行业工作教训(其实没啥帮忙),又是统招本科,专业对口,就间接决定录用我了。如果过后他让懂技术的人来面试我下,预计我多半过不了。 那是家小公司,连同老板在内,总共十几个人,给的待遇是6k。这待遇对于开发来说,算是最低水平了。但我过后还是很快乐。说出不来怕丢人,比起以前的工作,6k对我来说已是高薪了。 刚去下班那段时间,还是发现了很多“离奇”的货色。比方,原来还有一个岗位,叫做“产品经 理”。以前我始终认为,只须要有开发人员撸代码就行了。更让我汗颜的是,我都不晓得PHP也是能够做APP的。恰好我看的那些视频教程,都没提到这点。讲课的例子,以及做的实战我的项目练习,全是pc网站! 当我共事滑动着手机通知我,app中的这些数据,都是接口中获取的。我拍板,装作原来如此的样子。其实心田却震惊了:然来PHP还能够做APP啊,真是牛B!没错,我就是这么菜,甚至过后我都搞不明确,啥是api接口。感觉这是一个很难的货色。还把它和OOP中的"接口"搞混了。因为他们都叫“接口”二字。 在那里呆了两三个月后,我就没那么白痴了。给我安顿的日常开发工作,都能按时实现。呆了半年后,我慢慢地发现。我后端共事些,程度也不过如此,能够说根底还不如我,我还时不时给他们解答下技术上的问题。过后我还有点飘飘然了,感觉他们只不过对业务更相熟些。 当初的我回想起来,过后我的认识大抵没错。情理很简略:违心去这家公司,拿6-7k工资(除了工资以外,啥也没有)的程序员,只能是高级程度。 通过一年的工夫,我已成长为一个合格的增删改查工程师。这里已学不到什么货色了,当初回想起来,那个公司没有任何技术气氛,在外面呆着,有一种养老的感觉,内部没有什么能源和压力,逼本人持续学习。 经敌人介绍,我跳槽去了另一家公司,很顺利地通过了口试和面试,工资开的9k。 刚去的第一个月,我禁受了很大的压力。部门负责人,看我年龄这么大,就认为我是一个很牛逼的人。就给我安顿了些较难的工作,我很费劲地实现了一两个后。他就给我安顿了个更难的,说:“这个都是架构师搞了的,你好好钻研下吧。”我就在焦虑和不安中,钻研了一周,还是云里雾里的,只好鼓起勇气跟他摊牌了,说我做不来。还好那负责人也没说啥,安顿我做增删改查的业务了。 我第一家公司,还有个大问题是,用的都是些掉队的技术。而我在第二家公司这里也跟上了支流的技术。比方git(上家是svn)、laravel5(上家是tp3)、 docker(上家是phpstudy) 、前后端拆散(以前是混起的)、工作进度管理系统(上家没有) 、业余的测试工程师(上家是经营人员兼测试)等等。光是学习和相熟这些,我都花了大量的工夫。 这里开发人员的技术水平,和上家公司齐全不是一个品位的。气氛也和第一家公司不一样了,共事们常常聊各种新进去的技术。哪怕聊点8卦,也是以IT新闻为主。他们聊的货色,很多我都听不懂。让我深感本人知识面的狭隘。 这里的学习气氛也浓重。做过开发的都晓得,忙的时候真是喝水都顾不上。但有时没事,又闲得很。上家公司在没事干时,大家就偷偷玩游戏、看视频、小说等。这里没事时,大家就是看文档,学新货色。 两三个月后,我缓缓适应这里了。但还是那个问题,始终让我焦虑——年龄。共事闲聊时,我最怕聊到年龄的话题。哪怕和年龄有一点点关系的话题,我也会警惕。比方共事们聊起用的第一部智能手机。我个别就不接话,因为我用的第一个智能手机还是palm! 然而,怕什么还是来什么了。 有一次团聚,又聊起年龄。每个人就在说说笑笑地报本人的年龄。轮到我时,我强笑着说:“我嘛,永远18岁。”一个失常情商的人,都会明确,这就是不违心说,识趣的话应该也就别多问了。然而,在坐有个共事,情商真的太低了,他间接跳出来说:“他85年的!”此时,刚走进来一个95后共事,听到“85年”这三个字,顺口就说了句:“谁85年的啊?”过后我感觉整个空气都凝固了,我的大腿管制不住地抖动,背上稀稀拉拉地出汗,把衬衣都湿透了。我只好举手示意,说:“是我,我是85年的...”过后我的难堪和惭愧,永远也无奈遗记。 目前我工资12k,依然是一个技术一般的后端开发人员。对于这个支出我是知足和称心的。 我是个脸皮薄,性情敏感的人,2020年又要满35岁了,哎! 其实让我目前感到难堪和惭愧的并不齐全是因为年龄。而是我的年龄和技术能力齐全不匹配!公司中也有年龄和我相仿的人,但在我的眼中,他们都是技术大牛了。感觉什么都懂,轻易说一个问题,他们都能给你上上课,讲讲底层原理。当我新听到一个技术概念,感觉很陈腐,正筹备去理解个大略时。他们不仅相熟,甚至还晓得茴香豆的茴字,有四种写法! 青春逝去,时光不再。比我聪慧,比我入行早的人,都还在致力,我当初能做的,只能是持续努力学习,仅仅心愿不要那么争脸。 对于那些一毕业就干开发,目前不到30岁,但常常据说程序员只能做到35岁,并为此焦虑的同学。请你们只管释怀,只有你们做的不是养老的工作,每年在技术上都有显著提高,找到好工作相对没问题。至多在中型公司当个leader是没问题的。 但在此劝那些30多岁想转行程序员的人,如果你们像我一样,不是一个脸皮厚的人,肯定要谨慎! 不过如果呆在那种10集体左右的小公司,这种年龄难堪,要稍好点,但就没什么技术气氛了,成长较慢。 至于有人问我他该不该转行程序员,我想说职业规划是小事,每个人的状况都不一样,这很难答复。何况我也不是个“人生导师”,只是个技术一般的大龄程序员。我集体意见总结起来是这样的,就不再一一独自回复了: 1.你是否有趣味和能力去做好开发? 有个简略的办法,能够判断本人是否有能力。那就是回顾一下本人中学或大学时的数学问题!如果数学问题好,阐明你有天才,反之就没有。这并不是说,做我的项目开发须要多少数学知识——相关性不等于因果性。只是因为,数学问题好,代表你比拟聪慧,抽象思维能力强,这是开发所须要的。我本人读的是一个普通中学,一般大学。我的数学问题,个别在班上排名前5。我本人感觉就是学高级、中级的常识较容易。高级点的常识,学起来就特地吃力。我公司里有位共事,很年老,技术特地厉害。我就很好奇,问了他一句:“你大学时,是不是数学很好?”后果他答复,他数学始终是全校第一名。2.你的现状是什么? 如果当初有份支出不错,且能长期干上来的工作,那也没必要去转行。反之,如果像我当初一样,做着一份毫无前途,月支出仅三、四千元的工作,那能够思考转行。3.你的年龄? 如果你还年老,大略在26岁以下,且前2个条件都满足,那能够去转。而如果像我一样,过后都30多岁了,要谨慎。如果大家对于学习Java有任何的问题,对于如何晋升学习Java以及学习办法、学习技巧、疾速达到待业的技术水平,都能够随时来问我,这是我建设了5年的Java学习交换QQ群:796866257。有不懂的问题能够随时在外面问,须要Java各个阶段的学习材料也能够在外面进行下载。对于前端和Python的问题也能够问。

March 23, 2021 · 1 min · jiezi

关于php:原生php循环输出501到599保留两位小数

原生php循环输入5.01到5.99,保留两位小数 $RangeArray=array();for ($i=5.01; $i <= 5.99; $i+=0.01) { $val=sprintf("%.2f",$i); $RangeArray[]=$val;}print_r($RangeArray);作者:小小书童网站:http://apppay.xyz

March 23, 2021 · 1 min · jiezi

关于php:扩展推荐Aliyunosslaravel-Laravel最好的OSS-Storage扩展

我的项目地址https://github.com/alphasnow/aliyun-oss-laravel https://packagist.org/packages/alphasnow/aliyun-oss-laravel 装置办法如果您通过composer治理您的我的项目依赖,能够在你的我的项目根目录运行: $ composer require alphasnow/aliyun-oss-laravel或者在你的composer.json中申明依赖: "require": { "alphasnow/aliyun-oss-laravel": "~1.0" }批改环境文件.env ALIYUN_OSS_ACCESS_ID=ALIYUN_OSS_ACCESS_KEY=ALIYUN_OSS_BUCKET=ALIYUN_OSS_ENDPOINT=oss-cn-shanghai.aliyuncs.comALIYUN_OSS_IS_CNAME=falseALIYUN_OSS_CDN_DOMAIN=ALIYUN_OSS_IS_CNAME=falseALIYUN_OSS_SSL=false(可选)批改配置文件 config/filesystems.php 'default' => env('FILESYSTEM_DRIVER', 'aliyun'),// ...'disks'=>[ // ... 'aliyun' => [ 'driver' => 'aliyun', 'access_id' => env('ALIYUN_OSS_ACCESS_ID'), 'access_key' => env('ALIYUN_OSS_ACCESS_KEY'), 'bucket' => env('ALIYUN_OSS_BUCKET'), 'endpoint' => env('ALIYUN_OSS_ENDPOINT', 'oss-cn-shanghai.aliyuncs.com'), 'is_cname' => env('ALIYUN_OSS_IS_CNAME', false), 'cdn_domain' => env('ALIYUN_OSS_CDN_DOMAIN', ''), 'ssl' => env('ALIYUN_OSS_SSL', false), 'debug' => env('ALIYUN_OSS_DEBUG', false), ], // ...]疾速应用// 查问文件夹Storage::disk('aliyun')->files($directory);Storage::disk('aliyun')->allFiles($directory);// 写入文件Storage::disk('aliyun')->put('path/to/file/file.jpg', $contents); Storage::disk('aliyun')->putFile('path/to/file/file.jpg', 'local/path/to/local_file.jpg');// 读取文件Storage::disk('aliyun')->get('path/to/file/file.jpg'); Storage::disk('aliyun')->exists('path/to/file/file.jpg'); Storage::disk('aliyun')->size('path/to/file/file.jpg'); Storage::disk('aliyun')->lastModified('path/to/file/file.jpg');// 读取文件夹Storage::disk('aliyun')->directories($directory); Storage::disk('aliyun')->allDirectories($directory); // 文件操作Storage::disk('aliyun')->copy('old/file1.jpg', 'new/file1.jpg');Storage::disk('aliyun')->move('old/file1.jpg', 'new/file1.jpg');Storage::disk('aliyun')->rename('path/to/file1.jpg', 'path/to/file2.jpg');Storage::disk('aliyun')->putRemoteFile('target/path/to/file/jacob.jpg', 'http://example.com/jacob.jpg');Storage::disk('aliyun')->url('path/to/img.jpg');Storage::disk('aliyun')->temporaryUrl('path/to/img.jpg',3600);Storage::disk('aliyun')->prepend('file.log', 'Prepended Text'); Storage::disk('aliyun')->append('file.log', 'Appended Text');Storage::disk('aliyun')->delete('file.jpg');Storage::disk('aliyun')->delete(['file1.jpg', 'file2.jpg']);// 文件夹操作Storage::disk('aliyun')->makeDirectory($directory); Storage::disk('aliyun')->deleteDirectory($directory);

March 23, 2021 · 1 min · jiezi

关于php:详解PhpSpreadsheet设置单元格

PhpSpreadsheet提供了丰盛的API接口,能够设置诸多单元格以及文档属性,包含款式、图片、日期、函数等等诸多利用,总之你想要什么样的Excel表格,PhpSpreadsheet都能做到。 在调试设置时,确保引入了正确的文件并实例化。 use PhpOfficePhpSpreadsheetSpreadsheet;$spreadsheet = new Spreadsheet();$worksheet = $spreadsheet->getActiveSheet(); 字体第1行代码将A7至B7两单元格设置为粗体字,Arial字体,10号字;第2行代码将B1单元格设置为粗体字。 $spreadsheet->getActiveSheet()->getStyle('A7:B7')->getFont()->setBold(true)->setName('Arial') ->setSize(10);;$spreadsheet->getActiveSheet()->getStyle('B1')->getFont()->setBold(true); 色彩将文字色彩设置为红色。 $spreadsheet->getActiveSheet()->getStyle('A4') ->getFont()->getColor()->setARGB(PhpOfficePhpSpreadsheetStyleColor::COLOR_RED); 图片能够将图片加载到Excel中。 $drawing = new PhpOfficePhpSpreadsheetWorksheetDrawing();$drawing->setName('Logo');$drawing->setDescription('Logo');$drawing->setPath('./images/officelogo.jpg');$drawing->setHeight(36); 列宽将A列宽度设置为30(字符)。 $spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(30); 如果须要主动计算列宽,能够这样: $spreadsheet->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); 设置默认列宽为12。 $spreadsheet->getActiveSheet()->getDefaultColumnDimension()->setWidth(12); 行高设置第10行行高为100pt。 $spreadsheet->getActiveSheet()->getRowDimension('10')->setRowHeight(100); 设置默认行高。 $spreadsheet->getActiveSheet()->getDefaultRowDimension()->setRowHeight(15); 对齐将A1单元格设置为程度居中对齐。 $styleArray = [ 'alignment' => [ 'horizontal' => PhpOfficePhpSpreadsheetStyleAlignment::HORIZONTAL_CENTER, ],];$worksheet->getStyle('A1')->applyFromArray($styleArray); 合并将A18到E22合并为一个单元格。 $spreadsheet->getActiveSheet()->mergeCells('A18:E22'); 拆分将合并后的单元格拆分。 $spreadsheet->getActiveSheet()->unmergeCells('A18:E22'); 边框将B2至G8的区域增加红色边框。 $styleArray = [ 'borders' => [ 'outline' => [ 'borderStyle' => PhpOfficePhpSpreadsheetStyleBorder::BORDER_THICK, 'color' => ['argb' => 'FFFF0000'], ], ],];$worksheet->getStyle('B2:G8')->applyFromArray($styleArray); 工作表题目设置当前工作表题目。 $spreadsheet->getActiveSheet()->setTitle('Hello'); 日期工夫设置日期格局。 $spreadsheet->getActiveSheet() ->setCellValue('D1', '2018-06-15');$spreadsheet->getActiveSheet()->getStyle('D1') ->getNumberFormat() ->setFormatCode(PhpOfficePhpSpreadsheetStyleNumberFormat::FORMAT_DATE_YYYYMMDD2); 换行应用n进行单元格内换行,相当于(ALT+"Enter")。 ...

March 23, 2021 · 1 min · jiezi

关于php:什么叫给密码加盐如何安全的为你的用户密码加盐

在面对这个网络世界的时候,明码平安总是各个公司和用户都十分关怀的一个内容,毕竟当初大家不论是休闲娱乐还是学习购物都是通过网上的帐号来进行生产的,所以咱们通常会给用户的明码进行加密。在加密的时候,常常会听到“加盐”这个词,这是什么意思呢? 咱们通常会将用户的明码进行 Hash 加密,如果不加盐,即便是两层的 md5 都有可能通过彩虹表的形式进行破译。彩虹表就是在网上收集的各种字符组合的 Hash 加密后果。而加盐,就是人为的通过一组随机字符与用户原明码的组合造成一个新的字符,从而减少破译的难度。就像做饭一样,加点盐滋味会更好。 接下来,咱们通过代码来演示一种比拟平安的加盐形式。 首先,咱们建一个简略的用户表。这个表里只有四个字段,在这里仅作为测试应用。 CREATE TABLE `zyblog_test_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '用户名', `password` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '明码', `salt` char(4) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '盐', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;而后定义两个形式,一个用来生成盐,一个用来生成加盐后的 Hash 明码。 /** * 随机生成四位字符串的salt * 也能够依据理论状况应用6位或更长的salt */function generateSalt(){ // 应用随机形式生成一个四位字符 $chars = array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9')); for ($i = 0; $i < 4; $i++) { $str .= $chars[mt_rand(0, count($chars) - 1)]; } return $str;}/** * 明码生成 * 应用两层hash,将salt加在第二层 * sha1后再加salt而后再md5 */function generateHashPassword($password, $salt){ return md5(sha1($password) . $salt);}generateSalt() 办法很简略,就是生成一个随机的四位字符的字符串,咱们应用大小写加数字的模式生成这个字符串。这就是传说中的“盐”。 ...

March 23, 2021 · 2 min · jiezi

关于php:ThinkAPI短信接口正式上线

服务概述为了更好的服务开发者和ThinkPHP生态,官网优选优质稳固的短信服务商正式推出了短信API服务,目前仅反对验证码和告诉短信,后续还会陆续开明更多的短信服务。 因为短信服务是独自布局和设计的,调用接口对立纳入了ThinkAPI服务,所以咱们对短信API接口做了统一规划,未来还会陆续接入更多的短信服务通道和短信业务,因为调用参数和返回数据等标准曾经对立,所以不会影响原有接口的应用。 接口调用(调用须知)短信发送之前,首先要实现模板和签名的申请,登录市场后点击右上角用户头像抉择“我的服务->短信服务”,在签名治理和模板治理外面申请即可,审核通过后才能够进行短信发送调用。一旦查看发现有任何违规内容发送的话,咱们将会对签名和模板进行解冻,已购买的套餐资费不退,并且保留查究相干责任的权力。申请地址GET https://api.topthink.com/sms/send 申请参数参数名称 类型 必须 形容 signId Number 是 签名id,在我的服务->短信服务->签名治理外面查看 templateId Number 是 模板id,在我的服务->短信服务->模板治理外面查看 phone String 是 要发送的国内11位手机号码 params Json 否 模板变量 应用Json对象格局 返回data参数名称 类型 阐明 id String 短信发送工作id 留神:短信发送最终是否胜利的确认是运营商异步确认的,所以须要在我的服务->短信服务->发信记录外面确认,最终的计费也是以发信记录外面的胜利次数来计费。SDK调用$client = new Client("YourAppCode");$result = $client->smsSend() ->withSignId('78') ->withTemplateId('234') ->withPhone('15687902345') ->withParams('{"code": "7865"}') ->request();dump($result); 返回后果示例: {"code": 0,"message": "发送胜利","data":{ "id": "6055df2f45e10" }} 接口费用(¥0.035/次起)目前告诉类短信和验证码短信的单次价格是¥0.035起,采纳套餐包的形式购买次数。更多接口服务ThinkAPI对立API接口服务是由官网联结合作伙伴封装的一套接口调用服务及SDK,旨在帮忙ThinkPHP开发者更不便和更低成本调用官网及第三方的提供的各类API接口及服务,从而更好的构建开发者生态。更多API接口能够参见这里。

March 23, 2021 · 1 min · jiezi

关于php:关于PHP中的请求上下文的相关知识

咱们首先来理解下什么是上下文。在咱们写文章,写句子时,都会思考一个观点或者内容的前后逻辑,转承启合,而在这个观点前后的内容就能够看成是它的上下文内容。它蕴含了语境的象征在外面,其实代码世界中的上下文也是一样的意思,自身 Context 这个单词就是环境、背景的意思。 接下来,咱们来说说申请上下文又是什么呢?比如说咱们要应用PHP来申请一个链接地址,通常咱们会应用 curl 来进行申请,然而 curl 的配置其实是比较复杂的,所以咱们在简略应用的状况下会应用 file_get_contents() 这种函数来快捷地申请链接。不过,可能很多人并不知道或者说没怎么应用过它的上下文参数。其实,应用了上下文参数之后,file_get_contents() 不仅能够提交 POST 申请,还能够定义各种申请头内容。这些货色,就是一个申请的上下文,也就是它的执行环境和背景。 首先,咱们定义一个服务端,在这里只是输入 \$_GET 和 $_POST 外面的内容。同时,咱们还打印了 $_SERVER 来看看申请头是否获取到了。 print_r($_SERVER);echo 'GET INFO', PHP_EOL;foreach ($_GET as $k => $v) { echo $k, ': ', $v, PHP_EOL;}echo PHP_EOL,PHP_EOL;echo 'POST INFO', PHP_EOL;foreach ($_POST as $k => $v) { echo $k, ': ', $v, PHP_EOL;}接下来,在咱们的测试代码中,应用 file_get_contents() 来进行 POST 提交。 $postdata = http_build_query( [ 'var1' => 'some content', 'var2' => 'doh', ]);$opts = [ 'http' => [ 'method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $postdata, ],];$context = stream_context_create($opts);$result = file_get_contents('http://localhost:8088/?a=1', false, $context);print_r($result);var_dump($http_response_header);在这里,咱们只是用到了 stream_context_create() ,就可能轻松地创立一个申请的上下文环境了。stream_context_create() 是创立上下文环境的函数,它接管的参数是一个选项数组,外面用于定义以后申请的相干选项。留神,咱们这里其实定义的是 http/https 相干的选项,它还能够定义 ftp 、 socket 等相干的申请协定选项。 ...

March 22, 2021 · 1 min · jiezi

关于php:ThinkPHP5-统计指定条件的记录数目

形容ThinkPHP5统计指定条件的记录数目 利用举例统计订单数目 解决应用“聚合查问”。参考文档 后端代码应用模型。 1.查问语句 $recordNum = \app\index\Model\Reservation::where('username','=',session('username'))->count(); 2.将查问后果付给前台 $this->assign([ 'recordNum'=>$recordNum,]);前端代码<p>A total of {$recordNum}</p> 后果 参考官网文档

March 22, 2021 · 1 min · jiezi

关于php:PHP-的生成器generator

前沿明天咱们来看看PHP5.5.0引入的生成器(generator),咱们经常疏忽了这个性能,其实这是十分有用的性能。 创立生成器生成器的创立形式很简略,因为生成器就是PHP函数,只不过要在函数中一次或屡次应用 yield 关键字。 与一般的PHP函数不同的是,生成器从不返回值,只产出值。 //一个简略的生成器function myGenerator() { yield 'value1'; yield 'value2'; yield 'value3';}下面就是一个简略的生成器,调用生成器函数时,PHP会返回一个属于 Generator 类的对象。这个对象能够应用 foreach() 函数来迭代。每次迭代,PHP会要求 Generator 实例计算并提供下一个要迭代的值。 //应用foreach() 来迭代foreach (myGenerator() as $yieldValue) { echo $yieldValue, PHP_EOL;}//输入value1value2value3如上:每一次产出一个值之后, 生成器的外部状态都会进展;向生成器申请下一个值时,外部状态又会复原。生成器的外部状态会始终在进展和复原之间切换,直到到达函数定义体的末位或遇到空的return;语句为止。 应用生成器上面咱们以一个简略的函数,用于生成一个范畴内的数值,以此阐明PHP 生成器是如何节俭内存的。 <?phpfunction makeRangeYield($length) { //$dataset = []; for ($i = 0; $i < $length; $i++) { yield $i; // $dataset[] = $i; } //return $dataset;}//应用生成器$startMemory = memory_get_usage();$t1 = microtime(true);$customRangeYield = makeRangeYield(1000000);//完结$t2 = microtime(true);$endMemory = memory_get_usage();foreach ($customRangeYield as $i) { echo $i . PHP_EOL;}//输入echo sprintf("内存应用: %f kb\n", ($endMemory - $startMemory) / 1024);echo sprintf("耗时: %f秒\n", round($t2-$t1,3));咱们做个对照比拟,大家能够把makeRangeYield() 函数外面的正文关上,和没关上做个比照 ...

March 22, 2021 · 1 min · jiezi