首页
关于
Search
1
2022最新WPS政府/教育版合集
3,282 阅读
2
欢迎使用 Typecho
3,100 阅读
3
thinkphp 做301重定向跳转
2,550 阅读
4
IDE 注册教程
2,382 阅读
5
nginx反向代理设置泛目录解析
2,372 阅读
源码
教程
HTML
JAVASCRIPT
PHP
MYSQL
系统
LINUX
WINDOWS
填坑
工具
登录
/
注册
Search
标签搜索
系统工具
内网穿透
PHPDesktop
TaurusCoders
累计撰写
52
篇文章
累计收到
1
条评论
首页
栏目
源码
教程
HTML
JAVASCRIPT
PHP
MYSQL
系统
LINUX
WINDOWS
填坑
工具
页面
关于
搜索到
27
篇与
PHP
的结果
2020-07-23
ThinkPHP项目安全配置解决方案
前言: ThinkPHP MVC框架越来被开发者接受,众多的开发者选择了这个框架,也有很多的优秀项目使用的ThinkPHP框架。最近整理了一下ThinkPHP项目的一些安全配置。可能并不适用全部项目,大家可以适当的使用如下的安全配置。前置知识: web容器和各类组件的版本,这里使用的LNMP 的架构:Nginx1.19 Mysql 5.6 PHP7.4 Centos8.2,这里推荐是PHP的版本7.4一、ThinkPHP常见的被入侵方式ThinkPHP RCE案例分享:在某些ThinkPhp版本中只有开启了Debug才会导致命令执行的出现,例如拿ThinkPhp5.1.14举例获取网站的绝对路径等等敏感信息开启了Debug,执行exp2、通过log日志获取网站权限智宇发卡网举例此发卡网是可以访问runtime目录的,给大家看看目录他入口文件和runtime目录在同一个目录里面,他也没设置其他东西,所以可以直接访问runtime目录然后根据runtime目录的日志存储的格式runtime/log/年份月份/日.log来存储的,所以得到runtime/log/202007/22.log来获取网站日志,在遍历日志的时候在18号发现了管理员账号密码通过后台登录账号密码,通过代码审计发现存在一个比较鸡肋的Rce利用条件可以开启日志,或者支持into outfileGetShell1在审计的时候发现了数据库可以指定其他文件进行数据库恢复(恢复数据相当于执行SQL语句),下面是利用步骤1.下载网站备份文件2.修改SQL语句,添加漏洞利用代码3.在文件存储处添加.sql的后缀,然后在上传文件的地方上传.sql文件4.然后在恢复数据的时候指定这个.sql文件达到写shell的目的备份数据库下载后修改备份文件并修改文件漏洞利用代码(路径自己设置,后面的注释不可以删除)SET GLOBAL general_log = 'ON';SET GLOBAL general_log_file = 'C:\\wwwroot\\192.168.2.128\\wwwa.php';select '<?php eval($_POST[0]);?>';SET GLOBAL general_log_file = 'C:\\Temp\\a.txt';文件存储添加.sql后缀上传刚刚修改的.sql文件,例如此处在点击上传图片的时候,先抓包,添加一个.sql后缀的文件然后上传刚刚修改的sql文件,可以得到上传的路径恢复数据GetShell恢复成功后访问网站的wwwa.php,密码是0另外一个命令执行漏由于thinkphp框架开发,他存在Thinkphp的Rce漏洞,但是由于路由设置的原因,在进行Rce的时候他每次请求都会带有路由的子域名参数,例如可以看见他会带着当前的域名或者ip先传入该参数进行执行,所以导致很多函数无法使用,所以大部分函数无法使用,不过还是找到了system这个函数进行命令执行♡♡♡♡♡♡♡♡♡♡二、思考如何防御???2.1 配置防御log目录泄露 runtime目录下的文件是ThinkPhp运行时产生的文件,里面包括了日志,缓存,等等的信息,如果可以访问会导致如下危害:可以看见管理员和其他用户的登录日志,会记录明文账号和密码在某些版本可以通过缓存来进行代码执行修复方法伪静态中添加location ~* (runtime/|Application/){ return 403;}2.2 ThinkPHP安全入口限制案例https://www.bt.cn/bbs/thread-52183-1-1.html修复方法location ~ ^/index.php{ include enable-php-70.conf; }location ~* \.(php){ deny all;}2.3 使用Nginx防火墙默认拦截日志防御和ThinkPHP RCE攻击如下:发起ThinkPHP RCE 请求被拦截2.3 使用堡塔PHP安全防护防跨站的危害性作用当服务器中有多个网站时这个设置就非常有用,如果服务器中的某个网站被攻击了,可以避免其他网站也沦陷案例例如,如下服务器当该服务器的的192.168.2.128站点被入侵的时候,如果没有设置防跨站他是可以访问其他的网站的内容的如果设置了防跨站的话,是可以防止这种事情发生的以看到访问错误,不过单纯使用open_basedir是有被绕过的风险,上传一个带有如下内容的php文件<?php $a='chdir';$b='ini_set';mkdir('mi1k7ea');$a('mi1k7ea');$b('open_basedir','..');$a('..');$a('..');$a('..');$a('..');$b('open_basedir','/');echo file_get_contents('/etc/passwd');访问该php文件,可以成功获取到/etc/passwd文件里面的内容安装堡塔php安全防护后,进行设置具体使用说明https://www.bt.cn/bbs/forum.php?mod=viewthread&tid=49256&highlight=%E5%A0%A1%E5%A1%94php开启堡塔php安全防护后,已经成功拦截2.4 使用企业级防篡改thinkphp中默认是两个目录是存在写入和删除的。一个是缓存目录cache 一个是上传目录upload(并不是全部都是通用的根据项目自身去写规则)。这里我使用的是智宇发卡的程序来做的测试智宇发卡这个程序就两个目录需要写入和删除。一个是runtime 目录和/static/upload 这两个目录需要写入。那么先把企业级防篡改的保护目录全部清空只留下这两个目录即可。测试一下效果<?php file_put_contents('aaa.php','aaa');测试为:写入不了文件2.5 webshell防御--OpenRasp webshell防御的话。这里使用的百度的Openrasp具体的使用教程https://www.bt.cn/bbs/thread-49371-1-1.html直接安装即可测试效果如下:使用方法,在该网站放了一个webshell执行php代码,被拦截成功被拦截三、ThinkPHP其他安全设置3.1 关闭debug在线上环境,开启Debug模式会导致如下危害泄露网站敏感信息在Thinkphp5.0.24版本开启Debug模式的时候,在特定情况下会导致mysql数据库账号密码泄露在某些Thinkphp版本要开启Debug模式才会导致代码执行漏洞一般配置文件项目地址中的/application/config.php 文件中3.2 设置日志输出日志文件他存储在runtime/log/下面,上面也有讲解案例和危害,如果我们可以输出日志的内容就可以避免一些攻击,一般的日志输出会输出大部分的敏感信息,就想上面一样,登录的账号密码都会被记录,如果我们只输出错误的信息,就可以避免上面的敏感信息泄露出去修复方法只输出错误的日志或者直接关闭日志的输出四、其他安全设置1、服务器密码和网站密码全部分开2、数据库密码和网站密码。和FTP密码全部独立3、密码建议为md5的随机强密码这样减少被爆破的风险五、总结Thinkphp的MVC的单一入口的解决方案可以解决掉很多的一些安全问题。但是还是需要配合一些安全产品来更多的安全风险后续我们会持续更新更多的项目的安全策略。敬请期待如果此文章对你有帮助请转发至朋友圈中让更多人能学习
2020年07月23日
1,040 阅读
0 评论
0 点赞
2020-07-18
有关宝塔安装OpenRASP后网站有提提示/tmp/:/proc/出错
这段时间发现网站有时会提示图片的错误,但是一刷新面页,错误就没有了。scandir(:open basedir restriction in effect File(/opt/rasp php73/logs/plugin/plugin. log. 2020-06-18)is not within the allowed path(s) (/xxxx/xxxx/www_mxlog_com/:/tmp/:/proc/) 这样的情况下,是因为网站下有.user.ini文件,所以要比较注意open_base的设置,比如宝塔部署的话,是每个网站独立的open_base,一般是在网站根目录下的.user.ini,FTP里是看不到这个文件的,要做一些设置才行,所以需要在SSH远程登陆,后用ls -a才能看到,由于限制了权限需要用chattr解除权限。 chattr -i .user.ini vi .user.ini open_basedir=/www网站目录路径/:/tmp/:/proc/ 在后面追加 :/opt/rasp_php73/logs 要这里要特别说明一下哦,,如果是多版本的话,/opt/rsap/logs这里要看回你自己网站的设定的哦。。不过,最好要检查 logs 目录是否有写权限 如果没有权限,可以执行 chmod 777 /opt/rasp/logs 增加权限 检查 SELinux 是否开启,可以执行 setenforce 0 关闭 检查 php error_log 是否有 OpenRASP 相关的错误日志有没有配置 如果没有配置过,请在 php.ini 里开启,e.g error_log = /tmp/php_error.log 检查 php open_basedir 是否关闭(或者将 /opt/rasp 加入到允许的路径里) 我们的 alarm 日志使用 PHP stream 写入,会受到这个配置的影响,e.g PHP Warning: scandir(): open_basedir restriction in effect. File(/www/rasp/logs/alarm/...... 本文来自:小新Blog,原地址:https://mxlog.com/fenxiang/1543.html
2020年07月18日
1,115 阅读
0 评论
0 点赞
2020-07-05
thinkphp 做301重定向跳转
ThinkPHP怎么配置url的301跳转,永久转移很简单,只需要在目录下的.htaccess文件里面添加 第一种情况,是将整个网站所有地址都做301跳转RewriteCond %{http_host} ^luowebs.com [NC]RewriteRule ^(.*)$ http://www.luowebs.com/$1 [L,R=301]第二种情况,是网站特定的几个链接做301跳转#以前的页面链接是:A http://www.wolfcode.cn/newsWeb/newsDetail/1246.html#现在的页面链接是:B http://www.wolfcode.cn/article/index/id/526#我们要由A重定向到B;那么我们的规则就是:RewriteRule (.*)/article/index/id/526 http://www.wolfcode.cn/newsWeb/newsDetail/1246.html [L,R=301]301官方解释:(永久移动)请求的网页已永久移动到新位置。服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。您应使用此代码告诉 Googlebot 某个网页或网站已永久移动到新位置。注意:不要在控制器用header去跳转if($_SERVER['SERVER_NAME']=='luowebs.com'){ header('Location: http://www.luowebs.com'.$_SERVER['REQUEST_URI']); exit(); }上面代码使用header做的跳转,这里同学们需要注意以下了,这代码这么写虽然能跳转,但是你去检测会发现这是302跳转不是301跳转哦,大家千万要注意啦!在tp5.0中可以直接使用redirect来做301跳转://重定向到指定的URL地址 并且使用301$this->redirect('http://www.luowebs.cn',301);//重定向到指定的URL地址 并且使用302$this->redirect('http://www.luowebs.com',302);手册地址:https://www.kancloud.cn/manual/thinkphp5/118051
2020年07月05日
2,550 阅读
0 评论
0 点赞
2020-06-17
nginx反向代理设置泛目录解析
二级目录出租,用nginx反向代理设置实例:打开站点的nginx配置文件加入下面代码location /二级目录名称(英文)/ { proxy_pass http://47.105.130.185/二级目录名称(同上)/; proxy_set_header Host $host;#向代理目标主机目录发送主机名称 proxy_set_header X-Real-IP $remote_addr;#向代理目标主机发送客户端真实ip proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }需要注意的是如果出租目录站点没备案,而代理目标主机是备案主机,那么proxy_set_header Host $host;这句话必须去掉,否则会被备案页面拦截。
2020年06月17日
2,372 阅读
0 评论
0 点赞
2020-06-16
搜索引擎智能提示API
各大搜索引擎智能提示API(jsonp实现跨域自动补全建议)更新时间为2019年2月28日,亲测可用,去除不可用的接口,新增一些接口。谷歌(Google)谷歌API接口地址1:http://clients1.google.com/complete/search?hl=zh&output=toolbar&q=前端谷歌API接口地址2:http://suggestqueries.google.com/complete/search?output=toolbar&hl=zh&q=前端谷歌API接口地址2:http://suggestqueries.google.com/complete/search?client=youtube&q=前端&jsonp=window.google.ac.h 会直接下载。返回结果:百度(Baidu)百度API接口地址1:http://suggestion.baidu.com/su?wd=前端也有人会这样写:http://suggestion.baidu.com/su?wd=前端&p=3&cb=window.bdsug.sug返回结果:window.bdsug.sug({q:"前端",p:false,s:["前端工程师","前端学习路线","前端开发","前端框架","前端面试题","前端面试","前端面试题及答案","前端开发工具","前端ui框架","前端性能优化"]});搜狗(Sougou)搜狗API接口地址1:http://w.sugg.sogou.com/sugg/ajaj_json.jsp?key=前端&type=web返回结果:window.sogou.sug(["前端",["前端开发","前端框架","前端面试题","前端工程师","前端培训","前端和后端","前端招聘","前端开发培训","前端开发工具","前端和后端的区别"],["0;0;0;0","1;0;0;0","2;0;0;0","3;0;0;0","4;0;0;0","5;0;0;0","6;0;0;0","7;0;0;0","8;0;0;0","9;0;0;0"],["","","","","","","","","",""],["0"],"","suglabId_1"],-1);360搜索(so)360搜索API接口地址:https://sug.so.360.cn/suggest?callback=suggest_so&word=qianduan 测试只支持英文,不过可以支持拼音。360搜索API接口地址:https://sug.so.360.cn/suggest?encodein=utf-8&encodeout=utf-8&format=json&word=前端&callback=window.so.sug 测试支持汉字。返回结果:suggest_so({q:"qianduan",p:true,s:["前端","前端培训机构","前端开发需要学什么","前段","钱端","前端开发","前端工程师","前端框架","嵌段","前端面试题"]});必应(Bing)必应搜索API接口地址:https://api.bing.com/qsonhs.aspx?type=cb&q=前端 返回的是 json 格式。必应搜索API接口地址:https://api.bing.com/qsonhs.aspx?type=cb&q=前端&cb=window.bing.sug返回结果:if(typeof window.bing.sug == 'function') window.bing.sug({"AS":{"Query":"前端","FullResults":1,"Results":[{"Type":"AS","Suggests":[{"Txt":"前端切版","Type":"AS","Sk":"","HCS":0.0355},{"Txt":"前端工程師","Type":"AS","Sk":"AS1"},{"Txt":"前端工程師 薪水","Type":"AS","Sk":"AS2"},{"Txt":"前端科技股份有限公司","Type":"AS","Sk":"AS3"},{"Txt":"前端 英文","Type":"AS","Sk":"AS4"},{"Txt":"前端 框架","Type":"AS","Sk":"AS5"},{"Txt":"前端工程師 ptt","Type":"AS","Sk":"AS6"},{"Txt":"前端開發 windows","Type":"AS","Sk":"AS7"}]}]}}/* pageview_candidate */);淘宝(Taobao)淘宝搜索API接口地址:https://suggest.taobao.com/sug?code=utf-8&q=前端&callback=window.taobao.sug返回结果:KISSY.Suggest.callback({"result":[["前端播放器","10122"],["前端视频教程 2018","3080"],["前端开发","18144"],["前端开发书籍","13391"],["前端净水器","63525"],["前端开发视频","8932"],["前端过滤器","69083"],["前端耳机","40712"],["前端视频","3535"],["前端教程","22974"]]})一淘(etao)一淘搜索API接口地址:https://suggest.taobao.com/sug?area=etao&code=utf-8&callback=KISSY.Suggest.callback&q=前端返回结果:KISSY.Suggest.callback({"result":[["前端播放器","10122"],["前端视频教程 2018","3080"],["前端开发","18144"],["前端开发书籍","13391"],["前端净水器","63525"],["前端开发视频","8932"],["前端过滤器","69083"],["前端耳机","40712"],["前端视频","3535"],["前端教程","22974"]]})京东(JD)京东查价接口:http://p.3.cn/prices/mgets?skuIds=J_100002308919&type=1 红色部分为商品ID返回结果:[{"id":"J_100002308919","m":"6000.00","op":"3299.00","p":"3299.00"}]搜索建议使用方式:以百度为例,API返回的是JSONP数据,JSONP是跨域访问的一种方式。由于服务器返回的JavaScript代码可以直接引用,通过回调函数的方式就可以间接的获取服务器的数据。下面是一个回调搜索建议的例子,window.baidu.sug 返回的是一个json对象<script type="text/javascript"> window.onload = function() { //组装查询地址 var sugurl = "http://suggestion.baidu.com/su?wd=#content#&cb=window.baidu.sug"; var content = "关键字"; sugurl = sugurl.replace("#content#", content); //定义回调函数 window.baidu = { sug: function(json) { console.log(json) } } //动态添加JS脚本 var script = document.createElement("script"); script.src = sugurl; document.getElementsByTagName("head")[0].appendChild(script); }</script>控制台打印的结果:如果要将结果保存在一个字符串数组中,只需要 var arr = json.s 即可。
2020年06月16日
1,876 阅读
0 评论
0 点赞
2020-05-02
Composer 国内加速,修改镜像源
为什么慢由于默认情况下执行 composer 各种命令是去国外的 composer 官方镜像源获取需要安装的具体软件信息,所以在不使用代理、不翻墙的情况下,从国内访问国外服务器的速度相对比较慢如何修改镜像源可以使用阿里巴巴提供的 Composer 全量镜像 https://mirrors.aliyun.com/composer/a). 配置只在当前项目生效composer config repo.packagist composer https://mirrors.aliyun.com/composer/# 取消当前项目配置composer config --unset repos.packagistb). 配置全局生效composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/# 取消全局配置composer config -g --unset repos.packagistc). 使用第三方软件快速修改、切换 composer 镜像源crm composer registry manager安装 crmcomposer global require slince/composer-registry-manager列出可用的所有镜像源,前面带 * 代表当前使用的镜像composer repo:ls -- --------------- ------------------------------------------------ composer https://packagist.org phpcomposer https://packagist.phpcomposer.com aliyun https://mirrors.aliyun.com/composer tencent https://mirrors.cloud.tencent.com/composer huawei https://mirrors.huaweicloud.com/repository/php laravel-china https://packagist.laravel-china.org cnpkg https://php.cnpkg.org sjtug https://packagist.mirrors.sjtug.sjtu.edu.cn -- --------------- ------------------------------------------------使用 aliyun 镜像源composer repo:use aliyun# 执行成功之后会输出类似以下信息[OK] Use the repository [aliyun] success再次执行 composer repo:ls 命令,看到前面带 * 的就是当前使用的镜像composer repo:ls# 可以看到 aliyun 前面有一个 * 号,代表当前使用的是 aliyun 的源--- --------------- ------------------------------------------------ composer https://packagist.org phpcomposer https://packagist.phpcomposer.com * aliyun https://mirrors.aliyun.com/composer tencent https://mirrors.cloud.tencent.com/composer huawei https://mirrors.huaweicloud.com/repository/php laravel-china https://packagist.laravel-china.org cnpkg https://php.cnpkg.org sjtug https://packagist.mirrors.sjtug.sjtu.edu.cn --- --------------- ------------------------------------------------更多用法查看 crm GitHub
2020年05月02日
1,231 阅读
0 评论
0 点赞
2020-04-12
软件开发语义化版本 2.0.0
摘要版本格式:主版本号.次版本号.修订号,版本号递增规则如下:主版本号:当你做了不兼容的 API 修改,次版本号:当你做了向下兼容的功能性新增,修订号:当你做了向下兼容的问题修正。先行版本号及版本编译元数据可以加到“主版本号.次版本号.修订号”的后面,作为延伸。简介在软件管理的领域里存在着被称作“依赖地狱”的死亡之谷,系统规模越大,加入的包越多,你就越有可能在未来的某一天发现自己已深陷绝望之中。在依赖高的系统中发布新版本包可能很快会成为噩梦。如果依赖关系过高,可能面临版本控制被锁死的风险(必须对每一个依赖包改版才能完成某次升级)。而如果依赖关系过于松散,又将无法避免版本的混乱(假设兼容于未来的多个版本已超出了合理数量)。当你专案的进展因为版本依赖被锁死或版本混乱变得不够简便和可靠,就意味着你正处于依赖地狱之中。作为这个问题的解决方案之一,我提议用一组简单的规则及条件来约束版本号的配置和增长。这些规则是根据(但不局限于)已经被各种封闭、开放源码软件所广泛使用的惯例所设计。为了让这套理论运作,你必须先有定义好的公共 API 。这可以透过文件定义或代码强制要求来实现。无论如何,这套 API 的清楚明了是十分重要的。一旦你定义了公共 API,你就可以透过修改相应的版本号来向大家说明你的修改。考虑使用这样的版本号格式:X.Y.Z (主版本号.次版本号.修订号)修复问题但不影响API 时,递增修订号;API 保持向下兼容的新增及修改时,递增次版本号;进行不向下兼容的修改时,递增主版本号。我称这套系统为“语义化的版本控制”,在这套约定下,版本号及其更新方式包含了相邻版本间的底层代码和修改内容的信息。语义化版本控制规范(SemVer)以下关键词 MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、SHOULD NOT、 RECOMMENDED、MAY、OPTIONAL 依照 RFC 2119 的叙述解读。(译注:为了保持语句顺畅, 以下文件遇到的关键词将依照整句语义进行翻译,在此先不进行个别翻译。)使用语义化版本控制的软件必须(MUST)定义公共 API。该 API 可以在代码中被定义或出现于严谨的文件内。无论何种形式都应该力求精确且完整。标准的版本号必须(MUST)采用 X.Y.Z 的格式,其中 X、Y 和 Z 为非负的整数,且禁止(MUST NOT)在数字前方补零。X 是主版本号、Y 是次版本号、而 Z 为修订号。每个元素必须(MUST)以数值来递增。例如:1.9.1 -> 1.10.0 -> 1.11.0。标记版本号的软件发行后,禁止(MUST NOT)改变该版本软件的内容。任何修改都必须(MUST)以新版本发行。主版本号为零(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变。这样的公共 API 不应该被视为稳定版。1.0.0 的版本号用于界定公共 API 的形成。这一版本之后所有的版本号更新都基于公共 API 及其修改内容。修订号 Z(x.y.Z | x > 0)必须(MUST)在只做了向下兼容的修正时才递增。这里的修正指的是针对不正确结果而进行的内部修改。次版本号 Y(x.Y.z | x > 0)必须(MUST)在有向下兼容的新功能出现时递增。在任何公共 API 的功能被标记为弃用时也必须(MUST)递增。也可以(MAY)在内部程序有大量新功能或改进被加入时递增,其中可以(MAY)包括修订级别的改变。每当次版本号递增时,修订号必须(MUST)归零。主版本号 X(X.y.z | X > 0)必须(MUST)在有任何不兼容的修改被加入公共 API 时递增。其中可以(MAY)包括次版本号及修订级别的改变。每当主版本号递增时,次版本号和修订号必须(MUST)归零。先行版本号可以(MAY)被标注在修订版之后,先加上一个连接号再加上一连串以句点分隔的标识符来修饰。标识符必须(MUST)由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止(MUST NOT)留白。数字型的标识符禁止(MUST NOT)在前方补零。先行版的优先级低于相关联的标准版本。被标上先行版本号则表示这个版本并非稳定而且可能无法满足预期的兼容性需求。范例:1.0.0-alpha、1.0.0-alpha.1、1.0.0-0.3.7、1.0.0-x.7.z.92。版本编译元数据可以(MAY)被标注在修订版或先行版本号之后,先加上一个加号再加上一连串以句点分隔的标识符来修饰。标识符必须(MUST)由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止(MUST NOT)留白。当判断版本的优先层级时,版本编译元数据可(SHOULD)被忽略。因此当两个版本只有在版本编译元数据有差别时,属于相同的优先层级。范例:1.0.0-alpha+001、1.0.0+20130313144700、1.0.0-beta+exp.sha.5114f85。版本的优先层级指的是不同版本在排序时如何比较。判断优先层级时,必须(MUST)把版本依序拆分为主版本号、次版本号、修订号及先行版本号后进行比较(版本编译元数据不在这份比较的列表中)。由左到右依序比较每个标识符,第一个差异值用来决定优先层级:主版本号、次版本号及修订号以数值比较,例如:1.0.0 < 2.0.0 < 2.1.0 < 2.1.1。当主版本号、次版本号及修订号都相同时,改以优先层级比较低的先行版本号决定。例如:1.0.0-alpha < 1.0.0。有相同主版本号、次版本号及修订号的两个先行版本号,其优先层级必须(MUST)透过由左到右的每个被句点分隔的标识符来比较,直到找到一个差异值后决定:只有数字的标识符以数值高低比较,有字母或连接号时则逐字以 ASCII 的排序来比较。数字的标识符比非数字的标识符优先层级低。若开头的标识符都相同时,栏位比较多的先行版本号优先层级比较高。范例:1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0。为什么要使用语义化的版本控制?这并不是一个新的或者革命性的想法。实际上,你可能已经在做一些近似的事情了。问题在于只是“近似”还不够。如果没有某个正式的规范可循,版本号对于依赖的管理并无实质意义。将上述的想法命名并给予清楚的定义,让你对软件使用者传达意向变得容易。一旦这些意向变得清楚,弹性(但又不会太弹性)的依赖规范就能达成。举个简单的例子就可以展示语义化的版本控制如何让依赖地狱成为过去。假设有个名为“救火车”的函式库,它需要另一个名为“梯子”并已经有使用语义化版本控制的包。当救火车创建时,梯子的版本号为 3.1.0。因为救火车使用了一些版本 3.1.0 所新增的功能, 你可以放心地指定依赖于梯子的版本号大等于 3.1.0 但小于 4.0.0。这样,当梯子版本 3.1.1 和 3.2.0 发布时,你可以将直接它们纳入你的包管理系统,因为它们能与原有依赖的软件兼容。作为一位负责任的开发者,你理当确保每次包升级的运作与版本号的表述一致。现实世界是复杂的,我们除了提高警觉外能做的不多。你所能做的就是让语义化的版本控制为你提供一个健全的方式来发行以及升级包,而无需推出新的依赖包,节省你的时间及烦恼。如果你对此认同,希望立即开始使用语义化版本控制,你只需声明你的函式库正在使用它并遵循这些规则就可以了。请在你的 README 文件中保留此页连结,让别人也知道这些规则并从中受益。FAQ在 0.y.z 初始开发阶段,我该如何进行版本控制?最简单的做法是以 0.1.0 作为你的初始化开发版本,并在后续的每次发行时递增次版本号。如何判断发布 1.0.0 版本的时机?当你的软件被用于正式环境,它应该已经达到了 1.0.0 版。如果你已经有个稳定的 API 被使用者依赖,也会是 1.0.0 版。如果你很担心向下兼容的问题,也应该算是 1.0.0 版了。这不会阻碍快速开发和迭代吗?主版本号为零的时候就是为了做快速开发。如果你每天都在改变 API,那么你应该仍在主版本号为零的阶段(0.y.z),或是正在下个主版本的独立开发分支中。对于公共 API,若即使是最小但不向下兼容的改变都需要产生新的主版本号,岂不是很快就达到 42.0.0 版?这是开发的责任感和前瞻性的问题。不兼容的改变不应该轻易被加入到有许多依赖代码的软件中。升级所付出的代价可能是巨大的。要递增主版本号来发行不兼容的改版,意味着你必须为这些改变所带来的影响深思熟虑,并且评估所涉及的成本及效益比。为整个公共 API 写文件太费事了!为供他人使用的软件编写适当的文件,是你作为一名专业开发者应尽的职责。保持专案高效一个非常重要的部份是掌控软件的复杂度,如果没有人知道如何使用你的软件或不知道哪些函数的调用是可靠的,要掌控复杂度会是困难的。长远来看,使用语义化版本控制以及对于公共 API 有良好规范的坚持,可以让每个人及每件事都运行顺畅。万一不小心把一个不兼容的改版当成了次版本号发行了该怎么办?一旦发现自己破坏了语义化版本控制的规范,就要修正这个问题,并发行一个新的次版本号来更正这个问题并且恢复向下兼容。即使是这种情况,也不能去修改已发行的版本。可以的话,将有问题的版本号记录到文件中,告诉使用者问题所在,让他们能够意识到这是有问题的版本。如果我更新了自己的依赖但没有改变公共 API 该怎么办?由于没有影响到公共 API,这可以被认定是兼容的。若某个软件和你的包有共同依赖,则它会有自己的依赖规范,作者也会告知可能的冲突。要判断改版是属于修订等级或是次版等级,是依据你更新的依赖关系是为了修复问题或是加入新功能。对于后者,我经常会预期伴随着更多的代码,这显然会是一个次版本号级别的递增。如果我变更了公共 API 但无意中未遵循版本号的改动怎么办呢?(意即在修订等级的发布中,误将重大且不兼容的改变加到代码之中)自行做最佳的判断。如果你有庞大的使用者群在依照公共 API 的意图而变更行为后会大受影响,那么最好做一次主版本的发布,即使严格来说这个修复仅是修订等级的发布。记住, 语义化的版本控制就是透过版本号的改变来传达意义。若这些改变对你的使用者是重要的,那就透过版本号来向他们说明。我该如何处理即将弃用的功能?弃用现存的功能是软件开发中的家常便饭,也通常是向前发展所必须的。当你弃用部份公共 API 时,你应该做两件事:(1)更新你的文件让使用者知道这个改变,(2)在适当的时机将弃用的功能透过新的次版本号发布。在新的主版本完全移除弃用功能前,至少要有一个次版本包含这个弃用信息,这样使用者才能平顺地转移到新版 API。语义化版本对于版本的字串长度是否有限制呢?没有,请自行做适当的判断。举例来说,长到 255 个字元的版本已过度夸张。再者,特定的系统对于字串长度可能会有他们自己的限制。
2020年04月12日
1,098 阅读
0 评论
0 点赞
2020-04-10
使用PHP和PHP Desktop创建第一个桌面应用程序
嗨,欢迎来到这个特别的教程。在这里,我将向您展示如何在PHP Desktop的帮助下使用PHP,CSS,HTML和JavaScript创建基于Web的桌面应用程序 。实际上,PHP Desktop是一个简单易用的解决方案,可用于创建功能强大且复杂的桌面应用程序。什么是PHP桌面?根据官方定义,PHP Desktop是Czarek Tomczak在2012年创建的一个开源项目,旨在提供一种使用Web技术(例如PHP,HTML5,JavaScript和SQLite)开发本机桌面GUI应用程序的方法。-来源:PHP桌面官方页面提醒您,创建Web应用程序时惯用的开发工作流程保持不变。将现有网站转换为桌面应用程序的步骤基本上是复制和粘贴的问题。PHPDesktop是一个通用容器,只会吞噬您的项目。这样,您可以轻松地将现有网站转换为桌面应用程序,而无需进行任何修改。当您下载 PHP Desktop时,将具有一些文件和文件夹集。其中,您将有一个名为的文件夹,您将www在其中粘贴整个应用程序。对于那些使用过WampServer,Xamp或EasyPhp的用户来说,理解这一概念将不是问题。使用这些本地服务器时,通常将项目创建到名为www,htdocs或 的特定文件夹中localweb。它从一台服务器到另一台服务器有所不同,但是概念保持不变。该特定文件夹可帮助您的网络服务器知道从何处运行您的应用程序(网站)。PHP Desktop的工作方式相同。不同之处在于,PHP桌面不需要任何特定的安装。它是所有这些本地服务器具有的多合一便携式集合,它可以完成WampServer或Xamp以及同一家族中的其他服务器所能做的一切。PHP Desktop附带了一个.exe文件。每当您运行时.exe,它将进入该www文件夹并运行您的索引文件。我将在本教程的后面部分解释这个过程。一些故事回顾2005年,我记得曾经有人要求我提供商店管理应用程序。原理很简单,经理应该能够添加新库存和所有销售记录。最后,所有者应能够获得每天的干净报告,并在可能的情况下可以选择日期或期限。我告诉客户我可以做到,但是它将基于Web,因此它将使用他们的浏览器来工作。即使我知道他们不了解有什么不同,这也使我有必要尝试向他们明确说明。幸运的是,客户以这种方式接受了它。我使用EasyPhp制作了该应用程序。因此,要运行该应用程序,我必须在客户端的PC上安装EasyPhp。你可以告诉我oh yeah there is no problem in that??。确实,似乎没有问题,但是这样的系统/方法遇到很多问题,例如:在应用程序运行之前,EasyPhp必须打开,否则它们将收到404错误。我只需要安装几个EasyPhp及其所有模块。每当EasyPhp拒绝启动时,他们都必须给我打电话如果有人错误地卸载EasyPhp并认为它是一个奇怪的软件,则整个应用程序将保留所有记录。Pffff。我的数据库可以轻松访问。任何使用我的URL的人都可以入侵我的应用程序,因为它们是可见的。如果他们在另一个商店中需要相同的应用程序,那么我将不得不自己在那个商店中进行相同的处理,因为他们无法自己安装它。等等。绝对不是完美的解决方案。即使我没有任何问题,我也不能认为这是一个好的解决方案。我真幸运。在那之后,我以另外两种方式做过同样的事情,但是直到遇到PHP桌面我才对我的工作感到不满意。我想您可以理解我们在使用PHP的桌面应用程序时可能遇到的真正问题。我知道他们一定是个办法。否则,我在PHP中的技能只会用于网站。PHP Desktop可以减少(如果不能解决)所有这些问题,并提供了软件开发经验的新视野:无需再次将所有模块全部嵌入,仅需将其嵌入。无需安装任何Web服务器,一切都已嵌入无需担心浏览器兼容性,因为PHP Desktop带有嵌入式浏览器该浏览器非常轻巧,没有所有无聊的工具,例如地址栏,收藏夹栏,历史记录栏等。毕竟,我们将不需要它们。您可以将整个应用程序制作为.exe文件并将其发送给客户,以便他们自己安装PHP Desktop也可以充当纯HTML5 / JS应用程序的打包程序没有内存泄漏您可以将其用于Perl,Ruby和Python等等。不妙吗?我们想要什么?基本上,任何PHP程序员都希望创建任何桌面应用程序。创建一个可执行的(.exe)应用程序,他可以轻松共享或发送给他的客户。任何客户端都可以简单地按照安装向导安装应用程序,而无需程序员的任何努力或需求。不幸的是,如果您真的很喜欢PHP编程,那么现在应该知道这实际上是不可能的。由于PHP是一种解释型编程语言,因此您无法将项目文件编译为单个可执行文件(.exe),这就是最大的问题所在。大多数专门用于桌面应用程序的编程语言(例如Java)都有一些库,这些库提供了一些元素集(按钮,菜单,颜色,形状等)来帮助创建软件界面。实际上,PHP没有这种东西,PHP完全是一种脚本语言。人们试图创建一些扩展(例如PHP-GTK)来为语言提供这种功能,但是问题仍然没有完全解决。此外,PHP可以与HTML和JavaScript结合使用。而且我们知道可以使用CSS设置HTML标记的样式……越来越好。我们无法想象CSS在设计方面的局限性。因此,这就是PHP桌面发挥其力量的地方。它是如何工作的?PHP Desktop利用大多数Web技术来帮助PHP实现我们的目标。PHP Desktop本身是一种可以将您自己嵌入其中的软件。因此,当您安装PHP Desktop时,现在将自己的应用程序放入PHP Desktop的文件夹中。当您启动PHP Desktop时,它将去读取/解析您的应用程序以显示/运行它。PHP Desktop嵌入了应用程序在运行之前可能需要的所有服务。主要元素是Web服务器(猫鼬),PHP服务器和数据库引擎(Sqlite)。为了提供通用接口,它嵌入了浏览器(实际上是Chrome或Internet Explorer)。现在,浏览器可以帮助我们解释JavaScript,HTML和CSS。因此,在使用前无需安装任何其他服务器或解析器。使用PHP创建您的第一个桌面应用程序使用PHP创建桌面应用程序非常简单。下载PHP桌面(使用Chrome或Internet Explorer)创建一个新文件夹并命名 MyApp解压缩PHP Desktop Inside的内容您的文件夹中应该有以下内容MyApp:我下载了一个嵌入式Chome。无论您下载了哪个文件,最重要的是突出显示的文件,它是一个可执行文件(.exe)。双击该文件以运行它您应该得到这样的内容:- 发生了什么?PHP Desktop非常聪明。当您单击启动器时,它会进入一个特殊文件夹以查找任何可用的应用程序,并且该特殊文件夹不过是www文件夹。继续打开www文件夹,您应该会看到以下内容:惊讶!这些文件是我们单击启动器时列出的PHP桌面。注意:这些文件是.php文件。单击任何一个。您应该看到其内容。这些文件是示例文件,可以帮助您了解PHP Desktop可以执行这些文件正在执行的所有操作。其中,您具有Cookie,环境变量,表单,iframe,javascript等功能。这意味着您的PHP应用程序几乎可以执行所有操作。-为什么会提示两个窗口,它们分别是什么?默认情况下,PHP Desktop会提示两个窗口。第一个(更大)是chrome / explorer。这是您的应用程序所在的位置。用户将通过该窗口与之交互。您可以根据需要进行更改。第二个窗口(黑色和黑色的控制台)是调试界面(日志控制台)。它可以帮助您查看在运行应用程序时是否发生任何错误,这在开发阶段非常有用。-另一件事您应该知道,在生产中我们将不需要该黑色控制台,并且可能还需要调整主窗口的大小等。这些是设置。PHP Desktop带有一个名为的特殊文件settings.json。此文件将帮助我们配置PHP Desktop的某些行为。因此,例如,如果我们不希望PHP Desktop提示日志控制台,则可以settings.json使用任何文本编辑器打开文件并找到以下文件:"debugging": {"show_console": true,"subprocess_show_console": false,"log_level": "DEBUG4","log_file": "debug.log"}然后show_console像这样将false 的值更改为false:"debugging": {"show_console": false,"subprocess_show_console": false,"log_level": "DEBUG4","log_file": "debug.log"}然后再次运行PHP Desktop。pfff走了!-现在,让我们添加自己的应用程序进入www文件夹中的MyApp文件夹,然后删除其中的所有文件。创建一个简单的文件,并index.php用以下内容命名:<html><head> <title>MyApp</title></head><body> <h1>PHP Desktop is awesome</h1> <div style="background-color:blue; color:white; padding:2em; font-size:3em"> <?= "And PHP agrees!" ?> </div></body></html>现在将index.php文件移到www(如果未在其中创建www)文件夹中,然后启动PHP Desktop。您应该得到这样的内容:您会看到PHP桌面已将您识别index.php为第一个启动文件。那是Mongoose服务器(嵌入式Web服务器)的工作。另外,我们的HTML和CSS代码已解析,PHP代码也已解析。因此,您很高兴开始尝试其他代码。注意:将 Mongoose视为Apache服务器注意:我们的标题标签中的标题未显示。我们的应用程序窗口的标题应在以下对象的settings.json中设置: "main_window": { "title": "PHP Desktop Chrome", "icon": "", "default_size": [1024, 768], "minimum_size": [800, 600], "maximum_size": [0, 0], "disable_maximize_button": false, "center_on_screen": true, "start_maximized": false, "start_fullscreen": false }您可以看到该对象可以帮助您影响应用程序的窗口。所以现在怎么办?是的,您已经准备好应用程序了吗?您可以将文件夹MyApp放在计算机中的任何位置。每当您要启动它时,只需单击启动器,或为其创建快捷方式。Bahh,那不是我们想要的。我们需要一个可执行文件,可以发送给客户端,然后他可以自己安装应用程序。当然是。我忘记了大声笑。为了做到这一点,我们将需要另一个名为Inno Steup的特殊小软件。那又做什么?我们仅要求Inno Setup提取文件夹中的内容MyApp并将其转换为自安装包。最后,我们将获得一个简单的setup.exe文件,可以将其发送到客户端进行安装。为此,请按照以下步骤操作:下载Inno设置安装它如果出现这样的情况,请选择“创建一个新的空脚本文件”现在去 File > New该向导将出现:不要检查“创建新的空脚本文件”点击 Next该向导将出现:在这里,我们需要为您的应用程序进行一些设置:应用名称: MyApp应用版本: 0.0.1应用程序发布者:(iT Tutors Age Ltd您的公司或您的名字)申请网站:(www.phpocean.com或您的网站)现在Next再次点击该向导将出现:在这里,我们需要精确确定将文件夹安装在用户计算机中后将包含我们的应用程序的名称。当您安装应用程序时,它通常位于C:\Program Files或中C:\Program Files (x86)。因此,默认情况下,我们将保留“应用程序目标”文件夹。现在让我们将Application文件夹名称更改为 MyApp点击 Next该向导将出现:这是发生严重事情的地方。第一个应用程序的主要可执行文件名称。在向导上,我们有MyProg.exe(圈出的区域)。这是Inno Setup中的默认测试文件。我们需要更改它,否则当我们启动应用程序时,它将启动Inno Setup的测试应用程序。因此,单击Browse,将您的文件夹浏览到我们的MyApp文件夹,然后双击phpdesktop-chrome.exe。接下来是带有其他应用程序文件标签的白色小区域。这部分也非常重要,而且管理起来也非常微妙。首先,它意味着:如果除了顶部添加的可执行文件之外,还有其他组成应用程序的文件,请在此处全部添加。因此,通常您必须将文件MyApp夹中的所有phpdesktop-chrome.exe文件一一带到这里,这是一件困难而又缓慢的事情。我个人通常会进入我的文件夹并突出显示所有文件,但phpdesktop-chrome.exe随后将所有文件 拖放到小区域中。简单快捷。因此,最后,您应该具有以下内容:然后Next再次点击该向导将出现:这是不言自明的。单击Windows start菜单后,将单击该名称以启动应用程序。您还可以激活其他选项。Next再点击一次该向导将出现:这些是您的应用程序的文档文件:许可证文件,安装之前的说明文件和安装结束时的说明文件。虽然这不是必须的,但是如果您想要一个严肃的软件,则可以添加它。要建立三种不同的文本文件(license.txt,before-install.txt,和end-install.txt您的计算机)的地方。然后浏览每个并将其添加到相应的字段。无论您在其中放置什么内容,用户在安装软件时都会看到它-试试看。然后点击 next该向导将出现:这些是您为软件安装向导提供的客户端语言。因此,当他们要安装它时,他们可以选择安装向导应该显示说明的语言。您可以选择法语和英语或更多。Next再点击一次该向导将出现:自定义编译器输出文件夹是您希望Inno Setup在其末尾放置Finale Executable文件的位置。因此,浏览并在您的计算机中选择一个文件夹(我选择了我的桌面文件夹)。编译器输出基本文件名是您希望最终压缩可执行文件具有的名称。您可以保留 setup或将其更改为MyAppSetup与我一样。自定义安装图标是您的可执行文件的图标。该文件必须是.ico文件。现在,就离开它。并留下密码领域也然后click on next再next again然后finish之后,Inno安装程序将提示以下内容:只需点击 Yes它将再次询问您是否要将生成的代码保存在某处以备将来使用。说,Yes如果要保留它,请选择将其保存在计算机上的位置并保存。如果您不想要,只需单击no。然后,Inno Setup将开始将我们的文件编译成可执行文件。确保在到达此处之前关闭PHP桌面,否则会提示错误,指出在其他地方使用了元素。如果一切顺利,您应该得到以下信息:现在进入您要求Inno Setup保存可执行文件的文件夹。就我而言,我选择了我的台式机。所以,这就是我到达的地方:我有一个可执行文件MyAppSetup,当我将鼠标悬停在它上时,我有这个文件:考虑所有细节。凉!要安装它,只需双击它,然后按照安装向导的说明进行操作。样本[ 编辑 ]人们要求我为他们提供一些使用PHP Desktop完成的实际应用案例。 在此处下载可执行文件的示例[38.9 MB]。安装完成以访问应用程序后,请使用:用户名:admin-密码:admin贝娄是我做过的一些应用程序的屏幕截图:结论希望您喜欢这个冗长的教程。我不想错过任何东西,因为这很棘手。但是,它们仍然可能是您无法摆脱的。只需在评论部分此处询问即可。本教程是一个非常简单的过程。使用PHP桌面时,您需要考虑很多方面,例如窗口设置,环境设置,框架的使用,访问计算机文件和硬件等。
2020年04月10日
2,317 阅读
0 评论
0 点赞
2020-03-18
七牛云空间批量删除文件
由于业务转行之前存储在七牛云其中一个bucket的资源文件都不需要了,需要批量删除。但是文件管理中批量删除最多50个,这个bucket里有好几百万的文件,50个50个删除太笨了!!!!!因此请教了大神之后总结下面的方法做个记录供以后使用。首先安装七牛云的qshell命令行工具,源码地址:https://github.com/qiniu/qshell/。下载对应系统的安装文件按教程安装。安装完成后使用以下命令先导出文件列表:$ qshell listbucket2 --max-retry -1 yourBucketName --readable -o dfileList.txt大概10分钟导出完成后使用以下命令删除:$ qshell batchdelete yourBucketName -i qiniufile.txt --success-list success.txt --failure-list failure.txt好了大功告成,收工
2020年03月18日
1,271 阅读
0 评论
0 点赞
2020-03-07
Spacevim-php-init.toml
安装spacevim请自行去官网查看# 这是一个基础的 SpaceVim 配置示例 # 所有的 SpaceVim 选项都列在 [options] 之下 [options] # 设置 SpaceVim 主题及背景,默认的主题是 gruvbox,如果你需要使用更 # 多的主题,你可以载入 colorscheme 模块 colorscheme = "molokai" # 背景可以取值 "dark" 或 "light" colorscheme_bg = "dark" # 启用/禁用终端真色,在目前大多数终端下都是支持真色的,当然也有 # 一小部分终端不支持真色,如果你的 SpaceVim 颜色看上去比较怪异 # 可以禁用终端真色,将下面的值设为 false enable_guicolors = true # 设置状态栏上分割符号形状,如果字体安装失败,可以将值设为 "nil" 以 # 禁用分割符号,默认为箭头 "arrow" statusline_separator = "arrow" statusline_inactive_separator = "bar" # 设置顶部标签列表序号类型,有以下五种类型,分别是 0 - 4 # 0: 1 ➛ ➊ # 1: 1 ➛ ➀ # 2: 1 ➛ ⓵ # 3: 1 ➛ ¹ # 4: 1 ➛ 1 buffer_index_type = 0 # 显示/隐藏顶部标签栏上的文件类型图标,这一图标需要安装 nerd fonts, # 如果未能成功安装这一字体,可以隐藏图标 enable_tabline_filetype_icon = true # 是否在状态栏上显示当前模式,默认情况下,不显示 Normal/Insert 等 # 字样,只以颜色区分当前模式 enable_statusline_mode = true # 状态栏左端部分的构成 statusline_left_sections = ['winnr', 'major mode', 'filename', 'fileformat', 'minor mode lighters', 'version control info', 'search status'] # 状态栏右端部分的构成 statusline_right_sections = ['cursorpos', 'percentage', 'input method', 'date', 'time'] # 列表可以由以下一项或多项组成 # 'winnr' 当前窗口编号 # 'syntax checking' # 'filename' 文件名 # 'fileformat' 文件格式 # 'major mode' # 'minor mode lighters' # 'cursorpos' 光标位置 # 'percentage' 百分比 # 'date' 日期 # 'time' 时间 # 'whitespace' 打开或者保存文件时,如果第 n 行的行尾有空格则显示 trailing[n],并不能实时显示出行尾有空格的行号。 # 'battery status' 电池状态 # 'input method' 输入法 # 'search status' 搜索状态 # 文件树插件可选值包括: # - vimfiler (默认) # - nerdtree # - defx # filemanager = "nerdtree" # 中文支持 vim_help_language = "cn" # 语法检查如果需要使用 syntastic,将两者都设置为 false。 enable_neomake = false enable_ale = true # SpaceVim 模块设置,主要包括启用/禁用模块 # 启用 autocomplete 模块,启用模块时,可以列出一些模块选项,并赋值, # 关于模块的选项,请阅读各个模块的文档 [[layers]] name = "autocomplete" auto-completion-return-key-behavior = "complete" auto-completion-tab-key-behavior = "cycle" # 禁用 shell 模块,禁用模块时,需要加入 enable = false [[layers]] name = "shell" enable = false # 添加自定义插件 [[custom_plugins]] name = "lilydjwg/colorizer" merged = false # 主题模块 [[layers]] name = "colorscheme" random_theme = false # shell模块 [[layers]] name = "shell" default_position = "top" default_height = 30 # 中文帮助文档 [[layers]] name = "chinese" # 版本控制 [[layers]] name = "VersionControl" # 标签管理 [[layers]] name = "tools" # 代码自动补全 [[layers]] name = "lsp" # PHP语言模块 [[layers]] name = "lang#php" [[layers]] name = "lsp" filetypes = [ "php" ] [layers.override_cmd] php = ['php', '~/.cache/vimfiles/repos/github.com/felixfbecker/php-language-server/bin/php-language-server.php'] # 代码格式化 [[layers]] name = "format" # 自动语法检查 [[layers]] name = "checkers" show_cursor_error = true # 在文件树内显示隐藏的文件,默认是 false [[layers]] name = 'core' filetree_show_hidden = true # 搜索文件、函数列表、 命令历史等等特性 [[layers]] name = "fzf" # Git 支持 [[layers]] name = "git" # 项目 tags 管理工具 [[layers]] name = "gtags" gtagslabel = "ctags" # 额外的语言支持 [[layers]] name = "lang#extra" # HTML CSS 开发提供支持 [[layers]] name = "lang#html" # JavaScript 开发支持 [[layers]] name = "lang#javascript" auto_fix = true enable_flow_syntax = true [[layers]] name = "lsp" filetypes = [ "javascript" ] [layers.override_cmd] javascript = ['javascript-typescript-stdio'] # lua 开发支持 [[layers]] name = "lang#lua" # shell 语言支持 [[layers]] name = "lang#sh" [[layers]] name = "lsp" filetypes = [ "sh" ] [layers.override_cmd] sh = ['bash-language-server', 'start'] # vim 开发支持 [[layers]] name = "lang#vim" # vue 开发支持 [[layers]] name = "lang#vue" [[layers]] name = "lsp" filetypes = [ "vue" ] [layers.override_cmd] rust = ["vls"] # 提供了搜索文件、函数列表、 命令历史 [[layers]] name = "leaderf" # 管理员身份读写文件 [[layers]] name = "sudo" # 查找单词 [[layers]] name = "tools#dash" # 工具集插件 [[layers]] name = "tools" # IDE-like 界面 [[layers]] name = "ui" # css自动补全 [[layers]] name = "lsp" filetypes = [ "css" ] [layers.override_cmd] css = ['css-languageserver', '--stdio'] # 聊天框架 #[[layers]] # name = "chat"
2020年03月07日
1,923 阅读
0 评论
0 点赞
2020-03-04
vim自动配置程序
安装Mac OS X安装HomeBrew/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"安装vimplusgit clone https://github.com/chxuan/vimplus.git ~/.vimpluscd ~/.vimplus./install.sh设置Nerd Font为防止vimplus显示乱码,需设置mac终端字体为Droid Sans Mono Nerd Font。更新vimplus紧跟vimplus的步伐,尝鲜新特性./update.shLinux 64-bit支持以下发行版 安装vimplusgit clone https://github.com/chxuan/vimplus.git ~/.vimpluscd ~/.vimplus./install.sh //不加sudo设置Nerd Font为防止vimplus显示乱码,需设置linux终端字体为Droid Sans Mono Nerd Font。多用户支持将vimplus在某个用户下安装好后,若需要在其他用户也能够使用vimplus,则执行sudo ./install_to_user.sh username1 username2 //替换为真实用户名更新vimplus紧跟vimplus的步伐,尝鲜新特性./update.shDockerubuntu-vimplus是vimplus基于ubuntu18.04的docker镜像,无需安装vimplus,即可快速体验vimplus带来的快乐docker run -it chxuan/ubuntu-vimplus自定义~/.vimrc为vimplus的默认配置,一般不做修改 ~/.vimrc.custom.plugins为用户自定义插件列表,用户增加、卸载插件请修改该文件 ~/.vimrc.custom.config为用户自定义配置文件,一般性配置请放入该文件,可覆盖~/.vimrc里的配置 插件列表插件 说明 cpp-mode 提供生成函数实现、函数声明/实现跳转、.h .cpp切换等功能(I'm author) vim-edit 方便的文本编辑插件(I'm author) change-colorscheme 随心所欲切换主题(I'm author) prepare-code 新建文件时,生成预定义代码片段(I'm author) vim-buffer vim缓存操作(I'm author) vimplus-startify vimplus开始页面(修改自mhinz/vim-startify) tagbar 使用majutsushi/tagbar的v2.3版本,taglist的替代品,显示类/方法/变量 vim-plug 比Vundle下载更快的插件管理软件 YouCompleteMe 史上最强大的基于语义的自动补全插件,支持C/C++、C#、Python、PHP等语言 NerdTree 代码资源管理器 vim-nerdtree-syntax-highlight NerdTree文件类型高亮 nerdtree-git-plugin NerdTree显示git状态 vim-devicons 显示文件类型图标 Airline 可以取代powerline的状态栏美化插件 auto-pairs 自动补全引号、圆括号、花括号等 LeaderF 比ctrlp更强大的文件的模糊搜索工具 ack 强大的文本搜索工具 vim-surround 自动增加、替换配对符的插件 vim-commentary 快速注释代码插件 vim-repeat 重复上一次操作 vim-endwise if/end/endif/endfunction补全 tabular 代码、注释、表格对齐 vim-easymotion 强大的光标快速移动工具,强大到颠覆你的插件观 incsearch.vim 模糊字符搜索插件 vim-fugitive 集成Git gv 显示git提交记录 vim-slash 优化搜索,移动光标后清除高亮 echodoc 补全函数时在命令栏显示函数签名 vim-smooth-scroll 让翻页更顺畅 clever-f.vim 强化f和F键 快捷键以下是部分快捷键,可通过vimplus的,h命令查看vimplus帮助文档。快捷键 说明 , Leader Key <leader>n 打开/关闭代码资源管理器 <leader>t 打开/关闭函数列表 <leader>a .h .cpp 文件切换 <leader>u 转到函数声明 <leader>U 转到函数实现 <leader>u 转到变量声明 <leader>o 打开include文件 <leader>y 拷贝函数声明 <leader>p 生成函数实现 <leader>w 单词跳转 <leader>f 搜索~目录下的文件 <leader>F 搜索当前目录下的文本 <leader>g 显示git仓库提交记录 <leader>G 显示当前文件提交记录 <leader>gg 显示当前文件在某个commit下的完整内容 <leader>ff 语法错误自动修复(FixIt) <c-p> 切换到上一个buffer <c-n> 切换到下一个buffer <leader>d 删除当前buffer <leader>D 删除当前buffer外的所有buffer vim 运行vim编辑器时,默认启动开始页面 <F5> 显示语法错误提示窗口 <F9> 显示上一主题 <F10> 显示下一主题 <leader>l 按竖线对齐 <leader>= 按等号对齐 Ya 复制行文本到字母a Da 剪切行文本到字母a Ca 改写行文本到字母a rr 替换文本 <leader>r 全局替换,目前只支持单个文件 gcc 注释代码 gcap 注释段落 vif 选中函数内容 dif 删除函数内容 cif 改写函数内容 vaf 选中函数内容(包括函数名 花括号) daf 删除函数内容(包括函数名 花括号) caf 改写函数内容(包括函数名 花括号) fa 查找字母a,然后再按f键查找下一个 <leader>e 快速编辑~/.vimrc文件 <leader>s 重新加载~/.vimrc文件 <leader>vp 快速编辑~/.vimrc.custom.plugins文件 <leader>vc 快速编辑~/.vimrc.custom.config文件 <leader>h 打开vimplus帮助文档 <leader>H 打开当前光标所在单词的vim帮助文档 <leader><leader>y 复制当前选中到系统剪切板 <leader><leader>i 安装插件 <leader><leader>u 更新插件 <leader><leader>c 删除插件 FAQvimplus安装脚本会在自己电脑上安装哪些软件?网络良好情况下,vimplus只需30分钟左右即可将vim cpp环境配置好,vimplus真正的做到了一键配置,不让用户操心。vimplus会安装一些必备软件,比如说python、cmake、gcc、fontconfig等,vimplus也考虑到了有些系统的vim不支持python,它会自动去下载vim源码将python支持编译进去,vimplus也会安装nerd-font不让vim显示出现乱码,最最重要的是vimplus实现了ycm自动编译安装,给折腾了几天ycm都没有安装好的用户带来了新的希望,而且vimplus也支持macos和linux众多发行版,让linux发烧友频繁切换发行版而不用操心vim环境配置。最后说了这么多,不如看vimplus安装脚本来的直接。启动vim报错:RequestsDependencyWarning: Old version of cryptography ([1, 2, 3]) may cause slowdown.可以尝试将cryptography删掉,具体见issues #208。vimplus不支持目前用户正在使用的系统怎么办?可以给作者提Issues,或者自己fork vimplus来修改,并提交pr,贡献自己的一份力量。安装vimplus后Airline等插件有乱码,怎么解决?linux和mac系统需设置终端字体为Droid Sans Mono Nerd Font。xshell连接远程主机不能使用vim-devicons或乱码。windows系统安装Nerd Font字体后并更改xshell字体即可。ubuntu18.04安装了nerd font但通过终端属性并没有看到该字体。可以试试dconf-editor软件来设置,可以参考这里。使用第三方库时怎么让ycm补全第三方库API?vimplus安装完毕之后,~目录下将会生成两个隐藏文件分别是.vimrc和.ycm_extra_conf.py,其中.vimrc是vim的配置文件,.ycm_extra_conf.py是ycm插件的配置文件,当你需要创建一个project时,需要将.ycm_extra_conf.py拷贝到project的顶层目录,通过修改该配置文件里面的flags变量来添加你的第三方库路径。怎么自定义文件头,比如说添加作者、创建时间?你可以修改chxuan/prepare-code插件来达到目的,可以参考这里。安装vimplus在“[ 95%] Building CXX object ycm/CMakeFiles/ycm_core.dir/ycm_core.cpp.o”等进度时出现编译报错编译ycm需要消耗较大内存,建议内存大于1G,实在不行也可以开启linux swap分区。以上没有我遇到的问题怎么办?您可以通过上网找解决方法,或提Issues,也可以通过加QQ787280310、发邮件方式787280310@qq.com一起讨论解决方法。vimplus用起来真的太棒了,怎么办?那就麻烦您打赏一颗吧,给予我继续维护的动力。
2020年03月04日
845 阅读
0 评论
0 点赞
2020-03-03
Vim for PHP:强大的PHP IDE的完整指南
Vim,PHP IDE?我可以看到您在电脑前随地吐痰。“什么?带有Vim的PHP IDE?你疯了?”是吗 使用Vim制作功能非常强大的IDE绝对是可能的:您需要知道安装了哪些插件以及它们的用途。那是我的前同事之一(kushellig),您向我展示了如何操作。从他们那里,我只是根据自己的需要对其进行了改进。我在这里提出的插件列表将满足您的大多数需求:项目管理,自动完成,PHPDoc生成,强大的搜索和替换工具,调试器……所有这些功能都将免费唾手可得!这种配置也不会阻止Vim与不同语言的其他插件完美配合。与网络上的许多文章不同,我试图列出并描述一个良好的PHP IDE所必需的所有插件。当然,您需要阅读每个插件的文档以根据需要配置它们。这是Vim如此出色的多个原因之一:您可以制作自己的IDE,以完全满足您的需求和喜好!如果您需要一些具体的配置示例,可以看看我的一般vim配置。您也可以查看我的一些特定插件的配置。最后,如果您在配置这些插件时遇到困难,可以发表评论。我将竭诚为您服务。免责声明我在Arch Linux上将这些插件与Neovim一起使用,这意味着我不知道它们是否可以在MacO或Windows上运行。应该,但是要知道我从未测试过。Neovim和Vim实际上是几乎相同的软件,这就是为什么我在本文中以全局名称Vim引用它们。但是请记住,我提到的插件更可能与Neovim一起使用。PHP Vim插件我在这里尝试强调我使用的每个插件的所有优势。如果您只需要一个简单的无聊列表,则可以直接转到本文结尾处的插件参考列表。插件管理器首先,您需要一个插件管理器。这个插件是万能的插件:它将帮助您安装新插件,通过简单的命令行删除或更新它们。朱尼根/ vim-plug vim-plug是管理Vim插件所需的全部。您只需要安装它,并将此配置放在vimrc之上:call plug#begin('~/nvim/plugged')Plug 'tpope/vim-fugitive'call plug#end()该行Plug 'tpope/vim-fugitive'是您可以安装的插件的示例。关键字Plug必须在任何插件的github存储库之后。您需要在call plug#begin和之间声明您的插件call plug#end。就那么简单!生成标签该标记文件是可以为许多OOP语言(包括PHP)设置的索引。建议为每个项目创建一个标记文件:您将能够轻松跳转到方法和类定义(ctrl + ]默认情况下使用) 此列表中的某些插件需要具有标记文件才能工作 为了生成此文件,有两种解决方案:Universal ctags 或 Gutentags。我个人更喜欢第一个,但您当然可以同时测试两者。1-通用标签对于生成标记文件的第一种方法,您需要在您的PHP项目中使用git(我暗中希望您这样做!)。首先,您需要安装Universal-ctags才能生成此标签文件。如果在软件包管理器中不可用,则需要对其进行编译。执行这些命令行,您将在当前目录中下载并编译通用标签。一个小建议:将所有编译的软件都放在一个位置是个好习惯(我个人将它们放在文件夹中~/bin):git clone git@github.com:universal-ctags/ctags.gitcd ctags./autogen.sh./configuremakesudo make install然后,您需要添加一个git挂钩来自动生成此标记文件。ctags在.git/hooks/您的PHP项目的目录中创建一个文件,其内容如下:#!/bin/shset -ePATH="/usr/local/bin:$PATH"dir="`git rev-parse --git-dir`"trap 'rm -f "$dir/$$.tags"' EXITctags --tag-relative=yes -R -f "$dir/$$.tags" --fields=+aimlS --languages=php --PHP-kinds=+cdfint-av --exclude=composer.phar --exclude=*Test.php --exclude=*phpunit* --exclude="\.git"mv "$dir/$$.tags" "$dir/tags"现在,您需要更改文件的权限: sudo chmod 777 ctags最后,您需要在vimrc中添加以下行。每次保存PHP文件时,它将生成标记。 au BufWritePost *.php silent! !eval '[ -f ".git/hooks/ctags" ] && .git/hooks/ctags' &您可以通过在项目中打开任何PHP文件并将其保存来测试其是否有效。通常,tags文件应出现在.git项目目录中。这就是我们所需要的!2-Gutentags卢多维科恰班特 第二种方法更简单:您所需要做的就是安装gutentags插件,根据需要配置它,然后就可以开始使用!Essentials插件本节的插件只是死亡的最佳和必备插件。他们改善了Vim……很多!它们并不是专门为PHP开发而设计的,但是它们会带来一些主要IDE默认具有的强大功能。阴囊/书呆子 Vim带有一个非常简单的文件浏览器,但这还远远不够。如果要在编辑器中使用更复杂的文件树,则此树功能非常强大。bfredl / nvim-miniyank Miniyank非常容易导航到Vim的寄存器中。您可以使用所需的任何按键轻松地浏览寄存器。当您知道需要复制或删除某些内容时,它非常简单且功能强大。莫尔/维姆比 这个插件允许您关闭缓冲区而不关闭窗口。我一直都在使用它,很棒的是不要弄乱窗口布局并保持关闭文件的可能性。itchyny / lightline.vim lightline.vim是一个很好的状态栏,可随时提供您需要的当前文件和状态信息。您不记得自己处于哪种模式?您当前修改的是哪个文件?文件的编码是什么?此状态栏将为您提供所需的信息。tpope / vim注释 蒂姆·波普(Tim Pope)是Vim世界中一个多产的贡献者。他所有的插件都值得尝试。Vim-commentary将通过简单的击键注释每一行。它与多种语言(PHP,JavaScript,Go等)完美配合。tpope / vim废除 我最常使用的Vim功能之一是替换。它允许您在当前文件中简单地用一个字符串替换另一个字符串。该插件使替换功能更智能。例如,它允许您保留要替换的单词的复数形式或大写字母。它甚至可以用dot.case替换snake_case的camelCase。Vim的一个很好的补充。项目管理插件如今,在许多IDE或编辑器中将完全不同的代码文件组织到一个项目中非常自然。感觉如此自然,我们不再觉得它有多方便。通过组合两个插件,可以在Vim中实现相同的目的。阿米林/ vim项目 使用vim-project,您将能够覆盖一个项目的任何vim配置!与许多IDE一样,它允许您根据当前打开的项目进行完全个性化的配置。该插件还提供了Vim的启动页面,让您选择要打开的项目。不幸的是,这个启动页面似乎在Neovim上不起作用。这就是为什么我将vim-project与vim-startify一起使用。mhinz / vim-startify 你知道《财富》吗?每次您打开Neovim时,vim-startify都会使用它来显示与开发相关的随机报价。这听起来可能很愚蠢,但却很棒!在同一页面上,startify还将显示您已配置的每个项目,并让您选择要打开的项目。由于我将项目配置文件与vimrc分开,因此这里有一个示例,说明如何使用vim-project和vim-startify配置项目:let g:startify_bookmarks = [ \ {'1': '~/workspace/mySuperProject/README.md'}, \]call project#rc("~/workspace")Project 'mySuperProject'Callback 'mySuperProject', ['Symfony', 'mySuperProject']function! mySuperProject(...) let g:vdebug_options["path_maps"] = { \ "/mySuperProject": "/home/mySuperUser/workspace/mySuperProject" \} PadawanStartServerendfunctionfunction! Symfony(...) let g:ultisnips_php_scalar_types = 1 " standard phpcs config let g:neomake_php_phpcs_args_standard = 'PSR2' " php cs fixer let g:php_cs_fixer_php_path = "php" autocmd FileType php nnoremap <leader>g :silent :call PhpCsFixerFixFile()<CR>endfunction我定义的函数的一些特殊配置Symfony和mySuperProject然后我可以连接到该项目mySuperProject通过回调线。此配置使用我在下面介绍的插件。语法插件这些插件非常适合PHP开发。StanAngeloff / php.vim 一个简单的插件,它将改善PHP的语法突出显示。像本文中的许多插件一样,它是高度可配置的。stephpy / vim-php-cs-fixer 此代码将在需要时自动格式化代码(例如,通过按键或每次保存PHP文件)。默认情况下,它将按照PSR1 / PSR2规则格式化代码,但您也可以自行配置。自动补全插件当我开始完全使用Vim时,我非常害怕退出IntelliJ(PhpStorm的索引引擎,该引擎可以实现非常好的自动补全)。最后,我没有错过任何一秒钟……感谢以下插件!ncm2 / ncm2 必须使用自动完成引擎来自动触发自动完成本身。ncm2是我的最爱,因为它易于安装,易于配置且易于使用。我从来没有问题。但是,这还不够。您将需要以下插件来专门自动完成PHP代码:phpactor / phpactor phpactor / ncm2-phpactor phpactor绝对是必须具备的。它可以为您提供很多帮助(请参阅“ 重构/代码样式插件”部分)。它提供的自动补全功能非常好并且非常稳定。它还允许您自动导入类名称空间,甚至可以跳转到没有ctags的类或方法定义。插件ncm2-phpactor旨在将phpactor链接到ncm2。搜索/替换插件在文件甚至整个项目中搜索和替换呢?Vim也可以这样做吗?当然可以,而且做得很好。这些插件比我测试过的任何东西都更快,更强大。https://github.com/junegunn/fzf junegunn / fzf.vim 简而言之:fzf是您将找到的最佳模糊搜索器。用Go语言编写,它可以轻快的速度搜索任何文件中的所有内容。老实说,我从PhpStorm切换到Vim的部分原因是因为该插件!就是那样该列表的第一个插件将安装模糊搜索器本身:您可以在终端中使用它来搜索……任何您想要的东西。搜索命令行历史记录(例如)是我无法缺少的一项主要功能。第二个插件将在Vim中启用fzf。然后,您可以配置一些击键来搜索文件历史记录,缓冲区或搜索项目中的文件…https://github.com/BurntSushi/ripgrep Ripgrep不是Vim插件,但可以与fzf结合使用,以将事件搜索到多个文件中。非常强大,而且又快得惊人。您需要在计算机上安装ripgrep(对于使用Arch linux的用户,只需键入pacman -S ripgrep),并在vimrc中编写一些配置。例如:nnoremap <leader>a :Rg<space>nnoremap <leader>A :exec "Rg ".expand("<cword>")<cr>autocmd VimEnter * command! -nargs=* Rg \ call fzf#vim#grep( \ 'rg --column --line-number --no-heading --fixed-strings --ignore-case --no-ignore --hidden --follow --glob "!.git/*" --color "always" '.shellescape(<q-args>), 1, \ <bang>0 ? fzf#vim#with_preview('up:60%') \ : fzf#vim#with_preview('right:50%:hidden', '?'), \ <bang>0)当您输入按键<leader> a并在命令行提示符下键入内容时,ripgrep将在项目的所有文件中搜索该内容。然后,借助fzf,您可以在搜索窗口中微调搜索。您甚至可以通过键入在搜索中突出显示文件的预览?。https://github.com/wincent/ferret 最后但并非最不重要的一点,这里是一个使用Ripgrep的插件,用于搜索多个文件中的事件。就像ripgrep与fzf组合在一起(见上文),只是有一个区别:您可以使用多个著名的vim替换来为多个精确的文件选择命名的文件,从而重命名多个文件中的文件。假设您需要通过一堆文件来重命名变量?这个插件可以很容易地为您做到这一点。此外,它使您可以完全控制要修改的内容。PhpStorm批量重命名有很多问题,特别是因为它倾向于替换我不想替换的内容。我从来没有一个问题与此插件。代码质量插件您编写代码时会犯错误吗?如果答案是否定的,请与我们取得联系。我很想知道您的做法...否则,我强烈建议您获取此插件:新作/新作 Neomake将在左侧的装订线(在行号附近)和窗口的位置列表中填充代码中出现的任何错误,这要感谢警告者。这些警告制定者被插入一些著名的PHP代码质量工具中:PHP混乱检测器 PHP静态分析工具 PHP代码嗅探器 您也可以创建自己的制造商。在Vim中,只需输入:help neomake-job-makers并按照说明进行操作即可。Neomake可以立即显示任何PHP语法错误。重构插件拥有一些用于重构和正确格式化代码的工具可以节省大量时间。adoy / vim-php-refactoring-toolbox 通过简单的按键操作,您可以(显然)进行配置,此插件可以:重命名局部变量,方法,类属性 创建获取器和设置器或类属性 提取使用语句,常量,类属性 此列表并不详尽。一个做得很好的插件,易于配置。phpactor / phpactor 如上所述,此插件可以执行一些非常有用的操作,例如:在项目树中移动类并更新其所有引用(!) 根据构造函数参数自动创建属性 提取方法 提取常数 … 以及更多 一个怪兽。Git插件如今谁不使用git?如果您更喜欢使用SVN,这是一个谎言。尝试git,再也不要回头。tpope / vim逃犯 Vim逃犯是必须具备的。您可以执行很多操作(git怪或在特定文件上显示差异…)。强烈推荐。mhinz / vim-signify Vim signify也是非常有用的:它通过在左侧装订线中显示小标志来显示修改/添加/删除的行。片段插件没有摘要我该怎么办?为了加快代码键入速度,这非常方便。您是否要通过仅键入pri键击然后创建私有方法?我确定你会的。SirVer / ultisnips Ultisnips将为您提供一个非常好的和快速的摘录引擎,可以使用您想要的每种语言。honza / vim-snippets Vim代码段是许多语言(包括PHP或课程)的非常好的代码段集。最好的部分:用自己的代码片段很容易扩展!大纲插件大纲插件在单独的窗口中显示类的每个方法和属性的列表。然后,您可以选择它们以跳到源文件本身中的定义。majutsushi /标签栏 这是您会发现的最好的大纲插件。我个人不经常使用它(并且我经常忘记使用它),但是在某些情况下它可以派上用场。调试器插件琼蒂/ vdebug 如果您需要使用多种语言的优秀调试器,则vdebug是最好的选择。配置可能有些繁琐,但功能非常强大。对于PHP,您需要正确配置xdebug才能使用它。对于Docker用户(或者如果您使用Vagrant之类的任何虚拟机),则需要指定项目的路径,如下所示:let g:vdebug_options["path_maps"] = { \ "/mySuperProject": "/home/mySuperUser/workspace/mySuperProject" \}左边的路径是您的虚拟机/ Docker上的路径,右边的路径是您的本地路径。PHPDoc插件能够通过简单的按键生成PHPDoc非常方便。这些插件正是这些插件!tobyS / vmustache tobyS / pdv 这些插件将自动创建一些有用的带有参数变量的PHPDoc(但不会返回)。您大部分时间都需要完成信息,但这是一个好的开始。简而言之:Vim比PhpStorm好吗?我不喜欢这种比较:PhpStorm是具有更多功能的IDE。对我来说,它太多了,我讨厌有一百万个窗口突然弹出,这打扰了我的思维和流程。命令行比一堆Windows更加通用和强大。Vim可能并不比PhpStorm“更好”,但我认为Vim可以肯定地用本文列出的插件替换PhpStorm。此外,您还具有Vim配置的灵活性,可以根据需要扩展它。PhpStorm并没有真正为您提供任何配置选择(至少只有基本的选择)。至少对我来说,Vim确实比我尝试过的任何其他PHP IDE更有趣,功能更强大!如果您在设置自己的Vim时遇到任何问题或疑问,请在评论中让我知道。
2020年03月03日
1,395 阅读
0 评论
0 点赞
1
2