mshx

mshx 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

mshx 赞了文章 · 2020-12-23

用 Composer 组建了个 PHP 框架

image

大约在两三年前自己就有过写个 PHP web 框架的想法,期间也尝试过去实践开发,但总是由于各种各样的原因并没有完成。

这次终于恒心下来,忙里偷闲的组建了一个自己的 PHP 微框架。前前后后零零碎碎的开发了快一个月的时间,直到今天完成文档的编写,才向大家呈现。

除了框架本身的(Coole)核心代码,还提供一个框架应用(coolephp/skeleton)模板,另外编写了一份简陋的文档, 望能给 也想写框架的人带来一点参考(大神请忽略)。

生命周期

image

  1. 客户端向入口脚本 index.php 发起请求。
  2. 入口脚本中创建应用,向应用中注册配置服务、核心服务、第三方服务。
  3. 定义路由,载入到应用中。
  4. 启动运行应用。
  5. 创建请求对象。
  6. 根据请求对象解析路由,创建控制器实例。
  7. 动作调用模型数据,渲染到视图,生成响应对象。
  8. 管道过滤响应。
  9. 返回响应给客户端。
  10. 终止生命周期。

命令行界面

image

安装框架

$ composer require guanguans/coole -vvv

快速开始

<?php

use Guanguans\Coole\App;
use Guanguans\Coole\Facade\Router;
use Symfony\Component\HttpFoundation\Request;

require __DIR__.'/vendor/autoload.php';

// 1. 创建应用
$app = new App();
$app['debug'] = true;

// 2. 定义一个带中间件的路由
Router::get('/', function (){
    return 'This is the Coole framework.';
})->setMiddleware(function (Request $request, Closure $next){
    printf('Before request.<br>');
    $response = $next($request);
    printf('<br>After request.');

    return $response;
});

// 3. 监听运行
$app->run();

框架中每项功能职责所用到的组件

参考的文章及借鉴的框架

官方文档

源码链接

查看原文

赞 9 收藏 5 评论 0

mshx 收藏了文章 · 2020-12-23

用 Composer 组建了个 PHP 框架

image

大约在两三年前自己就有过写个 PHP web 框架的想法,期间也尝试过去实践开发,但总是由于各种各样的原因并没有完成。

这次终于恒心下来,忙里偷闲的组建了一个自己的 PHP 微框架。前前后后零零碎碎的开发了快一个月的时间,直到今天完成文档的编写,才向大家呈现。

除了框架本身的(Coole)核心代码,还提供一个框架应用(coolephp/skeleton)模板,另外编写了一份简陋的文档, 望能给 也想写框架的人带来一点参考(大神请忽略)。

生命周期

image

  1. 客户端向入口脚本 index.php 发起请求。
  2. 入口脚本中创建应用,向应用中注册配置服务、核心服务、第三方服务。
  3. 定义路由,载入到应用中。
  4. 启动运行应用。
  5. 创建请求对象。
  6. 根据请求对象解析路由,创建控制器实例。
  7. 动作调用模型数据,渲染到视图,生成响应对象。
  8. 管道过滤响应。
  9. 返回响应给客户端。
  10. 终止生命周期。

命令行界面

image

安装框架

$ composer require guanguans/coole -vvv

快速开始

<?php

use Guanguans\Coole\App;
use Guanguans\Coole\Facade\Router;
use Symfony\Component\HttpFoundation\Request;

require __DIR__.'/vendor/autoload.php';

// 1. 创建应用
$app = new App();
$app['debug'] = true;

// 2. 定义一个带中间件的路由
Router::get('/', function (){
    return 'This is the Coole framework.';
})->setMiddleware(function (Request $request, Closure $next){
    printf('Before request.<br>');
    $response = $next($request);
    printf('<br>After request.');

    return $response;
});

// 3. 监听运行
$app->run();

框架中每项功能职责所用到的组件

参考的文章及借鉴的框架

官方文档

源码链接

查看原文

mshx 赞了文章 · 2020-12-07

思否有约 | @敖丙:我是一个不安分的人

本期访谈嘉宾:敖丙
访谈编辑:袁钰涵

你见过刚毕业两年,就有着四年的大厂工作经验程序员吗?

今天这里就有一位,除了有远超同龄人的工作经验,论起面试经验,他也不输于别人,他骄傲地说,自己是一个有面试天赋的人,大部分岗位都能面试成功。

甚至为了不辜负这份天赋,他制作了关于程序员面试技巧分享的视频,发布后直接上了B站的专区热门,后来因为太多人模仿他的创意,作为一个不喜欢与别人一样的人,他停更了这系列的视频。

虽然视频停更,但他却喜欢上了自媒体这条路,于是在上一年,辞去了在大厂的工作,选择了一家不用加班的公司上班,把用工作之余的时间都拿来学习以及创作内容。

他就是@敖丙,拥有着程序员与自媒体人双重身份的少年。


大学两年修够学分,还成功拿了多家公司的 offer,但敖丙并不是学霸,更确切地说,一开始不是

大一时候的敖丙每天除了在宿舍打游戏就是在宿舍打游戏,俨然是一个网瘾少年。

从网瘾少年变为学霸,只经历了一年的时间,改变的开始是在2015年的夏天。

那时的敖丙暑假闲来无事,去了表哥所在的大学。

本来以为两人能无拘无束地玩游戏,想几点睡就几点睡,做什么都没人管。

谁知事实完全与之相反,表哥是个医学生,医学生的假期是属于自习室和图书馆的,每天看着努力学习的表哥,再看看成日玩游戏的自己,敖丙开始思考起了自己的未来,考虑到不富裕的家庭并不能为自己的就业提供太多的帮助,痛定思痛,敖丙开启了他的学霸之路。

暑假回来后,敖丙开始努力学习,但普通上课不能满足敖丙对知识吸收的渴望,在他看来,有些课程讲太慢了,不如自学效率高,不上课如何获得学分呢?

自从发现获得专业比赛的大奖可以兑换学分后,敖丙通过拿下各个比赛的大奖凑满了足以毕业的学分,敖丙的日常变成了不是学习如何做项目就是做项目,由此在大三,开启了他大厂打工的生涯。

无论是凑毕业学分还是成为新媒体人,敖丙总是努力避免去和别人走一样的路,按照他的说法那就是——不想和别人一样。


开始在大厂上班的敖丙光工作方向就发生了两次大变

大厂打工是从一个机缘开始的,大二的敖丙刚好参加了华为赞助的比赛,拿下前三名,获得了现场面试的机会,而他,面试成功了。

工作只是一个开始,在这四年的时间里,敖丙从做硬件转成了做后端,现在又在做大数据。

从硬件变成后端是因为个人更喜欢写代码,从后端变成大数据是因为2020年对于公司的冲击,导致部门大调动,面对这些变迁,敖丙的态度很平静,在他看来,只要认认真真地把事情做好就行了,然后在做好的基础上再做出成绩,剩下的就交给时间。

并且,一成不变从来不是他的作风。


在程序员生涯中,敖丙总结出了一套属于自己的工作流

敖丙曾在杭州的一家公司做电商活动项目,夜以继日地去做开发,项目与钱产生关联,一旦出现错误,会造成一个公司的损失,那段时间的压力非常大,项目组会把代码一遍又一遍地 review,拜托测试组多做测试,把 bug 都排出来,每天工作到凌晨三点不过是当时的常态。

敖丙跟着前辈们一起熬,伴随着压力与熬夜而来的,是他的成长。

正如人们所说的那样:压力最大的时候也是成长最快的时候,敖丙喜欢这种快速成长的感觉。

在一次次合作中,敖丙学到了很多,包括产品的思维、活动的理解。再后来一个需求下来了,敖丙就会去做设计思路,比如这次涉及到后面有哪些数据,哪些表我怎么去拿出来之后怎么处理,然后怎么以什么样的格式返回给后端,返回给前端,或者怎么跟其他的业务去交互,每一个项目他都要理清楚思路,他明白得把基础做好了,做踏实了,才能谈下一步。

于是在工作流程中,思维导图成为了必不可少的一部分。

👇是一张长图(这是敖丙分享的一个工作流程图,希望能对大家有帮助)


敖丙是一个踏实的程序员,同时他也是一个不安分的人

敖丙总会忍不住地去思考很多事情,比如在大一的暑假思考自己的未来,比如在老东家华为工作时思考自己想不想要打一辈子的工,赚个首付然后做一辈子的房奴,再比如写代码的时候,敖丙会努力思考如何让这行代码更加简洁、更加优雅。

忙忙碌碌一直埋头苦干的日子总是无法俘获他放飞的思想,一成不变的生活无法吸引到他,考虑清楚了更时候自己的东西后,他离开了他的前东家们,并且走上了自媒体这条路。

即使现在一边敲代码一边做自媒体,他脑子也会不断地思考什么样的代码运行起来更好,什么样的内容是大家喜欢又需要的,这些思考穿插在他每一个生活的瞬间,无论是看书、骑车还是其他时刻,他不安分,因为他的脑子从来都不安分。

周一到周五工作时间内的敖丙专心于他的程序员工作,总结出了许多工作经验与工作改进意见,而下班与假期的他则属于自己的媒体账号,坐飞机四处飞地参加活动、深夜剪视频、深夜写稿,每天思考新话题与新的社会动态,这些日子交织起来共同组成了他。

两边工作都想做好,固然是忙碌又疲惫的,当小编问道敖丙是不是很长时间没有休息的时候,敖丙说道,他确实很久没放假了,今年有过几次的旅游不过是在参加活动的时候出去顺便走了走,但他还年轻,他相信以后会有更多的时间去做自己的事情。


行业内卷是必然的,努力提升自己才是面对内卷的第一要领

谈起行业内卷时,敖丙提到身边一些比较优秀的朋友,以前他们的履历去大厂面试就像拥有了绿卡,但是如今面试也开始变得不容易了。

敖丙平时也很关注各家大厂的面试规则,有时候还会亲身去体验面试,往年阿里是不需要面试算法的,今年却加上了,现在对学校的要求也越来越高。

同时敖丙作为一个不安分的人,虽然身处于国内工作环境,却实时关注国外的互联网企业对于面试的要求,发现像 Google、Facebook 这些国人所羡慕的国外大公司,工作压力不比国内大厂小,并且进去的难度也极高。

平日里的敖丙还会专门买一些美国的编程课,去感受一下国外的工作氛围,敖丙笑称,如果不是因为疫情爆发,他今年就计划去国外溜达溜达,切实感受一下外国的编程环境,毕竟纸上得来终觉浅,于他而言,什么都比不上真正去体验实践一番。

讲到这里,敖丙说起关于年轻人为了提高薪酬频繁跳槽的事情,老实说他不太建议这样,即使像他这样不安分的人,如果不是认为公司同事之间相处不愉快、或者不喜欢公司的上班模式、或者认为在公司没有成长空间,只是为了薪资跳槽是不太理性的。

因为程序员是一个长期成长的角色,敖丙主要是基于做新媒体过程中需要更多的私人时间,无法进行加班,考虑到未来的发展进行了跳槽。


关于未来

敖丙还会继续从事程序员工作,但他为自己定了一个目标,等存了足够多的积蓄时,他就结束这种程序员叠加新媒体人的工作状态,他算了算,那一天不会来的太晚。

虽然敖丙每天都在努力赚钱、存钱、攒钱,但是比起钱,他更注重个人知识的积累,在他眼中,钱是一种自然而然的的东西,能力上去它就追随而来,他相信是金子总是会发光的。

现在的他,只需要继续努力、继续学习,继续发挥他的不安分优势,别的不考虑那么多。


小编有话说

一开始和敖丙聊微信时,感觉他是一个很高冷的人,回答简短,话不多说,直到开始了对敖丙的采访,才发现他是一个非常平易近人的人,甚至可以说有点话痨。

采访过程中,时常是小编提出一个问题后,敖丙顺着思路就能一直讲下去,小编准备的一连串问题还没用上,敖丙就把他们都回答了,这其中也穿插着许多他个人有趣的经历在里面,所以采访的过程中,敖丙说得很开心,小编也听得很高兴。

在此非常感谢敖丙愿意让我们了解他的故事,也希望这些故事能对大家有所触动。


欢迎有兴趣参与访谈的小伙伴踊跃报名,《思否有约》将把你与编程有关的故事记录下来。报名邮箱:mango@sifou.com

segmentfault公众号

查看原文

赞 16 收藏 3 评论 2

mshx 赞了文章 · 2020-12-02

极大提高国人开发效率超实用的 VS Code 插件

image
相信好多英语不好的同学在打代码的时候,经常会遇到不懂的单词,也相信好多时候同学写项目时候忘记框架的接口,需要网上翻阅文档,线上提问求助,参考其他项目的示例,那么如果你都过遇到这类问题,那么相信这款 VS Code 插件能极大的帮助到你,它能让您在代码中进行线上/线下搜索,或者翻译的。

使用

介绍下简单的使用过程,你可以在 VS Code 中搜索 Search/Translate Hero 然后点击安装,你也可以在这里进行下载:

image

如果你使用的是国产 Hbuider 编辑器,你可以点击这里进行下载:

搜索

首先,第一个最重要的功能就是搜索,作为开发者,我们每天打代码肯定都离不开搜索,当你在写代码的过程中遇到不明白的库,比如:require('react'),你就可以在编辑器中,选中代码中对应的关键词 react,然后点击鼠标右键,在出现的菜单面板中选择 Search Online 菜单项,插件会自动帮你打开默认浏览器,并搜索对应的关键词和显示搜索结果。

当然你还可以选中对应的关键词后,使用快捷键 cmd+enter(mac) / ctrl+enter(win) 去打开浏览器进行搜索,这样会更高效,再也无需每次切换屏幕到浏览器,输入搜索网址键入关键词然后进行搜索啦。

image

翻译

英文不好的同学的福音,当你在代码中遇到不懂的单词,你可以在编辑器中,选中代码中对应的关键词,然后点击鼠标右键,在出现的菜单面板中选择 Traslate Online 菜单项,插件会自动帮你打开默认浏览器,并进入谷歌翻译搜索,搜索对应的关键词的翻译结果。

同样你还可以选中对应的关键词后,使用快捷键 cmd+shift+enter(mac) / ctrl+shift+enter(win) 去打开浏览器进行翻译。

image

这里还使用了离线英汉词典插件中提供的离线词典库,所以支持了离线词典的搜索,也是跟上面一样相同的操作,选中代码中的关键词,翻译结果会出现在底部栏右下角,简单的翻译无需频繁地咨询百度和谷歌翻译,在底部展示结果,方便也清晰,如果你想查看更详细的翻译结果,可以点击底部栏右下角的中文翻译结果,此时会打开你的默认浏览器进行线上翻译。

image

切换搜索引擎

如果你有其他特别需要,你可以切换不同的搜索引擎,只需要点击在编辑器底部栏右侧 Search Engine,然后在弹窗选项中选择你需要的搜索引擎即可切换。

image

你还可以在右键菜单栏中选择 Search Online By Switch Engine菜单项,直接切换对应的搜索引擎进行搜索。

image

如果预设的搜索引擎地址不能满足你的使用,你可以手动更新搜索引擎地址,进入插件的 Extesion Settings 里设置即可。

image

默认的各搜索引擎地址格式如下:

注意:使用 %SELECTION% 来替换搜索引擎选中的关键词
EngineUrl
Googlehttps://www.google.com/search...
Binghttps://www.bing.com/search?q...
Githubhttps://www.github.com/search...
Baiduhttps://www.baidu.com/search?...
Npmhttps://www.npmjs.com/search?...
Yahoohttps://search.yahoo.com/sear...
Wikihttps://wikipedia.org/wiki/%S...
Duckhttps://duckduckgo.com/?q=%SE...
Code Penhttps://codepen.io/search/pen...
Code Sandboxhttps://codesandbox.io/search...

比如,你可以键入一个颜色网站的搜索引擎,以后打着打着代码就可以随时进入一波贤者模式了(手动滑稽)。

image

哼,你还可以通过修改 .vscode/setting.json 文件,来设置默认搜索引擎,例如修改 search-online.search-engine 的配置参数为 Bing,即可使用 Bing 作为默认搜索引擎来搜索。

{
  "search-online.search-engine": "Bing"
}

通过更改 .vscode/setting.json 文件的 search-online.add-search-engine 的配置参数,可以添加额外的搜索引擎。

{
  "search-online.add-search-engine": [
    {
      "name": "Visual Studio Marketplace",
      "url": "https://marketplace.visualstudio.com/search?term=%SELECTION%&target=VSCode"
    },
    {
      "name": "Pypi",
      "url": "https://pypi.org/search/?q=%SELECTION%"
    }
  ]
}

如果你嫌上面的操作都很麻烦,那你还可以通过可视化界面来增加搜索引擎,在切换引擎的面板底部点击 ➕ Add Search Engine,然后会出现两次输入框,分别填入如以下内容,即可增加搜索引擎↓

name: Visual Studio Marketplace

url: https://marketplace.visualstu...

image

有了这些,你可以一键在 Github 上搜索相关代码,在 Npm 搜索相关的工具库,在 Wiki 检索专业得词条,在 Duck Duck Go 留下你不可告人的小秘密,在 Code Pen 粘贴几段小代码回来,总之就是不讲道理,毫无武德。

image

切换翻译引擎

一般情况,你可以在设置面板更改需要翻译的语言,默认设置是英文翻译成中文。

image

但是如果遇到二般情况,比如遇上俄国人写的代码和注释,你想翻译一下,那么你可以把翻译引擎切换到俄语翻译成中文的设置,这里支持世界上大部分语言的线上翻译,谷歌翻译是个好东西,后续会增加百度翻译引擎的支持,请大家多多资瓷啦~

感谢

最后如果插件对您有帮助,恳请您在 插件商城 中给我们一个五星好评,您的鼓励是我前进的最大动力!

如果您有任何问题和建议,您可以进入 反馈链接 留言,我会尽快回复您。

查看原文

赞 14 收藏 8 评论 0

mshx 收藏了文章 · 2020-07-24

Laradock中运行Laravel之初体验

说明

本文不是Docker入门教程, 而是Laradock的入门教程, 使用Laradock可以方便高效地搭建兼容各平台的PHP开发环境.

上手Laradock需要一些Docker基础, 得知道Dockerfile文件和docker-compsoe.yml文件是干嘛用的

要解决的问题

  • Laradock中启动Nginx、MySQL、PHP、Redis服务运行一个全新的Laravel项目
  • 一个Laradock运行多个项目
  • 后期切换MySQL、PHP版本
  • 添加PHP扩展

操作环境

  • 主机: macOS 10.15
  • Docker Desktop community: 2.2.0 (Engin: 19.03) (已配置阿里的docker镜像加速)
  • Composer: 1.9
  • Git: 2.23

一些约定

  • 下文用到的主机命令别名: alias dr="docker " alias ds="docker-compose ", 即docker 简写成dr
  • 下面演示中的Laradock和Laravel代码都放置在~/_code/目录下

安装

Laradock默认是给单一项目搭建环境的, 但也可以设置成支持多项目的, 区别在于Laradock目录与项目目录的相对位置.

例如我的全部项目代码都是放置在~/_code/目录下的, 项目1的目录是~/_code/project_1/, 项目2的目录是~/_code/project_2/如此类推.

那多项目模式的Laradock目录结构如下:

~/_code/
    laradock/
    project_1/
    project_2/

单项目模式(也就是将laradock作为一个项目的子项目):

~/_code/
    project_3/
        laradock/
        项目3的其它目录/

多项目模式对于运行多个对环境无特别要求的项目的情况比较方便; 单项目模式对于专门给个别项目适配特定的服务比较有针对性, 同时还可以把laradock作为子项目一并提交到版本管理, 当需要在别处部署项目的时候代码和执行环境可以一步到位, 特别方便.

因此, 我个人建议是这两种模式可以根据面临的情况选择使用, 先搭一套多项目模式的, 一般情况就这个就够了, 然后其它情况特殊的就用单项目模式的. 下面我以多项目模式来演示.

下载

cd ~/_code/
git clone https://github.com/Laradock/laradock.git

配置

# 演示的Laradock目录在 `~/_code/laradock/`
cd laradock/
cp env-example .env

修改.env如下:

# 下面开始的是重点!
# 指定要挂载进容器的目录,也就是项目代码在主机的目录
APP_CODE_PATH_HOST=../

# 将`APP_CODE_PATH_HOST`指定的目录挂载进到容器(如workspack、php-fpm容器)内相应哪个位置
APP_CODE_PATH_CONTAINER=/var/www

# MySQL,Redis等数据持久化保存在主机的什么位置,可以自定义目录的
DATA_PATH_HOST=~/.laradock/general_data

# 给这个laralock(docker-compose)项目取个名字,这个名字将会作为未来启动的容器的命名前缀,不能与其它laradock重名.默认是`laradock`,当然也可以设置成`aaa`
COMPOSE_PROJECT_NAME=general

# php-cli和php-fpm的版本,目前可选填: 7.4 - 7.3 - 7.2 - 7.1 - 7.0 - 5.6
PHP_VERSION=7.3

# MySQL的版本,latest是最新版8.0.x,写5.7会给你安装5.7.x的最新版
MYSQL_VERSION=5.7

# 在国内网络环境下加快容器内的一些下载,默认采用阿里的镜像
CHANGE_SOURCE=true

# 设置时区,会影响到所有运行的容器,PRC是指中国
WORKSPACE_TIMEZONE=PRC


# 下面开始的是看情况有选择地操作:
# 设置composer镜像
WORKSPACE_COMPOSER_REPO_PACKAGIST=https://mirrors.aliyun.com/composer/
# Node镜像
WORKSPACE_NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node
# NPM镜像
WORKSPACE_NPM_REGISTRY=https://registry.npm.taobao.org/

# 修改映射端口,是为了避免与其它laradock或是主机端口冲突, 如果确定没有冲突的可以不用更改
# workspace相关端口
WORKSPACE_SSH_PORT=12222
WORKSPACE_VUE_CLI_SERVE_HOST_PORT=18080
WORKSPACE_VUE_CLI_UI_HOST_PORT=18001
# Nginx服务相关端口
NGINX_HOST_HTTP_PORT=10080
NGINX_HOST_HTTPS_PORT=10443
VARNISH_BACKEND_PORT=10081
# MySQL端口
MYSQL_PORT=13306
# Reids端口
REDIS_PORT=16379
# phpMyAdmin端口
PMA_PORT=18888
# phpRedisAdmin端口
REDIS_WEBUI_PORT=19987

选装PHP扩展

PHP扩展在laradock里是分成 PHP-CLI扩展和PHP-FPM扩展的, 因为它们分别位于两个容器中(PHP-CLI在workspace容器内, PHP-FPM单独一个容器), 可以根据情况只装一边或两边都装.

PHP-CLI默认扩展:
[PHP Modules]
ast
bcmath
calendar
Core
ctype
curl
date
dom
exif
fileinfo
filter
ftp
gd
gettext
hash
iconv
igbinary
intl
json
libxml
mbstring
memcached
msgpack
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_pgsql
pdo_sqlite
pgsql
Phar
posix
readline
redis
Reflection
session
shmop
SimpleXML
sockets
sodium
SPL
sqlite3
standard
sysvmsg
sysvsem
sysvshm
tokenizer
wddx
xml
xmlreader
xmlwriter
xsl
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache
PHP-FPM默认扩展:
[PHP Modules]
bcmath
Core
ctype
curl
date
dom
fileinfo
filter
ftp
gd
hash
iconv
imagick
intl
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcre
PDO
pdo_mysql
pdo_pgsql
pdo_sqlite
Phar
posix
readline
redis
Reflection
session
SimpleXML
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache
同时给PHP-CLI和PHP-FPM安装swoole扩展的配置

编辑.env

# PHP-CLI
WORKSPACE_INSTALL_SWOOLE=true
# PHP-FPM
PHP_FPM_INSTALL_SWOOLE=true

可选的PHP扩展都是WORKSPACE_INSTALL_*PHP_FPM_INSTALL_*这种格式的, 类似的扩展选项还有很多, 可以自行选用.

不安装Node的情况

如果你在容器中安装Node时因为网络问题出错(如图示), 或是在主机已经安装了Node, 不需要在容器中执行Node命令, 那可以不安装Node.

# 都设为false就不安装了
WORKSPACE_INSTALL_NODE=false
WORKSPACE_INSTALL_YARN=false
# 不安装的时候也不要有填写镜像地址,否则报错
WORKSPACE_NVM_NODEJS_ORG_MIRROR=
WORKSPACE_NPM_REGISTRY=

安装中可能的网络错误:
截屏2020-03-1500.40.52.png
(像上图这种情况, 如果还是坚持要Node的话可以采用全局科学上网的方式安装)

运行

启动服务

注意: 每次执行docker-compose命令时, 需要确保当前命令行所在的目录有docker-compose.yml文件, 在当前的演示中即为~/_code/laradock/目录

# 进入laradock根目录
cd ~/_code/laradock/
# 一次性启动 Nginx MySQL Redis phpMyAdmin phpRedisAdmin PHP-FPM workspace
# laradock在启动Nginx容器时会自动连带启动PHP-FPM和workspace容器,因此在启动命令中可以省略不写这两个
# `-d`参数指以守护进程方式运行,redis-webui是phpRedisAdmin的服务名
# 可以逐个启动, 如: `ds up -d mysql`
ds up -d nginx mysql redis phpmyadmin redis-webui
# 列出当前docker-compose项目下的所有容器
ds ps
# 关闭当前项目的所有容器并移除: `ds down`

如果是第一次启动, 那么laradock会根据配置生成各个docker镜像, 然后再启动这些镜像, 所需时间取决于所处环境的网速和要安装的东西的量的多少, 例如不装Node、Yarn和额外的PHP扩展就比装的时间短.

成功启动后会有如下的提示
截屏2020-03-1600.39.36.png

可以看到之前在.env中设置的项目名general已经成为了容器名的前缀

另外还可以通过命令docker exec -it [container-name] bash进入容器

截屏2020-03-1500.45.54.jpg
默认情况下workspace容器会装有Composer、Node、Yarn、Git等工具

更改PHP版本

例如要将php从之前设置的7.3更改为7.4

先修改.env的php版本参数

PHP_VERSION=7.4

然后重新生成PHP-FPM和workspace容器的镜像, 再重新启动即可

ds build php-fpm workspace
ds up -d php-fpm workspace

# 进入 workspace 服务在当前项目下的容器 general_workspace_1 查看PHP-CLI版本
dr exec -it general_workspace_1 bash
# 类似地, 查看PHP-FPM版本
dr exec -it general_php-fpm_1 bash

截屏2020-03-1601.53.29.png

更改MySQL版本

例如要将MySQL从之前设置的5.7更改为8.0

先修改Laradock.env的php版本参数

PHP_VERSION=8.0

更改数据库涉及持久化的数据文件问题, 需要专门另外处理

# 大版本之间的MySQL数据库文件存在不兼容的问题,所以要迁移旧或删除旧数据库文件
# 停止mysql容器, 防止操作还生成数据库文件
ds stop mysql
# 迁移旧数据库文件
mv ~/.laradock/general_data/mysql ~/.laradock/general_data/mysql_5.7
# 重新生成镜像
ds build mysql
# 按镜像启动
ds up -d mysql
# 可参考更改php版本一节查看mysql版本

使用

跑一个laravel项目

在主机使用composer创建一个6.x版本的laravel新项目, 取名为lv6_2, 使用本地域名lv6_2.test运行

下载Laravel并修改配置

cd ~/_code/
composer create-project --prefer-dist laravel/laravel:^6 lv6_2
cp .env.example .env

此时lv6_2目录已经出现在容器的挂载目录中
截屏2020-03-1517.54.08.png
修改Laravel的.env文件

# 代码是在容器内运行的,容器之间的通信地址就是服务名,所以这里的数据库地址写`mysql`
DB_HOST=mysql
# 容器内用的是默认的端口
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=root
DB_PASSWORD=root

REDIS_HOST=redis
REDIS_PORT=6379

之前在Laradock的.env文件中给MySQL设置的端口13306是映射到物理主机的端口, 即在主机连接容器中的MySQL时都用13306, 容器之间还是3306, Redis也是一样的道理.

修改主机hosts文件

# 要确保主机当前用户有修改hosts的权限
echo '127.0.0.1  lv6_2.test' >> /etc/hosts

添加nginx站点配置文件并重启

复制默认配置文件

cd ~/_code/laradock/nginx/sites
cp laravel.conf.example lv6_2.test.conf

修改lv6_2.test.conf关键参数

# 就改这两个就可以
server_name lv6_2.test;
root /var/www/lv6_2/public;

重启nginx容器

cd ~/_code/laradock/
ds restart nginx

运行项目

编辑~/_code/lv6_2/routes/web.php路由文件, 加入MySQL和Redis的测试代码

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

Route::prefix('t')->group(function () {

    Route::get('db', function () {
        dump(DB::select('select version()'));

        dump(Redis::incr('incr_key'));

        dd('db end');
    });
  
});

浏览器访问 http://lv6_2.test:10080/t/db
截屏2020-03-1423.22.59.png

正常显示则说明MySQL和Redis的连接没有问题

主机命令行连接MySQL和Redis

此前已经将MySQL和Redis的端口映射成1330616379,要如下连接

# redis
redis-cli -p 16379
# mysql 划重点! 注意参数`-h127.0.0.1` 不能用默认值不能不写
mysql -u root -proot -h127.0.0.1 -P 13306

截屏2020-03-1423.31.26.png

MySQL的host参数不能用localhost是因为它默认是通过sock文件与mysql通信,而容器与主机文件系统已经隔离,所以需要通过TCP方式连接,所以需要指定IP。

phpMyAdmin

浏览器访问http://127.0.0.1:18888, 要注意服务器这一个参数, 这是容器之间访问数据库, 要写成数据库容器的服务名mysql
截屏2020-03-1417.10.35.png

截屏2020-03-1417.12.37.png

phpRedisAdmin

浏览器访问http://127.0.0.1:19987, 这个账号和密码在laradock的.env文件有, 分别是REDIS_WEBUI_USERNAMEREDIS_WEBUI_PASSWORD
截屏2020-03-1501.12.41.png

截屏2020-03-1501.14.14.png

结语

从Docker到Laradock, 学习成本是有的, 但也是绝对值得的. 使用Laradock搭建环境是跨平台的, 高效的, 而且还相当的酷!

本文对Laradock的介绍只是很基础的一部分, 其实它里面还集合了好多好多有用的工具, 如netdata、protainer和rabbitmq等等, 这将是接下来要探索的东西🌏

以上是本人的一些实践经验, 欢迎留言交流😃

参考资料

查看原文

mshx 赞了文章 · 2020-07-24

Laradock中运行Laravel之初体验

说明

本文不是Docker入门教程, 而是Laradock的入门教程, 使用Laradock可以方便高效地搭建兼容各平台的PHP开发环境.

上手Laradock需要一些Docker基础, 得知道Dockerfile文件和docker-compsoe.yml文件是干嘛用的

要解决的问题

  • Laradock中启动Nginx、MySQL、PHP、Redis服务运行一个全新的Laravel项目
  • 一个Laradock运行多个项目
  • 后期切换MySQL、PHP版本
  • 添加PHP扩展

操作环境

  • 主机: macOS 10.15
  • Docker Desktop community: 2.2.0 (Engin: 19.03) (已配置阿里的docker镜像加速)
  • Composer: 1.9
  • Git: 2.23

一些约定

  • 下文用到的主机命令别名: alias dr="docker " alias ds="docker-compose ", 即docker 简写成dr
  • 下面演示中的Laradock和Laravel代码都放置在~/_code/目录下

安装

Laradock默认是给单一项目搭建环境的, 但也可以设置成支持多项目的, 区别在于Laradock目录与项目目录的相对位置.

例如我的全部项目代码都是放置在~/_code/目录下的, 项目1的目录是~/_code/project_1/, 项目2的目录是~/_code/project_2/如此类推.

那多项目模式的Laradock目录结构如下:

~/_code/
    laradock/
    project_1/
    project_2/

单项目模式(也就是将laradock作为一个项目的子项目):

~/_code/
    project_3/
        laradock/
        项目3的其它目录/

多项目模式对于运行多个对环境无特别要求的项目的情况比较方便; 单项目模式对于专门给个别项目适配特定的服务比较有针对性, 同时还可以把laradock作为子项目一并提交到版本管理, 当需要在别处部署项目的时候代码和执行环境可以一步到位, 特别方便.

因此, 我个人建议是这两种模式可以根据面临的情况选择使用, 先搭一套多项目模式的, 一般情况就这个就够了, 然后其它情况特殊的就用单项目模式的. 下面我以多项目模式来演示.

下载

cd ~/_code/
git clone https://github.com/Laradock/laradock.git

配置

# 演示的Laradock目录在 `~/_code/laradock/`
cd laradock/
cp env-example .env

修改.env如下:

# 下面开始的是重点!
# 指定要挂载进容器的目录,也就是项目代码在主机的目录
APP_CODE_PATH_HOST=../

# 将`APP_CODE_PATH_HOST`指定的目录挂载进到容器(如workspack、php-fpm容器)内相应哪个位置
APP_CODE_PATH_CONTAINER=/var/www

# MySQL,Redis等数据持久化保存在主机的什么位置,可以自定义目录的
DATA_PATH_HOST=~/.laradock/general_data

# 给这个laralock(docker-compose)项目取个名字,这个名字将会作为未来启动的容器的命名前缀,不能与其它laradock重名.默认是`laradock`,当然也可以设置成`aaa`
COMPOSE_PROJECT_NAME=general

# php-cli和php-fpm的版本,目前可选填: 7.4 - 7.3 - 7.2 - 7.1 - 7.0 - 5.6
PHP_VERSION=7.3

# MySQL的版本,latest是最新版8.0.x,写5.7会给你安装5.7.x的最新版
MYSQL_VERSION=5.7

# 在国内网络环境下加快容器内的一些下载,默认采用阿里的镜像
CHANGE_SOURCE=true

# 设置时区,会影响到所有运行的容器,PRC是指中国
WORKSPACE_TIMEZONE=PRC


# 下面开始的是看情况有选择地操作:
# 设置composer镜像
WORKSPACE_COMPOSER_REPO_PACKAGIST=https://mirrors.aliyun.com/composer/
# Node镜像
WORKSPACE_NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node
# NPM镜像
WORKSPACE_NPM_REGISTRY=https://registry.npm.taobao.org/

# 修改映射端口,是为了避免与其它laradock或是主机端口冲突, 如果确定没有冲突的可以不用更改
# workspace相关端口
WORKSPACE_SSH_PORT=12222
WORKSPACE_VUE_CLI_SERVE_HOST_PORT=18080
WORKSPACE_VUE_CLI_UI_HOST_PORT=18001
# Nginx服务相关端口
NGINX_HOST_HTTP_PORT=10080
NGINX_HOST_HTTPS_PORT=10443
VARNISH_BACKEND_PORT=10081
# MySQL端口
MYSQL_PORT=13306
# Reids端口
REDIS_PORT=16379
# phpMyAdmin端口
PMA_PORT=18888
# phpRedisAdmin端口
REDIS_WEBUI_PORT=19987

选装PHP扩展

PHP扩展在laradock里是分成 PHP-CLI扩展和PHP-FPM扩展的, 因为它们分别位于两个容器中(PHP-CLI在workspace容器内, PHP-FPM单独一个容器), 可以根据情况只装一边或两边都装.

PHP-CLI默认扩展:
[PHP Modules]
ast
bcmath
calendar
Core
ctype
curl
date
dom
exif
fileinfo
filter
ftp
gd
gettext
hash
iconv
igbinary
intl
json
libxml
mbstring
memcached
msgpack
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_pgsql
pdo_sqlite
pgsql
Phar
posix
readline
redis
Reflection
session
shmop
SimpleXML
sockets
sodium
SPL
sqlite3
standard
sysvmsg
sysvsem
sysvshm
tokenizer
wddx
xml
xmlreader
xmlwriter
xsl
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache
PHP-FPM默认扩展:
[PHP Modules]
bcmath
Core
ctype
curl
date
dom
fileinfo
filter
ftp
gd
hash
iconv
imagick
intl
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcre
PDO
pdo_mysql
pdo_pgsql
pdo_sqlite
Phar
posix
readline
redis
Reflection
session
SimpleXML
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache
同时给PHP-CLI和PHP-FPM安装swoole扩展的配置

编辑.env

# PHP-CLI
WORKSPACE_INSTALL_SWOOLE=true
# PHP-FPM
PHP_FPM_INSTALL_SWOOLE=true

可选的PHP扩展都是WORKSPACE_INSTALL_*PHP_FPM_INSTALL_*这种格式的, 类似的扩展选项还有很多, 可以自行选用.

不安装Node的情况

如果你在容器中安装Node时因为网络问题出错(如图示), 或是在主机已经安装了Node, 不需要在容器中执行Node命令, 那可以不安装Node.

# 都设为false就不安装了
WORKSPACE_INSTALL_NODE=false
WORKSPACE_INSTALL_YARN=false
# 不安装的时候也不要有填写镜像地址,否则报错
WORKSPACE_NVM_NODEJS_ORG_MIRROR=
WORKSPACE_NPM_REGISTRY=

安装中可能的网络错误:
截屏2020-03-1500.40.52.png
(像上图这种情况, 如果还是坚持要Node的话可以采用全局科学上网的方式安装)

运行

启动服务

注意: 每次执行docker-compose命令时, 需要确保当前命令行所在的目录有docker-compose.yml文件, 在当前的演示中即为~/_code/laradock/目录

# 进入laradock根目录
cd ~/_code/laradock/
# 一次性启动 Nginx MySQL Redis phpMyAdmin phpRedisAdmin PHP-FPM workspace
# laradock在启动Nginx容器时会自动连带启动PHP-FPM和workspace容器,因此在启动命令中可以省略不写这两个
# `-d`参数指以守护进程方式运行,redis-webui是phpRedisAdmin的服务名
# 可以逐个启动, 如: `ds up -d mysql`
ds up -d nginx mysql redis phpmyadmin redis-webui
# 列出当前docker-compose项目下的所有容器
ds ps
# 关闭当前项目的所有容器并移除: `ds down`

如果是第一次启动, 那么laradock会根据配置生成各个docker镜像, 然后再启动这些镜像, 所需时间取决于所处环境的网速和要安装的东西的量的多少, 例如不装Node、Yarn和额外的PHP扩展就比装的时间短.

成功启动后会有如下的提示
截屏2020-03-1600.39.36.png

可以看到之前在.env中设置的项目名general已经成为了容器名的前缀

另外还可以通过命令docker exec -it [container-name] bash进入容器

截屏2020-03-1500.45.54.jpg
默认情况下workspace容器会装有Composer、Node、Yarn、Git等工具

更改PHP版本

例如要将php从之前设置的7.3更改为7.4

先修改.env的php版本参数

PHP_VERSION=7.4

然后重新生成PHP-FPM和workspace容器的镜像, 再重新启动即可

ds build php-fpm workspace
ds up -d php-fpm workspace

# 进入 workspace 服务在当前项目下的容器 general_workspace_1 查看PHP-CLI版本
dr exec -it general_workspace_1 bash
# 类似地, 查看PHP-FPM版本
dr exec -it general_php-fpm_1 bash

截屏2020-03-1601.53.29.png

更改MySQL版本

例如要将MySQL从之前设置的5.7更改为8.0

先修改Laradock.env的php版本参数

PHP_VERSION=8.0

更改数据库涉及持久化的数据文件问题, 需要专门另外处理

# 大版本之间的MySQL数据库文件存在不兼容的问题,所以要迁移旧或删除旧数据库文件
# 停止mysql容器, 防止操作还生成数据库文件
ds stop mysql
# 迁移旧数据库文件
mv ~/.laradock/general_data/mysql ~/.laradock/general_data/mysql_5.7
# 重新生成镜像
ds build mysql
# 按镜像启动
ds up -d mysql
# 可参考更改php版本一节查看mysql版本

使用

跑一个laravel项目

在主机使用composer创建一个6.x版本的laravel新项目, 取名为lv6_2, 使用本地域名lv6_2.test运行

下载Laravel并修改配置

cd ~/_code/
composer create-project --prefer-dist laravel/laravel:^6 lv6_2
cp .env.example .env

此时lv6_2目录已经出现在容器的挂载目录中
截屏2020-03-1517.54.08.png
修改Laravel的.env文件

# 代码是在容器内运行的,容器之间的通信地址就是服务名,所以这里的数据库地址写`mysql`
DB_HOST=mysql
# 容器内用的是默认的端口
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=root
DB_PASSWORD=root

REDIS_HOST=redis
REDIS_PORT=6379

之前在Laradock的.env文件中给MySQL设置的端口13306是映射到物理主机的端口, 即在主机连接容器中的MySQL时都用13306, 容器之间还是3306, Redis也是一样的道理.

修改主机hosts文件

# 要确保主机当前用户有修改hosts的权限
echo '127.0.0.1  lv6_2.test' >> /etc/hosts

添加nginx站点配置文件并重启

复制默认配置文件

cd ~/_code/laradock/nginx/sites
cp laravel.conf.example lv6_2.test.conf

修改lv6_2.test.conf关键参数

# 就改这两个就可以
server_name lv6_2.test;
root /var/www/lv6_2/public;

重启nginx容器

cd ~/_code/laradock/
ds restart nginx

运行项目

编辑~/_code/lv6_2/routes/web.php路由文件, 加入MySQL和Redis的测试代码

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

Route::prefix('t')->group(function () {

    Route::get('db', function () {
        dump(DB::select('select version()'));

        dump(Redis::incr('incr_key'));

        dd('db end');
    });
  
});

浏览器访问 http://lv6_2.test:10080/t/db
截屏2020-03-1423.22.59.png

正常显示则说明MySQL和Redis的连接没有问题

主机命令行连接MySQL和Redis

此前已经将MySQL和Redis的端口映射成1330616379,要如下连接

# redis
redis-cli -p 16379
# mysql 划重点! 注意参数`-h127.0.0.1` 不能用默认值不能不写
mysql -u root -proot -h127.0.0.1 -P 13306

截屏2020-03-1423.31.26.png

MySQL的host参数不能用localhost是因为它默认是通过sock文件与mysql通信,而容器与主机文件系统已经隔离,所以需要通过TCP方式连接,所以需要指定IP。

phpMyAdmin

浏览器访问http://127.0.0.1:18888, 要注意服务器这一个参数, 这是容器之间访问数据库, 要写成数据库容器的服务名mysql
截屏2020-03-1417.10.35.png

截屏2020-03-1417.12.37.png

phpRedisAdmin

浏览器访问http://127.0.0.1:19987, 这个账号和密码在laradock的.env文件有, 分别是REDIS_WEBUI_USERNAMEREDIS_WEBUI_PASSWORD
截屏2020-03-1501.12.41.png

截屏2020-03-1501.14.14.png

结语

从Docker到Laradock, 学习成本是有的, 但也是绝对值得的. 使用Laradock搭建环境是跨平台的, 高效的, 而且还相当的酷!

本文对Laradock的介绍只是很基础的一部分, 其实它里面还集合了好多好多有用的工具, 如netdata、protainer和rabbitmq等等, 这将是接下来要探索的东西🌏

以上是本人的一些实践经验, 欢迎留言交流😃

参考资料

查看原文

赞 6 收藏 6 评论 0

mshx 赞了文章 · 2020-05-15

不满公司有毒文化,亚马逊技术副总裁愤而离职

疫情期间,亚马逊工人争取更多防护和福利的意见,遭到了该公司的严厉打压。发起请愿或抗议的工人,纷纷遭到了辞退。日前亚马逊副总裁 Tim Bray,因不满公司这种不人道的做法,发布了一篇辞职博文,直指公司企业文化有毒。

放弃数百万薪资,不满亚马逊打压员工,亚马逊技术副总裁 Tim Bray 因为一封离职博客,引发了全网的关注。

他毫不客气地指出,亚马逊以多种理由,威胁和解雇试图维权的员工。这也让更多人开始审视疫情下的科技巨头,到底是如何对待旗下的员工。

与此同时,亚马逊日前又有一名仓库工人因新冠肺炎去世,当前已累计有三名员工死于新冠。

 大牛放弃百万薪资,只为发声抗议

4 月底,Tim Bray 发布了一篇名为《再见了,亚马逊》的博客长文,宣告他将于 5 月 1 日离职,文章里论述了他离职的原因,并直指亚马逊公司文化有毒。

今年 64 岁的 Tim Bray,是一位顶级软件工程师,他被尊称为「XML之父」,是搜索引擎的发明人,也是可在线检索的牛津英文字典的发明人,曾和比尔盖茨一起入选北美 100 名人。

此图像的alt属性为空;文件名为640

Tim Bray:XML 之父,搜索引擎之叔

他于 1973 年在贝鲁特美国大学毕业,后续在加拿大的圭尔夫大学拿到了硕士和博士学位。

此后在多家科技公司一路打怪升级,曾创办过自己的科技公司,于 2010 加入谷歌 Android 团队,2014 年加入亚马逊,离职前担任技术副总裁,首席工程师,薪资超 100 万美元。

此图像的alt属性为空;文件名为640

Tim Bray 的部分工作履历

而这些靠自己打拼来的优越条件,都抵不过他想为员工发声的念头。

不满公司有毒文化,发长文愤而辞职

员工抗议遭解雇,大牛出离愤怒  

让 Tim Bray 怒而离职的原因,都在于亚马逊近期对员工的一些迷之行为。

3 月份,就有员工股因为亚马逊对员工防护不力而发起抗议,此后罢工活动的发起人 Christian Smalls,被亚马逊找借口开除。

此图像的alt属性为空;文件名为640

工人举牌抗议亚马逊

4 月,公开批评公司劳工政策的两位用户体验设计师 Emily Cunningham 和 Maren Costa,在发起请愿当天就遭遇了解雇。

这些事招致了 Tim bray 的不满,随后又有多起组织请愿或抗议的事件,均无一例外被公司进行了解雇。最终让 Tim 彻底失望并选择了辞职。

痛斥公司有毒文化,不愿同流合污  

Bray 在博文中表示,亚马逊对组织抗议活动员工进行解雇和贬低,实际上是「懦夫」的行为,并称解雇员工实际上是在营造恐惧。

他认为该做法完全背离了人道主义,不看重个人的自由和权利的平衡,而是试图用镇压的方式,平息不同的声音,这一切都不可理喻。

此图像的alt属性为空;文件名为640

Tim Bray 的离职信截图

Bray 还指出:解雇举报人的做法,证明公司中存在着一条贯穿公司文化的「毒脉」,所以我选择既不服务也不喝这种「毒药」。

他也在文章中指出这种现象不仅是亚马逊的专有,而是许多大厂都有的一个问题,甚至是资本主义文化的一个弊病。

最后他写到,「我很难过,但我现在感觉自己的呼吸更自由了。」

亚马逊的回应还迟迟未到

这份引发全网关注的辞职信,亚马逊目前拒绝发表评论。

好玩的是,我们在之前在《贝佐斯发布年度股东信,是什么让商界每年必读变了味?》一文中,报道了首富先生贝佐斯不久前在 2020 年度的股东信中,吹嘘了一波亚马逊的企业文化。

此图像的alt属性为空;文件名为640

这么快就被得力手下将了一军,不知老贝会不会有所触动。

查看原文

赞 2 收藏 0 评论 0

mshx 关注了用户 · 2020-04-29

CrazyCodes @crazycodes

https://github.com/CrazyCodes... 我的博客
_
| |__ __ _
| '_ | | | |/ _` |
| |_) | |_| | (_| |
|_.__/ \__,_|\__, |

         |___/   感谢生命可以让我成为一名程序员

                         CrazyCodes To Author

关注 4682

mshx 收藏了文章 · 2020-04-29

初中级PHP面试基础汇总

timg.jpeg

这是我整理的一套面试题,老铁们看看就当复习了哦

概述

感觉现在发面试题有些冷门,就跟昨天德国那场似的,不过看看当提前复习了。提前备战。这2个月出门面试的童鞋可注意不要中暑哦。

说几个你所知道的设计模式

单例模式

保证一个类仅有一个实例,并提供一个访问他的全局访问点例如框架中的数据库连接 - 类似DB类

策略模式

针对一组算法,将每一个算法封装到具有共同接口的独立的类中,例如进入个人主页时,根据浏览者的不同,给予不同的显示与操作 - 类似不同用户呈现不同效果

注册模式

提供了在程序中有条理的存放并管理一组全局对象 (object) - 类似服务提供者的注入

适配器模式

将不同接口适配成统一的API接口,例如数据操作有mysql、mysqli、pdo等,可利用适配器模式统一接口

观察者模式

一个对象通过添加一个方法使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。例如实现实现消息推送 - 将所有类的实例化注册到一个数组,通过循环批量执行类

装饰器模式

不修改原类代码和继承的情况下动态扩展类的功能,例如框架的每个Controller文件会提供before和after方法 - 在某个方法或输出之前执行或之后执行,用于修饰

迭代器模式

提供一个方法顺序访问一个聚合对象中各个元素,在PHP中将继承 Iterator 类 - yield

POST和GET有什么区别

  1. GET是从服务器上获取数据,POST是向服务器传送数据
  2. GET是通过发送HTTP协议通过URl参数传递进行接收,而POST是实体数据,通过表单提交
  3. GET传送的数据量较小,不能大于2KB。POST传送的数据量较大,一般被默认为不受限制。
  4. GET安全性非常低,POST安全性较高

session与cookie的区别

  1. session存储在服务器上的php指定目录中(session_dir)的位置
  2. cookie存储在客户端

数据库中的事务是什么?

指作为一个单元的一组有序的数据库操作,如果组中的所有操作都成功,则认为事务成功,即使有一个操作失败。事务也不成功,如果所有操作完成,事务提交,其修改将作用于所有其他数据库进程,如果有一个操作失败,则事务回滚,该事务影响到的操作都会取消。

PHP中传引用与传值的区别?

按值传递:函数内对值的内容改变对函数外部无影响
引用传递:函数内对值的内容改变在函数外部也会做出相应修改

MYSQL优化方案有哪些?

  1. 选用适合的字段类型,避免数据库增加不必要的空间,字段尽量设定为NOTNULL,类似性别,省份尽量使用枚举类型ENUM
  2. 使用JOIN查询代替子查询
  3. 使用UNION代替临时表
  4. 尽量不使用外键、除非必须保持数据表与表之间的一致性、完整性
  5. 尽量不使用视图
  6. 分表分库,读写分离
  7. 合理设置主键及索引

    • 索引分为:普通索引、唯一索引、全文索引、主键(也是一种唯一索引)
  8. 后期演变的数据表优化

    - 垂直拆分:表数据拆分到不同表中,按照业务拆分
    - 水平拆分:行数据拆分到不同表中,按照时间、类型、身份等因素拆分表
    - 水平垂直联合拆分

9.索引建立原则

  - 最左前缀匹配原则
  - 索引列尽量不参与计算
  - 尽量扩展索引不要新建索引

面向对象编程的五个基本原则 (S.O.L.I.D)

  1. SRP 单一功能原则 (你可以这样干,并不是说你应该这样干)

    - 引起类变化的因素永远不要多余一个,保证类的有且只有一个责任
  2. OCP 开闭原则 (开胸手术时不需要穿一件外套)

    - 对扩展开放,对修改闭合
  3. LSP 里氏替换原则

    - 当一个子类的实例应该能够替换任何其父类的实例时,它们之间才具有IS-A关系
  4. ISP 接口隔离原则

    - 不要强迫客户端(泛指调用者)去依赖那些他们不使用的接口
  5. DIP 依赖反转原则

    • 高层模块不应该依赖底层模块,两者都应该依赖其抽象
    • 抽象不应该依赖于细节,细节应该依赖于抽象

yield的使用

生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。

子类重写父类的protected方法有什么限制?

  1. final修饰的类方法不可被子类重写
  2. 5.3以后方法参数个数必须一致
  3. 重写时访问级别只可以等于或者宽松于当前重写方法的访问级别

什么是CGI? 什么是FastCGI? php-fpm , FastCGI,Nginx 之间是什么关系?

CGI 是通用网关接口,用户WEB服务器和应用程序间的交互,定义输入输出规范,用户的请求通过WEB服务器转发给FastCGI进程,FastCGI进程再调用应用程式进行处理,如PHP解析器,应用程序的处理结果如HTML返回给FastCGI,FastCGI返回给Nginx进行输出,假设WEB服务器是NGINX,应用程序是PHP,而 php-fpm 是管理FastCGI的,这就是php-fpm,fastCGI与NGINX的关系.

FastCGI 用来提高cgi程序性能,启动一个master,再启动多个worker,不需要每次解析php.ini 而php-fpm实现了fastcgi协议,是fastcgi的进程管理器,支持平滑重启可以启动的时候预先生成多个进程。

什么是 CSRF 攻击 ?XSS 攻击?如何防范?

CSRF,跨站请求伪造,攻击方伪装用户身份发送请求从而窃取信息或者破坏系统。
防范

  1. 合理规范api请求方式,GET,POST
  2. 对POST请求加token令牌验证,生成一个随机码并存入session,表单中带上这个随机码,提交的时候服务端进行验证随机码是否相同。

XSS,跨站脚本攻击。
防范

  1. 不相信任何输入,过滤输入。

基本算法

顺序查找

function search($arr,$k){
  $n = count($arr);
    $arr[$n]= $k;
    for($i=0; $i<$n; $i++){
        if($arr[$i]==$k){
        break;
        }
    }
    if ($i<$n){
        return $i;
    }else{
        return -1;
    }
}

二分查找

function binaryRecursive($arr,$low,$top,$target){
        if($low<=$top){
            $mid = floor(($low+$top)/2);
            if($arr[$mid]==$target){
                return $arr[$mid];
            }elseif($arr[$mid]<$target){
                return binaryRecursive($arr,$mid+1,$top,$target);
            }else{
                return binaryRecursive($arr,$low,$top-1,$target);
            }
        }else{
            return -1;
        }
    }

冒泡排序

function _sort($arr)
    {
        $count = count ($arr) - 1;
        $temp  = 0;
        
        for ($i = 0; $i < $count; $i++) {
        
            for ($j = 0; $j < $count - $i; $j++) {
                if ($arr[$j] < $arr[$j + 1]) {
                    $temp        = $arr[$j];
                    $arr[$j]     = $arr[$j + 1];
                    $arr[$j + 1] = $temp;
                }
            }
        }
        
        return $arr;
    }

快速排序

function quick_sort($arr)
{
    //判断参数是否是一个数组
    if(!is_array($arr)) {
        return false;
    }else{
        //递归出口:数组长度为1,直接返回数组
        $length = count($arr);
        
        if($length<=1) return $arr;
            //数组元素有多个,则定义两个空数组
            $left = $right = array();
            //使用for循环进行遍历,把第一个元素当做比较的对象
            for($i=1; $i<$length; $i++)
            {
                //判断当前元素的大小
                if($arr[$i]<$arr[0]){
                    $left[]=$arr[$i];
                }else{
                    $right[]=$arr[$i];
                }
            }
        //递归调用
        $left=quick_sort($left);
        $right=quick_sort($right);
        //将所有的结果合并
        return array_merge($left,array($arr[0]),$right);
    }
}

NOSQL

Redis、Memecached 这两者有什么区别?

  1. Redis 支持更加丰富的数据存储类型,String、Hash、List、Set 和 Sorted Set。Memcached 仅支持简单的 key-value 结构。
  2. Memcached key-value存储比 Redis 采用 hash 结构来做 key-value 存储的内存利用率更高。
  3. Redis 提供了事务的功能,可以保证一系列命令的原子性
  4. Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中
  5. Redis 只使用单核,而 Memcached 可以使用多核,所以平均每一个核上 Redis 在存储小数据时比 Memcached 性能更高。

Redis 如何实现持久化?

  1. RDB 持久化,将 redis 在内存中的的状态保存到硬盘中,相当于备份数据库状态
  2. AOF 持久化(Append-Only-File),AOF 持久化是通过保存 Redis 服务器锁执行的写状态来记录数据库的。相当于备份数据库接收到的命令,所有被写入 AOF 的命令都是以 redis 的协议格式来保存的

Laravel 设计原理

服务提供者是什么?

服务提供者是所有Laravel应用程序引导启动的中心,Laravel的核心服务器、注册服务、绑定服务、监听器、中间件、路由注册以及我们应用程序都是由服务提供者引导启动的。

IOC容器是什么?

IOC就是控制反转,也被叫做依赖注入(DI),对象A可以依赖对象B,但是控制权在对象A中,所以叫做控制反转,依赖注入则是在IOC容器运行时动态将某种依赖关系注入到对象中。
作用:解决代码难易度,实现低耦合、高扩展

Facades 是什么?

提供了一个"static"(静态)接口去访问注册到 IoC 容器中的类。提供了简单、易记的语法,而无需记住必须手动注入或配置的长长的类名。此外,由于对 PHP 动态方法的独特用法,也使测试起来非常容易。

Contract 是什么?

Contract(契约)是 Laravel 定义框架提供的核心服务的接口。Contract 和 Facades 并没有本质意义上的区别,其作用就是使接口低耦合、更简单。

架构

Thrift 实现的基本原理及作用

通过使用RPC通信协议,实现多语言开发场景下无感知的互相调用。
优点

  • 数据包呈二进制发送,流量消耗小
  • 传输效率高
  • 语言之间无障碍

如何解决优化网站App大数据大流量高并发

  • 硬件方面
  • 软件方面
  • 禁止外部盗链
  • 控制大文件的下载
  • 负载均衡
  • 分布式
  • 集群
  • 主从数据库
  • 分布式数据库
  • 分布式缓存

TCP 三次握手

三次握手就是客户端与服务器端建立TCP连接时需要发送3个包进行连接的确认,在三次握手完成后即可建立连接。

  • 第一次握手。客户端发送请求报文,标志位SYN设置为1,随机产生seq值为x,客户端进入SYN_SENT状态,等待服务器端的回应。
  • 第二次握手。服务器端接收到请求报文,将SYN和ACK都设置为1,ack为x+1,随机产生seq值为y,然后将数据包发送给客户端进行确认,服务器端进入SYN_RCVD状态。
  • 第三次握手。客户端收到回应的数据包后,确认ack是否为x+1,以及ACK是否为1,若正确,则将ACK设置为1,ack为y+1,然后将数据发送给服务器端。服务器端在接受到数据后检查ack是否为y+1,ACK是否为1,若正确则正确建立连接,双方均进入ESTAB-LISHED状态,完成三次握手。

TCP 与 UDP 的区别

除了TCP之外,我们还常听到的是UDP,那么他俩有啥区别呢?
TCP对应的是可靠性要求高的应用,从上面的解释可以看出来,在真正通信之前要三次握手,是面向连接的;并且TCP利用序列号保证消息的有序性。
而UDP对应的则是可靠性要求低,但是流量大、速度快的应用;和TCP相比,UDP是无连接的并且可能是无序的。
TCP更重量,UDP更轻量,没有高低之分,只是应用的场景不同。

非技术问题

  1. 为什么要在上家公司离职?
  2. 未来三年的职业规划的怎样的?
  3. 您这边有什么要理解的吗?
非技术问题没有正确答案
查看原文

mshx 收藏了文章 · 2020-03-18

分解 Laravel 框架的核心:服务容器(Service Container)

分解 Laravel 框架的核心:服务容器(Service Container)

原文链接:https://learnku.com/laravel/t...

讨论请前往专业的 Laravel 开发者论坛:https://learnku.com/Laravel

在理解服务容器之前,我们需要知道什么是容器,从名称上可以解释这一切,因为容器是我们存储东西的地方,当我们需要时我们从那里获取它。下面是代码示例。

class container{

    public $bindings =[];

    public function bind($name, Callable $resource){

       $this->bindings[$name]=resource;

    }

    public function make($name){

       $this->bindings[$name]();

    }

}

$container = new container();

$container->bind('Game',function(){
    return 'Football';
});

print_r($container->make('Game'));

//输出

'Football'

正如您所看到的,我创建了一个容器类,其中有两个方法

1) Bind
2) Make

在 bind 方法中将我们的函数注册到一个容器中,然后在 make 方法中调用这个函数。
这是 Laravel 中服务容器的基本概念

正如已经阅读了 Laravel 文档一样,Service Container 帮助我们管理依赖关系。让我们看一个例子


app()->bind('Game',function(){

    return new Game();

});

dd(app()->make('Game'));

// 输出

Game{}  // class 

在上面的代码中 app()->bind() 将我们的服务绑定起来。。然后我们就可以调用 make() 方法来使用它,接着我们可以将它作为一个类输出。。但是如果类 Game 依赖于类 Football,如下面的代码所示。它将会有错误抛出


Class Game{

    public function __construct(Football $football){

        $this->football =$football;

    }
}

app()->bind('Game',function(){

    return new Game();

});

dd(app()->make('Game'));

// 输出

将抛出类 football not found 的错误信息,因此我们要创建一个 football 类,如下代码所示。


class Football{

}

Class Game{

    public function __construct(Football $football){

        $this->football =$football;

    }
}

app()->bind('Game',function(){

    return new Game(new Football);

});

但是,如果类 Football 需要依赖一个体育场的类等等,Laravel 都可以通过服务容器处理依赖。


class Football{

}

class Game{

    public function __construct(Football $football){
        $this->football =$football;
    }
}

/*app()->bind('Game',function(){

    return new Game(new Football);
});*/

dd(resolve('Game'));

// 输出

Game{
  football {}
}

因此,我们可以说 Service Container 是管理类依赖项和执行依赖项注入的强大工具。。。:)

原文链接:https://learnku.com/laravel/t...

讨论请前往专业的 Laravel 开发者论坛:https://learnku.com/Larav
查看原文

认证与成就

  • 获得 0 次点赞
  • 获得 2 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 2 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2017-11-27
个人主页被 273 人浏览