首页
统计
留言
Search
1
PHP中使用反射
995 阅读
2
phpstorm配置SFTP
940 阅读
3
Go语言——结构体
792 阅读
4
PhpStorm 使用 AI 代码生成工具 Codeium
779 阅读
5
关于PHP的垃圾回收机制
763 阅读
后端
PHP
Go
数据库
其他
前端
其他技术
生活杂谈
登录
Search
标签搜索
Laravel
Mysql
RPC
Redis
Liunx
PHP
CSS
ES
算法
开发工具
断点续传
反射
phpstorm
工具
防盗链
CURL
设计模式
面试
Nginx
搜索引擎
quhe.net
首页
栏目
后端
PHP
Go
数据库
其他
前端
其他技术
生活杂谈
页面
统计
留言
搜索到
57
篇与
quhe.net
的结果
2023-02-14
宝塔无法删除swap虚拟内存的问题
之前用宝塔设置了swap虚拟内存,现在不需要了(因为swap没有物理内存快),但是直接在宝塔的Liunx工具箱里无法删除。故作此记录删除Swap步骤1、查看Swap文件swapon -s2、关闭Swap文件swapoff /etc/swapfile3、rm命令删除刚才Swap盘rm -rf /etc/swapfile4、检查swap是否被删除swapon -s free -h
2023年02月14日
132 阅读
0 评论
0 点赞
2023-01-10
Typecho 文章页面自定义可编辑字段插件
关于市面上很多主题和插件会为文章或者页面新增一些额外的数据库字段,但是typecho并没有为这些字段提供手动编辑的地方。比如joe主题就会新增浏览量和点赞数这两个属性。但是typecho后台文章页面编辑页并没有这两个字段的编辑框,导致不能手动更新这两个字段,所以本插件应运而生。具体包含以下功能页面自定义字段编辑文章自定义字段编辑安装请前往github下载插件地址:https://github.com/qingfeng1024/CustomContentField将文件夹重命名为CustomContentField,然后拷贝至usr/plugins/下,最后在后台->插件处安装。演示 (给joe主题添加文章阅读量和点赞数可编辑功能)设置自定义字段 新增或者编辑文章 升级方法下载最新文件,全部覆盖即可(请先禁用插件后再升级)
2023年01月10日
276 阅读
0 评论
23 点赞
2023-01-05
理解Commonjs、AMD、CMD、ES6的区别
第一阶段:无模块化JavaScript最初的作用仅仅是验证表单,后来会添加一些动画,但是这些js代码很多在一个文件中就可以完成了,所以,我们只需要在html文件中添加一个script标签。后来,随着前端复杂度提高,为了能够提高项目代码的可读性、可扩展性等,我们的js文件逐渐多了起来,不再是一个js文件就可以解决的了,而是把每一个js文件当做一个模块。大概是下面这样:<script src="jquery.js"></script> <script src="jquery_scroller.js"></script> <script src="main.js"></script> 优点比于使用一个js文件,这种多个js文件实现最简单的模块化的思想是进步的缺点污染全局作用域。 因为每一个模块都是暴露在全局的,简单的使用,会导致全局变量命名冲突,当然,我们也可以使用命名空间的方式来解决。对于大型项目,各种js很多,开发人员必须手动解决模块和代码库的依赖关系,后期维护成本较高。依赖关系不明显,不利于维护。 比如main.js需要使用jquery,但是,从上面的文件中,我们是看不出来的,如果jquery忘记了,那么就会报错。第二阶段: CommonJS规范CommonJS就是一个JavaScript模块化的规范,该规范最初是用在服务器端的node的,前端的webpack也是对CommonJS原生支持的。根据这个规范,每一个文件就是一个模块,其内部定义的变量是属于这个模块的,不会对外暴露,也就是说不会污染全局变量。CommonJS的核心思想就是通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或者 module.exports 来导出需要暴露的接口。CommonJS模块化规范:1)通过module.exports或exports来暴露模块2)通过require来加载模块CommonJS的特点1)同步加载,一般用于node端2)一次加载,多次使用。对同一个模块而言,只会运行一次,多次使用时会从缓存中获取3)模块加载的顺序,按照它出现的顺序4)代码都运行在模块作用域,不会造成全局污染简单应用// a.js文件 var math = { add:function(a,b){ return a+b; } } module.exports = math //module是代表当前模块,通常通过module.exports来暴露模块//b.js var math = require('./a.js') //模块依赖,通过require导入模块 console.log(math.add(1,2)) //3 一个模块有多个变量// a.js var x = 5; var addX = function (value) { return value + x; }; module.exports.x = x; module.exports.addX = addX;//b.js var example = require('./a.js'); console.log(example.x); // 5 console.log(example.addX(1)); // 6 注意:当被暴露的对象是单一的值时,不能通过exports来暴露,只能通过module.exports来暴露var x = 5 module.exports.x = x //不能使用exports.x = x 优点CommonJS规范在服务器端率先完成了JavaScript的模块化,解决了依赖、全局变量污染的问题,这也是js运行在服务器端的必要条件。缺点这篇文章我们讲的主要是浏览器端js的模块化, 由于 CommonJS 是同步加载模块的,在服务器端,文件都是保存在硬盘上,所以同步加载没有问题,但是对于浏览器端,需要将文件从服务器端请求过来,那么同步加载就不适用了,所以,CommonJS是不适用于浏览器端的。第三阶段: AMD规范之前提到: CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。AMD是一种异步加载模块的方式,主要用在浏览器环境中。主要依赖于require.js库,是requireJs在推广过程中生产的对模块定义的规范。AMD模块化规范1)通过define()方法定义模块require([module], callback) 2.)通过require方法加载模块define(id, [depends], callback) 即通过define来定义一个模块,然后使用require来加载一个模块。 并且,require还支持CommonJS的模块导出方式。使用方法1)先加载require.js(从官网下载最新版本)//通过这种方式先加载requirejs <script src="js/require.js"></script> //为防止加载require.js阻塞页面,可以将其写在页面的底部,或写成以下这种形式 <script src="js/require.js" defer async="true" ></script> //async属性表明要异步加载,避免网页失去响应,IE不支持这个属性,为兼容IE,所以需要添加defer属性 2)创建一个主文件(入口文件)//创建一个main.js,我们要写的代码从这里开始 //在html里导入以下js <script src="js/require.js" data-main="js/main"></script> //data-main的作用时指出我们的入口文件在哪,require.js会第一个加载主文件 3)主文件的写法//若主模块不依赖于其他模块,则不必要使用requirejs//一般而言,主模块要依赖于其他模块,需要使用AMD的require方法来加载依赖的模块//main.js require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){// some code here}); //require第一个参数时一个数组,表示依赖的模块,第二个参数是一个回调,回调的参数表示对应的模块,这样在回调中就可以使用这些模块了 //它的回掉函数只有在所有模块都加载完成才开始执行 4.在主模块中配置模块加载的一些行为(通过require.config()方法)// main.js require.config({paths: {"jquery": "lib/jquery.min","underscore": "lib/underscore.min","backbone": "lib/backbone.min"} }); //require配置一般写在main.js入口文件的顶部 //paths属性表示要加载的文件的路径,可以写本地路径,或服务器路径 //baseUrl属性可以用来改变基目录,上面代码可用以下方式表示require.config({baseUrl: "js/lib",paths: {"jquery": "jquery.min","underscore": "underscore.min","backbone": "backbone.min"} }); 5.定义模块(通过define()方法)//a.js //通过define来定义模块, //如果该模块还依赖其他模块,则第一个参数是一个数组,表示其依赖的模块define(['package/lib'], function(lib){function foo(){lib.log('hello world!');}return {foo: foo}; }); //b.js //在其他模块使用a.jsrequire(['a'], function (a){a.foo() }); 优点适合在浏览器环境中异步加载模块。可以并行加载多个模块。缺点提高了开发成本,并且不能按需加载,而是必须提前加载所有的依赖。第四阶段:CMD规范CMD规范是阿里的玉伯提出来的,实现js库为sea.js。 它和requirejs非常类似,即一个js文件就是一个模块,但是CMD的加载方式更加优秀,是通过按需加载的方式,而不是必须在模块开始就加载所有的依赖。定义方法define(function(){require,exports, module}) require: 导入其他依赖的办法exports、导出的方法 导出的方法CMD导出的三种方式第一种使用exports导出//common.js //使用define定义模块,require、exports、module是define自带的 define(function(require, exports, module){//定义导出的方法function minus(a, b) {return a - b}// 使用exports导出exports.minus = minus }) 第二种使用module导出//common.js //使用define定义模块,require、exports、module是define自带的 define(function(require, exports, module){//定义导出的方法function minus(a, b) {return a - b}// 使用module.exports导出module.exports = {minus} }) 第三种使用return 返回//common.js //使用define定义模块,require、exports、module是define自带的 define(function(require, exports, module){//定义导出的方法function minus(a, b) {return a - b}// 使用return导出return {minus} }) 都可以用同一种方法导入let common= require('./common') // 文件相对路径 //调用减法的方法 console.log(common.minus(5,4)) //结果:1 优点同样实现了浏览器端的模块化加载。可以按需加载,依赖就近。缺点依赖SPM打包,模块的加载逻辑偏重。AMD和CMD的区别前者是对于依赖的模块提前执行,而后者是延迟执行。 前者推崇依赖前置,而后者推崇依赖就近,即只在需要用到某个模块的时候再require。 如下:// AMD define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好 a.doSomething() // 此处略去 100 行 b.doSomething() ... }); // CMD define(function(require, exports, module) {var a = require('./a') a.doSomething() // 此处略去 100 行 var b = require('./b') // 依赖可以就近书写 b.doSomething()// ... }); 第五阶段: ES6模块化之前的几种模块化方案都是前端社区自己实现的,只是得到了大家的认可和广泛使用,而ES6的模块化方案是真正的规范。 在ES6中,我们可以使用 import 关键字引入模块,通过 exprot 关键字导出模块,功能较之于前几个方案更为强大,也是我们所推崇的,但是由于ES6目前无法在浏览器中执行,所以,我们只能通过babel将不被支持的import编译为当前受到广泛支持的 require。模块化规范一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。export 命令用于规定模块的对外接口。import 命令用于输入其他模块提供的功能。两种导入导出方式第一种导入导出方式 export导出如下// common.js function minus(a,b) {return a-b } // 使用export,一定要使用{}导出,否则会报错 export {minus } 导入如下// import 后采用大括号导入,大括号中是变量名,变量名要跟导出的名称一致 // from 后跟文件文件路径 这里是相对路径 import {minus} from './common.js' //调用方法 minus(5,4) //结果:1 //另一种导入方式 意思就是全部导入 as为重命名为导入的变量重新取一个名字 import * as common from './common.js' // 调用方式common.minus(5,4) //结果:1 第二种导出方式 export default导出如下// common.js function minus(a,b) {return a-b } // 使用export default 后不用使用{} export default minus 导入如下// import 后不采用{}导入,后跟的变量名可以随意更改,想取什么取什么 // from 后跟文件文件路径 这里是相对路径 import minus from './common.js' //调用方法 minus(5,4) //结果:1 //我改为另一个名称 import common from './common.js' // 调用方式 common(5,4) //结果:1 CommonJS、AMD、CMD、ES6比较CommmonJS用于node端,是同步加载的AMD依赖于requirejs,是异步加载的,是提前加载,立即加载CMD依赖于seajs,是异步加载,延后加载,就近加载,用时加载ES6是ES2015的简称,一般通过export来暴露模块,import来导入模块
2023年01月05日
39 阅读
0 评论
0 点赞
2022-12-28
Composer忽略环境扩展依赖强制安装
今天需要安装phpstan ,但是执行composer require的时候报错了,报之前的某个composer包需要某某拓展,但是因为这是本地环境,我并不需要管其他包的情况,我只想用phpstan,因此需要强制安装,命令如下:composer install --ignore-platform-reqs composer update --ignore-platform-reqs
2022年12月28日
176 阅读
0 评论
0 点赞
2022-12-06
Laravel 最佳实践
本文翻译自 https://github.com/alexeymezenin/laravel-best-practices单一职责原则一个类和一个方法应该只有一个责任。例如:public function getFullNameAttribute(): string { if (auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified()) { return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name; } else { return $this->first_name[0] . '. ' . $this->last_name; } }更优的写法:public function getFullNameAttribute(): string { return $this->isVerifiedClient() ? $this->getFullNameLong() : $this->getFullNameShort(); } public function isVerifiedClient(): bool { return auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified(); } public function getFullNameLong(): string { return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name; } public function getFullNameShort(): string { return $this->first_name[0] . '. ' . $this->last_name; }🔝 返回目录保持控制器的简洁如果您使用的是查询生成器或原始SQL查询,请将所有与数据库相关的逻辑放入Eloquent模型或Repository类中。例如:public function index() { $clients = Client::verified() ->with(['orders' => function ($q) { $q->where('created_at', '>', Carbon::today()->subWeek()); }]) ->get(); return view('index', ['clients' => $clients]); }更优的写法:public function index() { return view('index', ['clients' => $this->client->getWithNewOrders()]); } class Client extends Model { public function getWithNewOrders() { return $this->verified() ->with(['orders' => function ($q) { $q->where('created_at', '>', Carbon::today()->subWeek()); }]) ->get(); } }🔝 返回目录使用自定义Request类来进行验证把验证规则放到 Request 类中.例子:public function store(Request $request) { $request->validate([ 'title' => 'required|unique:posts|max:255', 'body' => 'required', 'publish_at' => 'nullable|date', ]); ... }更优的写法:public function store(PostRequest $request) { ... } class PostRequest extends Request { public function rules() { return [ 'title' => 'required|unique:posts|max:255', 'body' => 'required', 'publish_at' => 'nullable|date', ]; } }🔝 返回目录业务代码要放到服务层中控制器必须遵循单一职责原则,因此最好将业务代码从控制器移动到服务层中。例子:public function store(Request $request) { if ($request->hasFile('image')) { $request->file('image')->move(public_path('images') . 'temp'); } ... }更优的写法:public function store(Request $request) { $this->articleService->handleUploadedImage($request->file('image')); ... } class ArticleService { public function handleUploadedImage($image) { if (!is_null($image)) { $image->move(public_path('images') . 'temp'); } } }🔝 返回目录DRY原则 不要重复自己尽可能重用代码,SRP可以帮助您避免重复造轮子。 此外尽量重复使用Blade模板,使用Eloquent的 scopes 方法来实现代码。例子:public function getActive() { return $this->where('verified', 1)->whereNotNull('deleted_at')->get(); } public function getArticles() { return $this->whereHas('user', function ($q) { $q->where('verified', 1)->whereNotNull('deleted_at'); })->get(); }更优的写法:public function scopeActive($q) { return $q->where('verified', 1)->whereNotNull('deleted_at'); } public function getActive() { return $this->active()->get(); } public function getArticles() { return $this->whereHas('user', function ($q) { $q->active(); })->get(); }🔝 返回目录使用ORM而不是纯sql语句,使用集合而不是数组使用Eloquent可以帮您编写可读和可维护的代码。 此外Eloquent还有非常优雅的内置工具,如软删除,事件,范围等。例子:SELECT * FROM `articles` WHERE EXISTS (SELECT * FROM `users` WHERE `articles`.`user_id` = `users`.`id` AND EXISTS (SELECT * FROM `profiles` WHERE `profiles`.`user_id` = `users`.`id`) AND `users`.`deleted_at` IS NULL) AND `verified` = '1' AND `active` = '1' ORDER BY `created_at` DESC更优的写法:Article::has('user.profile')->verified()->latest()->get();🔝 返回目录集中处理数据例子:$article = new Article; $article->title = $request->title; $article->content = $request->content; $article->verified = $request->verified; // Add category to article $article->category_id = $category->id; $article->save();更优的写法:$category->article()->create($request->validated());🔝 返回目录不要在模板中查询,尽量使用惰性加载例子 (对于100个用户,将执行101次DB查询):@foreach (User::all() as $user) {{ $user->profile->name }} @endforeach更优的写法 (对于100个用户,使用以下写法只需执行2次DB查询):$users = User::with('profile')->get(); @foreach ($users as $user) {{ $user->profile->name }} @endforeach🔝 返回目录注释你的代码,但是更优雅的做法是使用描述性的语言来编写你的代码例子:if (count((array) $builder->getQuery()->joins) > 0)加上注释:// 确定是否有任何连接 if (count((array) $builder->getQuery()->joins) > 0)更优的写法:if ($this->hasJoins())🔝 返回目录不要把 JS 和 CSS 放到 Blade 模板中,也不要把任何 HTML 代码放到 PHP 代码里例子:let article = `{{ json_encode($article) }}`;更好的写法:<input id="article" type="hidden" value='@json($article)'> Or <button class="js-fav-article" data-article='@json($article)'>{{ $article->name }}<button>在Javascript文件中加上:let article = $('#article').val();当然最好的办法还是使用专业的PHP的JS包传输数据。🔝 返回目录在代码中使用配置、语言包和常量,而不是使用硬编码例子:public function isNormal() { return $article->type === 'normal'; } return back()->with('message', 'Your article has been added!');更优的写法:public function isNormal() { return $article->type === Article::TYPE_NORMAL; } return back()->with('message', __('app.article_added'));🔝 返回目录使用社区认可的标准Laravel工具强力推荐使用内置的Laravel功能和扩展包,而不是使用第三方的扩展包和工具。如果你的项目被其他开发人员接手了,他们将不得不重新学习这些第三方工具的使用教程。此外,当您使用第三方扩展包或工具时,你很难从Laravel社区获得什么帮助。 不要让你的客户为额外的问题付钱。想要实现的功能标准工具第三方工具权限PoliciesEntrust, Sentinel 或者其他扩展包资源编译工具Laravel Mix, ViteGrunt, Gulp, 或者其他第三方包开发环境Laravel Sail, HomesteadDocker部署Laravel ForgeDeployer 或者其他解决方案自动化测试PHPUnit, MockeryPhpspec, Pest页面预览测试Laravel DuskCodeceptionDB操纵EloquentSQL, Doctrine模板BladeTwig数据操纵Laravel集合数组表单验证Request classes他第三方包,甚至在控制器中做验证权限Built-in他第三方包或者你自己解决API身份验证Laravel Passport, Laravel Sanctum第三方的JWT或者 OAuth 扩展包创建 APIBuilt-inDingo API 或者类似的扩展包创建数据库结构Migrations直接用 DB 语句创建本土化Built-in第三方包实时消息队列Laravel Echo, Pusher使用第三方包或者直接使用WebSockets创建测试数据Seeder classes, Model Factories, Faker手动创建测试数据任务调度Laravel Task Scheduler脚本和第三方包数据库MySQL, PostgreSQL, SQLite, SQL ServerMongoDB🔝 返回目录遵循laravel命名约定来源 PSR standards.另外,遵循Laravel社区认可的命名约定:对象规则更优的写法应避免的写法控制器单数ArticleControllerArticlesController路由复数articles/1article/1路由命名带点符号的蛇形命名users.show_activeusers.show-active, show-active-users模型单数UserUsershasOne或belongsTo关系单数articleCommentarticleComments, article_comment所有其他关系复数articleCommentsarticleComment, article_comments表单复数article_commentsarticle_comment, articleComments透视表按字母顺序排列模型article_useruser_article, articles_users数据表字段使用蛇形并且不要带表名meta_titleMetaTitle; article_meta_title模型参数蛇形命名$model->created_at$model->createdAt外键带有_id后缀的单数模型名称article_idArticleId, id_article, articles_id主键-idcustom_id迁移-2017_01_01_000000_create_articles_table2017_01_01_000000_articles方法驼峰命名getAllget_all资源控制器tablestoresaveArticle测试类驼峰命名testGuestCannotSeeArticletest_guest_cannot_see_article变量驼峰命名$articlesWithAuthor$articles_with_author集合描述性的, 复数的$activeUsers = User::active()->get()$active, $data对象描述性的, 单数的$activeUser = User::active()->first()$users, $obj配置和语言文件索引蛇形命名articles_enabledArticlesEnabled; articles-enabled视图短横线命名show-filtered.blade.phpshowFiltered.blade.php, show_filtered.blade.php配置蛇形命名google_calendar.phpgoogleCalendar.php, google-calendar.php内容 (interface)形容词或名词AuthenticationInterfaceAuthenticatable, IAuthenticationTrait使用形容词NotifiableNotificationTraitTrait (PSR)adjectiveNotifiableTraitNotificationEnumsingularUserTypeUserTypes, UserTypeEnumFormRequestsingularUpdateUserRequestUpdateUserFormRequest, UserFormRequest, UserRequestSeedersingularUserSeederUsersSeeder🔝 返回目录尽可能使用简短且可读性更好的语法例子:$request->session()->get('cart'); $request->input('name');更优的写法:session('cart'); $request->name;更多示例:常规写法更优雅的写法Session::get('cart')session('cart')$request->session()->get('cart')session('cart')Session::put('cart', $data)session(['cart' => $data])$request->input('name'), Request::get('name')$request->name, request('name')return Redirect::back()return back()is_null($object->relation) ? null : $object->relation->idoptional($object->relation)->idreturn view('index')->with('title', $title)->with('client', $client)return view('index', compact('title', 'client'))$request->has('value') ? $request->value : 'default';$request->get('value', 'default')Carbon::now(), Carbon::today()now(), today()App::make('Class')app('Class')->where('column', '=', 1)->where('column', 1)->orderBy('created_at', 'desc')->latest()->orderBy('age', 'desc')->latest('age')->orderBy('created_at', 'asc')->oldest()->select('id', 'name')->get()->get(['id', 'name'])->first()->name->value('name')🔝 返回目录使用IOC容器来创建实例 而不是直接new一个实例创建新的类会让类之间的更加耦合,使得测试越发复杂。请改用IoC容器或注入来实现。例子:$user = new User; $user->create($request->validated());更优的写法:public function __construct(User $user) { $this->user = $user; } ... $this->user->create($request->validated());🔝 返回目录避免直接从 .env 文件里获取数据将数据传递给配置文件,然后使用config()帮助函数来调用数据例子:$apiKey = env('API_KEY');更优的写法:// config/api.php 'key' => env('API_KEY'), // Use the data $apiKey = config('api.key');🔝 返回目录使用标准格式来存储日期,用访问器和修改器来修改日期格式例子:{{ Carbon::createFromFormat('Y-d-m H-i', $object->ordered_at)->toDateString() }} {{ Carbon::createFromFormat('Y-d-m H-i', $object->ordered_at)->format('m-d') }}更优的写法:// Model protected $casts = [ 'ordered_at' => 'datetime', ]; public function getSomeDateAttribute($date) { return $date->format('m-d'); } // View {{ $object->ordered_at->toDateString() }} {{ $object->ordered_at->some_date }}🔝 返回目录其他的一些好建议永远不要在路由文件中放任何的逻辑代码。尽量不要在Blade模板中写原始 PHP 代码。🔝 返回目录
2022年12月06日
78 阅读
0 评论
1 点赞
1
2
3
...
12