快速操作Linux终端命令行的快捷键列表

快速操作Linux终端命令行的快捷键列表

操作组合键 说明 注释(自己猜想)
移动光标:
Ctrl + a 光标回到命令行首 a = ahead
Ctrl + e 光标回到命令行尾 e = end
Ctrl + b 光标向行首移动一个字符 b = backwards
Ctrl + f 光标向行尾移动一个字符 f = forwards
Alt + b 光标向行首移动一个单词
Alt + f 光标向行尾移动一个单词
删除命令:
Ctrl + w 向行首删除一个单词 w = word
Alt + d 向行尾删除一个单词 d = delete
Ctrl + k 删除光标处到行尾的字符
Ctrl + u 删除整个命令行文本字符
Ctrl + h 向行首删除一个字符 h = head
Ctrl + d 向行尾删除一个字符 d = delete
查找历史命令:
Ctrl + p 上一个使用的历史命令 p = previous
Ctrl + n 下一个使用的历史命令 n = next
Ctrl + r 快速检索历史命令 r = retrieve
其它:
Ctrl + i 相当于Tab键,命令、文件名自动补全
Ctrl + m 相当Enter键,执行命令
Ctrl + o 相当于Ctrl + m
Ctrl + t 交换光标所在字符和其前的字符
Ctrl + y 粘贴Ctrl+u,Ctrl+k,Ctrl+w删除的文本
Ctrl + s 使终端发呆,静止,可以使快速输出的终端屏幕停下来
Ctrl + q 退出Ctrl+s引起的发呆
Ctrl + z 使正在运行在终端的任务,运行于后台 可用fg恢复
Ctrl + c 中断终端中正在执行的任务
Ctrl + d 在空命令行的情况下可以退出终端 和上面的同命令但不同结果

MySQL插入Emoji提示 HY000 1366 Incorrect string value 错误

==本文前提:mysql Ver 14.14 Distrib 5.7.14, for Linux (x86_64) using EditLine wrapper==

  • 问题描述:在获取微信粉丝信息入库时线上环境产生了错误,而在本地开发时是成功的,线上环境提示nickname字段设置了错误字符串值,如下图:
    MySQL错误提示
  1. 出现这个问题,我明白是有用户的nickname里面含有Emoji导致的.

  2. 经过查找资料,我知晓在Emoji字符有一个特殊的地方,在存储时,需要用到4个字节。MySQL中常用的utf8字符集的utf8_general_ci这个collate最大只支持3个字节。所以为了支持能够存储Emoji,需要修改为utf8mb4字符集;于是用到了这篇文章里提到的方法,不管是修改/etc/my.cnf文件配置,还是在MySQL Client里修改全局配置,错误仍然出现.

    在查询相关资料时,还知道了一个信息,my.cnf中的default_character_set设置只影响mysql命令连接服务器时的连接字符集,不会对使用libmysqlclient库的应用程序产生任何作用,就是说会影响客户端链接时命令执行时的字符集,不影响我使用php脚本里的使用!鸟哥相关文章

  3. 后来我意识到一个问题,会不会是MySQL的sql_mode造成的问题,之前在做数据库迁移也出现过各种不兼容的问题.
    于是,我查看了一下线上MySQL的sql_mode的设置,因为sql_mode是有默认值的,所以在/etc/my.cnf里并没有显性写出,所以只能使用命令select @@sql_mode;在MySQL的客户端里查看,线上环境如下:
    默认的sql_mode

  4. 本地环境的如下:
    本地的sql_mode

  5. 修改/etc/my.conf文件,在mysqld部分增加sql_mode的配置,再次运行程序后成功,修改配置后内容如下图:
    修改后内容

  6. 去MySQL官网查看了5.7版本的Server SQL Modes模块这部分的文档,有这么一句话:

    The default SQL mode in MySQL 5.7 includes these modes: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, and NO_ENGINE_SUBSTITUTION.

大意是,如果没有覆盖配置,那么你的5.7版本的MySQL的SQL mode默认配置就会是上面提到的那些,见3图的默认信息。在MySQL官网有对应每部分详细的说明,我怀疑是STRICT_TRANS_TABLES模式造成插入不成功,我没有测试,最后我只保留了NO_ENGINE_SUBSTITUTION.

NO_ENGINE_SUBSTITUTION:顾名思义,没有引擎时替换。详细来说就是,在创建或修改表时,当指定的数据表引擎不可用或是未编译时,会替换为MySQL默认设置的存储引擎.
> 1. 当此项未设置时,创建表和修改表在引擎不可用时它们的表现也不同。创建表时,如果引擎不可用,MySQL会选择默认的存储引擎,并产生一个警告,但表会创建成功;在修改表结构时,如果引擎不可用,也会产生警告,不同的是修改不会生效.
> 2. 当此项设置时,如果设置的存储引擎不可用,会产生一个错误,并且新建或是修改表都不会成功.

php-fpm里进程管理配置介绍

  • 强调一个观点,给自己的备忘录:
    > 关于开发时使用到的相关软件(php,nginx,php-fpm,mysql等)的使用信息,最好的方式是查看他们的文档和各自的配置信息.
当然没有一定的知识,可能看了也会云里雾里,在此给出自己对php-fpm配置文件的一些理解.
  • 首先,需要知道php-fpm配置文件所在的路径,使用命令ps -ef | grep php,如下图:
    本机
    远程服务器
  1. 可以看到在两台机器上,配置文件的路径不一样,上图的路径是/etc/php/5.6/fpm/php-fpm.conf,下图的路径是/etc/php-fpm.conf,而且php-fpm启动的进程数也不一样,master进程数都为1,worker进程数上图为3个,下图为5个.
  2. 配置文件路径不一样是因为软件安装时软件包里指定的路径不一样,但为什么启动的进程数也不一样呢?这就要看配置文件的详细内容了.
  • 打开php-fpm.conf,内容如下,详细信息请看注释:
;;;;;;;;;;;;;;;;;;;;;
; FPM Configuration ;
;;;;;;;;;;;;;;;;;;;;;

; All relative paths in this configuration file are relative to PHP's install
; prefix (/usr). This prefix can be dynamically changed by using the
; '-p' argument from the command line.

; Include one or more files. If glob(3) exists, it is used to include a bunch of
; files from a glob(3) pattern. This directive can be used everywhere in the
; file.
; Relative path can also be used. They will be prefixed by:
; - the global prefix if it's been set (-p argument)
; - /usr otherwise
; 可以看到,在文件的开始就又加载了另外一个目录下以 .conf 结尾的配置,关于进程运行方式和数量的配置就在这个目录下.
include=/etc/php/5.6/fpm/pool.d/*.conf

........ 以下内容省略,因为此次内容是关于php-fpm进程相关的配置,故只截取了部分内容 ........
  • 打开对应目录/etc/php/5.6/fpm/pool.d/,可以看到www.conf文件,打开文件,可以看到内容有很多,我只截取了与进程数相关的内容,大概从74行开始,不同机器,不同版本php-fpm,文件内容应该大同小异,详情请看注释
; Choose how the process manager will control the number of child processes.
; 注:以何种方式运行php-fpm,进而管理子进程数量,这里列出了三种可选方式:
; 静态模式(static),动态模式(dynamic),按需加载模式(ondemand).

; Possible Values:
; static - a fixed number (pm.max_children) of child processes;
; 注:静态模式,这种模式下,进程数是固定的,固定的个数就是参数 max_children 所设置的个数,此个数不可以动态调整,对于个人本地开发或是小站来说,此模式可以节约资源.

; dynamic - the number of child processes are set dynamically based on the
; following directives. With this process management, there will be
; always at least 1 children.
; 注:动态模式,这种模式下,进程数是会动态改变的,但最少必须保留一个进程,它的启始进程数和动态改变最大进程数受以下参数控制.
; pm.max_children - the maximum number of children that can
; be alive at the same time.
; 最大进程数:动态增加时,进程数的最大值,即使 php-fpm 进程数被使用完要报错了,进程数的总量也不会超过这个值的限定.
;
; pm.start_servers - the number of children created on startup.
; 启始进程数:望文生义即可.

; pm.min_spare_servers - the minimum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is less than this
; number then some children will be created.
; 最少保留进程数:望文生义即可,需要注意的时,即使没有请求需要处理,空闲的进程数少于这个设定值时,php-fpm的进程数还是会增加,这样就会浪费机器资源,要根据机器实际情况来调整.
;
; pm.max_spare_servers - the maximum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is greater than this
; number then some children will be killed.
; 最大保留进程数:望文生义即可,需要注意的时,在没有请求需要处理,空闲的进程数大于这个设定值时,php-fpm的进程数会被kill掉.

; ondemand - no children are created at startup. Children will be forked when
; new requests will connect. The following parameter are used:
; 注:按需加载模式,服务启动时没有进程启动,但在请求到来时,会自动fork进程,这种模式下,进程数是会动态改变的,但最少必须保留一个进程,它的启始进程数和动态改变最大进程数受以下参数控制.
;
; pm.max_children - the maximum number of children that
; can be alive at the same time.
; 最大进程数:同上.
;
; pm.process_idle_timeout - The number of seconds after which
; an idle process will be killed.
; 进程空闲保留时间(秒):当进程空闲时,如果在设置的时间内没有被使用将会被kill掉.
; Note: This value is mandatory.
; 注:此参数不能缺省.
pm = dynamic

; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI. The below defaults are based on a server without much resources. Don't
; forget to tweak pm.* to fit your needs.
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
; Note: This value is mandatory.
; 注:非缺省值,含义见上.
pm.max_children = 5

; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
; 注:只能作用于动态模式,以动态模式运行时可为缺省值,缺省值为:最少保留进程数 + (最大保留进程数 - 最少保留进程数) / 2. 含义见上.
; 测试过,如果这个值随便填写重启php-fpm报错,但根据这个公式且不超过max_children,则没有问题,更详细需要进一步验证.
pm.start_servers = 2

; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
; 注:只能作用于动态模式,以动态模式运行时为非缺省值,含义见上.
pm.min_spare_servers = 1

; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
; 注:只能作用于动态模式,以动态模式运行时为非缺省值,含义见上.
pm.max_spare_servers = 3

; The number of seconds after which an idle process will be killed.
; Note: Used only when pm is set to 'ondemand'
; Default Value: 10s
; 注:只能作用于按需加载模式,缺省值为10s.
;pm.process_idle_timeout = 10s;
  • 总结:
  1. 以何种方式运行php-fpm,进而管理子进程数量,这里列出了三种可选方式:
    静态模式(static),动态模式(dynamic),按需加载模式(ondemand).

  2. 不同模式有不同参数控制进程数.

懂了配置参数的含义,就明白在不同的情况下要选择什么运行模式,以及为什么在查看进程数不同的机器上会有所不同了.

php-src源码目录说明

下面简单介绍一下PHP源码的目录结构。

  • 根目录: / 这个目录包含的东西比较多,主要包含一些说明文件以及设计方案。 其实项目中的这些README文件是非常值得阅读的例如:
    • /README.PHP4-TO-PHP5-THIN-CHANGES 这个文件就详细列举了PHP4和PHP5的一些差异。
    • 还有有一个比较重要的文件/CODING_STANDARDS,如果要想写PHP扩展的话,这个文件一定要阅读一下, 不管你个人的代码风格是什么样,怎么样使用缩进和花括号,既然来到了这样一个团体里就应该去适应这样的规范,这样在阅读代码或者别人阅读你的 代码是都会更轻松。
  • build 顾名思义,这里主要放置一些和源码编译相关的一些文件,比如开始构建之前的buildconf脚本等文件,还有一些检查环境的脚本等。
  • ext 官方扩展目录,包括了绝大多数PHP的函数的定义和实现,如array系列,pdo系列,spl系列等函数的实现,都在这个目录中。个人写的扩展在测试时也可以放到这个目录,方便测试和调试。
  • main 这里存放的就是PHP最为核心的文件了,主要实现PHP的基本设施,这里和Zend引擎不一样,Zend引擎主要实现语言最核心的语言运行环境。
  • Zend Zend引擎的实现目录,比如脚本的词法语法解析,opcode的执行以及扩展机制的实现等等。
  • pear “PHP 扩展与应用仓库”,包含PEAR的核心文件。
  • sapi 包含了各种服务器抽象层的代码,例如apache的mod_php,cgi,fastcgi以及fpm等等接口。
  • TSRM PHP的线程安全是构建在TSRM库之上的,PHP实现中常见的*G宏通常是对TSRM的封装,TSRM(Thread Safe Resource Manager)线程安全资源管理器。
  • tests PHP的测试脚本集合,包含PHP各项功能的测试文件
  • win32 这个目录主要包括Windows平台相关的一些实现,比如sokcet的实现在Windows下和*Nix平台就不太一样,同时也包括了Windows下编译PHP相关的脚本。

PHP的测试比较有意思,它使用PHP来测试PHP,测试php脚本在/run-tests.php,这个脚本读取tests目录中phpt文件。 读者可以打开这些看看,php定义了一套简单的规则来测试,例如以下的这个测试脚本/tests/basic/001.phpt:

--TEST--
Trivial "Hello World" test
--FILE--
<?php echo "Hello World"?>
--EXPECT--
Hello World

这段测试脚本很容易看懂,执行–FILE–下面的PHP文件,如果最终的输出是–EXPECT–所期望的结果则表示这个测试通过, 可能会有读者会想,如果测试的脚本不小心触发Fatal Error,或者抛出未被捕获的异常了,因为如果在同一个进程中执行, 测试就会停止,后面的测试也将无法执行,php中有很多将脚本隔离的方法比如: system(),exec()等函数,这样可以使用主测试进程服务调度被测脚本和检测测试结果,通过这些外部调用执行测试。 php测试使用了proc_open()函数, 这样就可以保证测试脚本和被测试脚本之间能隔离开。phpt文件的编写详细信息可参考 附录E phpt文件的编写。 如果你真的那么感兴趣,那么研究下$PHP_SRC/run-tests.php脚本的实现也是不错的选择。这个测试框架刚开始 由PHP的发明者Rasmus Lerdorf编写,后来进行了很多的改进。后面可能会引入并行测试的支持。

自我剖析

今天发生了一件事,和同事对某个功能的封装发生了一场小争论,他认为应该把这个功能封装成两个方法,以下是他的观点:

代码一旦出现岔路型变量,证明封装有问题(如这个里的 is_group_by);

对于使用者,这样的封装并没有透明化 “是否用 group by 逻辑” 对于之后的维护者,这类的方法势必两个分支会有不共用的逻辑,最终会导致一个大方法出现;

从两个角度考虑方便与否,一个是使用者,对于用参数还是用两个方法,使用者都需要知晓,使用者成本一样。对于可读性,多一个分岔路标变量会影响代码可读性,对于可维护性而言,分岔逻辑势必意味着大函数的出现;

  1. 永远不要断言未来,变的时候会去考虑改吗,这是一个明日复明日的问题,终有一个明日改不动了;
  2. is_group_by 可读性就好了吗.
而我的观点很简单:
  1. 不想新增新方法;
  2. 其它已经使用的地方不需要有改动.
在这记录一下我内心的想法:
  • 其实我是很赞同他的观点的,因为我内心是明白什么是好的设计,什么是差的设计。
  • 开始我也是那样想的,但由于要改动的地方太多,太麻烦,所以选择了简单的方式。
  • 以下这个想法不排除有推卸责任的嫌疑:你不能既让我在短时间里去实现业务逻辑,还要求一个很高的设计(搞什么,我现在写这篇稿子的时候,也开始觉得有推卸责任的嫌疑了)。
由今天的事引申
  • 不要在意别人在你背后说的话, 是真的不在意。

  • 除了上一条外,好的建议就要听。

mysql客户端emma中文乱码问题的解决

emma默认用apt-get 安装的话,emma是不支持中文的,配置文件或直接修改emma程序源文件(python)。

apt-get安装emma

sudo apt-get install emma

ubuntu的apt-get 安装emma是在/usr/share/emma目录下面。

cd /usr/share/emma/emmalib

sudo vim init.py

找到

“db_encoding”: “latin1”

改为

“db_encoding”: “utf8”

保存退出。

如果你已经安装完毕并且运行过emma,程序就会创建 ~/.emma/emmarc文件,保存配置。所以可以更改这里的配置文件,或者像下面直接修改emma的python源文件。
vim ~/.emma/emmarc
找到
db_encoding=latin1
改为
db_encoding=utf8
重新运行emma,此时发现还是乱码,在执行所有的sql语句之前加入这条sql语句,
set names utf8
但每次新用户都要改配置文件,以及执行新sql前都加这个语句,岂不是很费力,直接修改emma的源文件,来实现,新创建的emmrc配置文件就是utf8,和当选择数据库时,自动的执行“set names utf8” 语句。

以后新创建的配置文件默认就会是utf8的解码了,我想在连接数据之后就执行 “set names utf8” 语句,所以

sudo vim /usr/share/emma/emmalib/mysql_host.py

但是我下边这一步没执行成功,写完之后,emma 就没发启动了,

跳到155行左右的_use_db(self, name, do_query=True)函数哪里,改成如下

def _use_db(self, name, do_query=True):

if self.current_db and name == self.current_db.name: return

if do_query:

self.query(“use %s” % name, False)

self.query(“set names utf8”,  False)

try:

self.current_db = self.databases[name]

except KeyError:

print “Warning: used an unknown database %r! please refresh host!/n%s” % (name, “”.join(traceback.format_stack()))

ubuntu个人机使用到的一些软件

个人目前使用ubuntu,主要是用来进行web开发,在安装完ubuntu后,可以看到默认是有浏览器firefox,办公套件LiBreOffice,电邮客户端Thunderbird Mail,好了接下来说说我为了个人需要安装一些软件,仅供参考。
  • 通迅相关
  1. QQ International 这个不是官方发布的客户端,具体开发者我也不知道是谁,但我在使用ubuntu 13.x 的时候就使用的这个客户端,到目前使用的16.04LTS版都没有出现过问题,应该具备QQ2013的所有功能,办公使用足够了。如果有人需要这个deb包可以留言回复,我会发送文件到你邮箱并协助你安装。注意:需要先安装Wine(sudo apt install wine).

  2. Electronic WeChat 微信客户端,这个也不是腾讯官方发布的客户端,是一个开源项目。具体安装方法在github上面写的非常清楚,当然,如果你有不明白的地方,也可以回复我,我会尽我所能帮助你。


  • 输入法
  1. fcitx ubuntu有自带的ibus,不过我更喜欢使用fcitx,使用它的五笔拼音,打字嗖嗖的。

  • 浏览器
  1. google-chrome-stable安装文档

  2. chromium chromium是开发版,各种新功能都会有,但ubuntu的包却是很落后,刚开始我用的是chromium,后台更换为了chrome。


  • 音乐
  1. 厉害了word我的网易,网易云音乐有专门ubuntu对应版本的包,一般人我不告诉他,16.04LTS亲测能用,一直使用的网易云音乐

  • 虚拟机
  1. VirtualBox 不管是为了在Linux上使用Windows(Linuxer的痛)还是为了统一开发环境使用vagrant,都需要安装VirtualBox。

  • 数据库客户端
  1. emma 最开始我一直使用的emma,界面简洁,查看方便,能使用SQL语句,相对功能会少一些,且apt安装后有个小问题,不支持中文显示,解决方法

  2. navicat for mysql navicat对比其它Linux下Mysql客户端确实强大太多了,常用的各种功能自不在话下,还支持视图,函数,事件等等,下载解压后进入目录,运行脚本启动即可,但navicat也有个小问题,它不是免费的,只有15天试用期,不过你可以到目录.navicat下把user.reg删掉(cd ~/.navicat/),然后重启,你就又有15天的试用期了。


  • markdown编辑器
  1. Haroopad 界面美观,清晰,支持实时预览等很多功能,还有我最舒适的vim操作模式,我只使用了它的markdown语法编辑功能,目前只能导出HTML格式文件,下载后点击安装即可,此文就是通过这个软件编写的。

  2. Atom A hackable text editor for the 21st Century,Atom编辑器功能更强大,放到这个模块下面,其实是不合理的,因为它不仅仅是一个markdown编辑器,更是一个功能强大的文本编辑器,由于我使用的是(G)vim,所以只是把Atom当作写markdown文档的工具在使用,使用Atom的原因是家里电脑使用的是ArchLinux,ArchLinux上没有Haroopda的包,不得已找到了Atom,才发现它也非常强大,有超多第三方插件可供选择使用,除了自带插件,我搜索下载了支持vim的vim-mode,md文件转换为pdf的markdown-pdf,此次更新文件使用Atom修改。


  • 图片编辑工具
  1. GIMP Image Editor 是一个很强大的图片编辑工具,据说是Linux下的PhotoShop,当时我需要制作一个自己博客的logo,此网站的logo就是使用这个软件制作的,最后就找到了这个软件,目前使用了此软件很小一部分功能。

  2. gnome-screeshot 顺带说一下gnome自带的截图工具,我自己在系统设置,键盘,快捷方式里设置了它的快捷键ctrl + alt + a对应gnome-screenshot -a,此后截图就非常方便了。


  • 开发相关
  1. PHP7 Nginx mariaDB就不用说了.

  2. vim-gtk 我之前使用的vim-gnome编辑器,后来在每次关闭vim时,都会提示一个错误,在搜索这个问题时,看到Stack Overflow上别人推荐使用vim-gtk,使用下来一点不差.

  3. Composer PHP 的一个依赖管理工具,安装文档.


  • 科学上网
  1. Shadowsocks科学上网工具,结合浏览器插件SwitchyOmega或是终端代理工具ProxyChains.注意:直接apt install shadowsocks安装的可能不支持rc-md5,可先安装pip(sudo apt install python-pip),然后用pip安装(pip install shadowsocks).

  • 系统设置
  1. 使用monaco字体,参考github一篇文档,clone或下载文件,请仔细阅读README.md,最后找到其中为Ubuntu定制的安装脚本。运行命令./install-font-ubuntu.sh https://github.com/todylu/monaco.ttf/blob/master/monaco.ttf?raw=true,文档里提供的地址已失效。

  2. Unity Tweak Tool设置系统工具,可以在Ubuntu应用商店搜索安装,安装后可以使用第一步里安装好的monaco字体.


  • 其它相关问题
  1. 配置thunderbird,qq企业邮箱服务时要补全为exmali.qq.com

  2. 字的问题,一些字体显示不正确。
    /ect/honts/conf.d/64-language-selector-prefer.conf 有以下内容:

<alias>
      <family>sans-serif</family>
      <prefer>
         <family>Noto Sans CJK JP</family>
         <family>Noto Sans CJK SC</family>
         <family>Noto Sans CJK TC</family>
      </prefer>
   </alias>
   <alias>
      <family>monospace</family>
      <prefer>
         <family>Noto Sans Mono CJK JP</family>
         <family>Noto Sans Mono CJK SC</family>
         <family>Noto Sans Mono CJK TC</family>
      </prefer>
   </alias>

你要做的就是把 JP 换到最后面,然后重启电脑。

PHP魔术常量的示例

php的魔术常量有8个

私以为这个顺序是比较方便记忆的,从整体到局部,分别是:
__DIR__       文件所在目录的绝对路径

__FILE__     文件所在绝对路径

__LINE__    文件所在绝对路径

__NAMESPACE__    当前命名空间名称

__CLASS__    当前类名称

__TRAIT__     当前Trait名称

__MEHTOD__   当前方法名称

__FUNCTION__    当前函数名称

有一点是需要注意的就是trait的优先级,从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。当前类的方法又会覆盖trait的方法。
当有使用到Trait时,且没有被当前类里的方法覆盖时__METHOD__输出的是trait里的方法;

否则,__METHOD__输出的是当前类里的方法。

以下是代码。

<?php
namespace bobo;

trait Lianbo {
    public function test()
    {
        echo 'hello world'.PHP_EOL;

        // /var/www/html/test
        echo __DIR__.PHP_EOL;

        // /var/www/html/test/magic_const.php
        echo __FILE__.PHP_EOL;

        // 16
        echo __LINE__.PHP_EOL;

        // bobo echo 
        __NAMESPACE__.PHP_EOL;

        // bobo\Lianbo 
        echo __TRAIT__.PHP_EOL;
        // bobo\Bobo
        echo __CLASS__.PHP_EOL;

        // bobo\Lianbo::test
        echo __METHOD__.PHP_EOL;

        // test
        echo __FUNCTION__.PHP_EOL;
    }
}

class Bobo {
    use Lianbo;

    //public function test() {
        //echo __DIR__.PHP_EOL;
        //echo __FILE__.PHP_EOL;
        //echo __LINE__.PHP_EOL;
        //echo __NAMESPACE__.PHP_EOL;
        //echo __CLASS__.PHP_EOL;
        //echo __TRAIT__.PHP_EOL;
        //echo __METHOD__.PHP_EOL;
        //echo __FUNCTION__.PHP_EOL;
    //}
}

$obj = new Bobo;
$obj->test();

图片第一张是class Bobo里test()方法注释时的结果,第二张是注释打开时的结果。

一次http请求的过程

  • ##### 用户访问

首先会输入网站URL,例如:http://blog.blianb.com,这个时候DNS( Domain Name System):“域名系统”,会把域名翻译为对应的IP地址。为什么会有这一步呢?你可以先简单的理解为手机里保存的手机号与对应姓名,QQ号与备注的关系,目的是为了辨识和使用。

  1. 输入URL回车后,计算机会先查找浏览器的缓存,如果浏览器没有缓存这个URL对应的IP地址,或者缓存已经过期,那么计算机会接着查找操作系统本地DNS解析器的缓存。

    注:我们怎么查看Chrome自身的缓存?
    > 可以使用 chrome://net-internals/#dns 来进行查看,如下图,标红为过期:
    浏览器缓存

  2. 计算机检查本地hosts文件里是否含有这个映射关系
    Windows的hosts文件一般在C:\Windows\System32\drivers\etc\hosts
    Linux的hosts文件一般在/etc/hosts里

    注:Linux文件路径和内容如下图:
    host文件路径
    host文件内容
    btw,一般做网站开发的都会修改这个文件,配合本地的web server实现虚拟主机,方便在本地测试,127.0.0.1代表请求本地的服务

  3. 查找网络设置里的DNS服务器(区域)

  4. 检查此DNS服务器里是否含有这个IP地址映射关系

  5. 最后转至根DNS服务器查询,以下是DNS服务器的一些相关资料:

名称类型 说明 示例
根域 DNS域名中使用时,规定由尾部句点(.)来指定名称位于根或更高级别的域层次结构 单个句点(.)或句点用于末尾的名称
顶级域 用来指示某个国家/地区或组织使用的名称的类型名称 .com
第二层域 个人或组织在Internet上使用的注册名称 blianb.com
子域 已注册的二级域名派生的域名,通俗的讲就是网站名 www.blianb.com
主机名 通常情况下,DNS的域名的最左侧的标签标识网络上的特定计算机,如h1 blog.blianb.com
DNS域名称 组织类型
com 商业公司
edu 教育机构
net 网络公司
gov 非军事政府机构
Mil 军事政府机构
xx 国家/地区代码(cn代表中国)
  1. DNS工作简图:
    DNS工作简图

  • ##### 发起TCP三次请求
    > 拿到域名对应的IP地址之后,User-Agent(一般是指浏览器)会以一个随机端口(1024 < 端口 < 65535)向服务器的web server(常用的有apache,nginx等)80端口发起TCP的连接请求。这个连接请求(原始的http请求经过TCP/IP4层模型的层层封包)到达服务器端后(这中间通过各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达web server(本文就以Nginx为例),最终建立了TCP/IP的连接。
  1. 使用子网掩码判断客户机和服务器是否在一个子网络

  2. 在同一个子网络,则使用以太网进行广播发送数据包

  3. 不在同一个子网络,则通过网关转发

涉及的相关资料:
OSI模型七层协议
tcp的三次握手,建立连接
TCP/IP模型是一系列网络协议的总称,TCP/IP模型一共包括几百种协议,对互联网上交换信息的各个方面都做了规定


  • ##### web server(nginx)
要知道http请求到达web server之后,web server是怎么工作的,就要先知道以下几个概念:
  1. CGI:CGI 是 Web Server 与后台语言交互的协议;

  2. FPM (FastCGI Process Manager),它是 FastCGI 的实现,任何实现了 FastCGI 协议的 Web Server 都能够与之通信;

  3. FPM 是一个 PHP 进程管理器,包含masterworker两种进程:master进程只有一个,负责监听端口,接收来自Web Server的请求,而worker进程则一般有多个 (具体数量根据实际需要配置),每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方,下图是我本机上 fpm 的进程情况,1个master进程,多个worker进程(本地有3个,云服务器上有5个worker);
    本机:
    本机

运程服务器:
远程服务器

  1. 关于php-fpm worker进程的配置说明,详见php-fpm里进程管理配置介绍;

  • ##### web server按端口监听到请求后,会分配给worker进程,调用相关PHP脚本进行具体的处理。

  • ##### php-fpm执行php文件
    涉及到解释器的执行过程
    通过socket和数据库或是缓存等交互

  • ##### 返回结果
    也是通过网络协议

  • ##### 浏览器显示

转:或许你也患上了开发瘫痪症

亲爱的开发者们:你们是否因为自己只精通于三大设备平台的八种编程语言而惴惴不安?又发现一个JavaScript框架是否会让你不寒而栗、愁眉苦脸?你是否曾经因为无法确定哪个云平台最适合而把业余项目一再推迟?

或许你也换上了开发瘫痪症(Developaralysis)。颤抖吧,这个病是治不好的。

如今开发者们可选的技术方案多到令人发指,让人眼花缭乱,透不过气来。过去几年里,我拿着别人给我的酬劳,写过Java、Objective-C、C、C++、Python、Ruby、JavaScript、PHP(对不起,这个也算),用过各种各样的SQL/键值/文件数据存储技术(MySQL、PostgreSQL、MongoDB、BigTable、Redis、Memcached等等)。我是否自我感觉良好?上帝啊,一点也没有。我反而感觉到愧疚,因为我还没有用过Erlang、Clojure、Rust、Go、C#、Scala、Haskell、Julia、Scheme、Swift或者是OCaml。

我就是一名开发瘫痪症患者:软件产业发展太快、任何一个人都无法跟上,从而对我的意识造成了毁灭性打击。

上面提到的几乎任何一种语言,你都会找到无数可选的框架、套件和库——看得头都要爆炸了。如今仅仅是把JavaScript的框架和库的所有排列认真评估一遍就要花上几个月的时间。另外,你知道Ruby语言有多少种gem包吗?有多少种iOS框架吗?有多少种NewSQL或NoSQL的数据库技术吗?更不用说从Hadoop、Spark与Google Dataflow中进行选择了,究竟是用Avro,还是Thrift,还是协议缓冲区,等等,等等……

还好,移动领域已经简化到了Android、iOS两大垄断平台——尽管也隐藏着一些交叉代替方案,比如Xarmarin或者PhoneGap、Sencha这样的跨平台HTML技术——但是确定在哪个平台上部署后端、如何部署又会让你头大。我开发过的各个系统部署在Heroku、Amazon Web Services、Google App Engine、Google Compute Engine以及Parse上面……这让我感觉非常糟糕,因为我对OpenStack、Force.com、Azure、Appfog一无所知,好多AWS服务我也从来没有真正用过,说多了都是泪。

I Am Devloper @iamdevloper

2014年编写简单网站的步骤:

  1. 安装Node

  2. 安装Bower

  3. 选择CSS框架

  4. 选择敏捷的方法

……

  1. 写几行HTML代码

如今的开发者面临着太多的选择,以至于使用的许多工具仅仅是用来管理另一堆工具:比如Bundler、Bower、CocoaPods、Pip等等。这些东西太棒了!我完全离不开它们!别高兴得太早。你开始使用另一堆工具后,等用到一半的时候你真正理解了它们的内容,你开始觉得这样的配置还不够用,你有点想要把它们重写一遍了……也许再找另一个工具代替……

可悲的是,如今开发者可用的语言、工具、框架以及平台的多样性和绝对数量庞大到让人畏惧。当然没人会承认这一点。所有人都想装作精通所有语言的编程大师。然而事实却是,我们都已经深陷于开发瘫痪症之中无法自拔。

即便收集了各种信息做出了最明智的选择,结果往往也适得其反。比如说,在项目开始前,你真的花时间分析了所有的可能,克服了由此产生的学习曲线,结果却被一些用着PHP、Swift这样易于上手的语言,写着表情符号变量名的小屁孩抢了市场先机——

——不过另一方面,如果你选择使用Swift和PHP的话,你就会生活在无休止的恐惧之中,担心一些C#/Haskell程序员高手很快就会做出更好的产品几百你,就像保罗·格拉汉姆(Paul Graham)很多年前用Lisp语言编写Viaweb那样。回忆往昔,他这样写道:

当你选择了技术之后,你必须要忽略其他人在做什么,全心全意思考怎样做到最好……事实上我们确实有一个秘密武器……我们开发软件的速度超出了所有人的想象……我们用一种全是括号的语法奇怪的AI语言编写出了我们的软件。

再说回开发瘫痪症。我们应该选择已经掌握的技术吗?这样我们就能立刻动手开发,无需克服学习曲线,但是需要生活在恐惧之中,担心其他人在以更好、更快、更优雅的方式实现同样的产品,担心到了明年我们的技能就跟不上时代、丧失竞争力了。还是应该选择未知的新技术?因为我们热爱学习,更好的工具使用起来不仅更加有趣,而且能够带来巨大的竞争优势……付出的代价则是大量的时间、精力和认知负荷。

这个问题太难回答了!不存在绝对正确的答案。因此每个月都是开发瘫痪症发作月。我马上会做好五颜六色、闪闪发光的丝带给你们佩戴,只要等我选好用哪种3D打印机、哪种微控制器、哪种LED软件、哪种无人机系统就行了。恐怕要麻烦你们期待很久很久了。

翻译:顾秋实