五月
22
2017

SSH 方式下为 Git 设置多用户登录

特别说明 这个是目前开发过程中经常要遇到的问题了。呃,一般是系统装了环境之后会用到。又是 Hy369 要说的老话了:唉,不想每次都去谷歌百度了! 功能说明 针对 GIT 的 SSH 的方式,实现用不同的账号和密钥访问不同的仓库。 可能的场景: 通过电子邮箱1和密钥1访问 Github 通过电子邮箱2和密钥2访问 Oschina 通过电子邮箱3和密钥3访问公司内部仓库 实现方式 第一步 生成各个站点需要用到的密钥 相关命令与推荐参数: # 切换到 .ssh 目录(建议,可偷懒) cd ~/.ssh # 生成密钥文件 ssh-keygen -t rsa -C "youremail@mail.com" -f 密钥文件名,如:id_rsa.github # 加载私钥文件 ssh-add 密钥文件名 命令说明: 推荐切换到 .ssh 目录下面,Windows 环境下,.ssh目录在 C:\Users\登录账号同名文件夹\。这样可以在输入生成文件路径的时候省事。若不存在这个文件夹,直接创建即可。 ssh-keygen -t 参数表示生成的类型为:rsa ssh-keygen -C 注释,推荐带上,这样拷贝公钥到 Git 仓库中时,Web端一般会自动把 Comment 作为公钥名称显示,嗯,又可以偷懒了。 ssh-keygen -f 输出密钥文件的路径,很多教程中,都没有这个选项,这样就导致执行时会询问把文件用什么名字存在哪里。个人认为:不利于偷懒,所以推荐带这个选项咯。 后续的所有询问直接回车搞定了,一般不设置密码,如果需要,请自行百度,Hy369 还没有使用过,没有发言权。 命令执行完以后, .ssh 目录下,就会生成密钥文件,带 .pub 的就是密钥的公钥。 需要多少个不同的密钥,便执行上述步骤即可。 第二步 配置 config 文件 在 .ssh 目录下,创建一个 config 文件。注意没有后缀。实现为不同的仓库配置不同的密钥: 配置文件样例: # oschina Host git.oschina.net HostName git.oschina.net PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa.oschina User Hylin # github Host github.com HostName github.com PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa.github User Hy369 至此,配置完成,正常情况下,便可使用了。 第三步 添加公钥到网站 登录自己的 Github 或者 Oschina,公司的请咨询运维。一般在个人设置的界面,有个 SSH 的选项或者导航标签,点击进去,就可以看到添加公钥的界面。 将公钥中的字符,全部复制到文本框内,然后设置一个便于自己区分的名字,提交即可。 第四步 测试 ssh -T git@github.com # 如果出现了这个提示,直接输入 yes 确认即可 The authenticity of host 'github.com (192.30.255.113)' can't be established. RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8. Are you sure you want to continue connecting (yes/no)? # 以下是成功之后的信息: Hi Hy369! You've successfully authenticated, but GitHub does not provide shell access. 如果没有成功,试着备份或者重命名一下 .ssh 目录下的 known_hosts 文件,再次尝试。 如果还是有问题,请针对具体问题,利用搜索引擎查找一下解决方案。或者,你也可以给 Hy369 发邮件,Hy369 会为你提供力所能及的帮助。 SSH 方式下为 Git 设置多用户登录 补充说明
十二月
21
2016

笔记007 rsync 命令比较文件但不同步

Linux 中同步文件经常用到 rsync 命令,用来保证两个地方的文件的一致性。系统会自动进行对比,保证两边的文件是一样的。 在使用这个命令的时候,还有的一个情况,就是想要先了解哪些文件将会被同步,避免多人进行这类操作时,导致了错误的文件也被同步过去。 Hy369 又是数次折腾过这个问题,这次终于痛定思痛,要把他记录下来了!! 只对比需要同步的文件,而不进行实质性的同步,只需要对 rsync 命令添加额外的参数就可以了: rsync -avzn -P 源地址 目标地址 rsync -avz -P --list-only 源地址 目标地址 额外的参数可以是 -n 也可以是 --list-only,效果相同,只是后者显示的信息更加详尽。
七月
28
2016

Python 链表方法汇总

以下罗列链表可用的方法: append(x) 把一个元素添加到链表的结尾,相当于 a[len(a):] = [x]。 extend(L) 通过添加指定链表的所有元素来扩充链表,相当于 a[len(a):] = L。 insert(i, x) 在指定位置插入一个元素,第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x) 会将 x 插入到整个链表的前面,而 a.insert(len(a), x) 则会实现与 a.append(x) 一样的功能。 remove(x) 删除链表中的值为 x 的第一个元素,如果没有这样的元素,将返回一个错误。 pop([i]) 从链表的指定位置删除元素,并返回被删除的元素。如果没有指定索引,a.pop() 将会删除并返回最后一个元素。(注意:方法 i两边的方括号表示该参数可选,并非是要求输入一对方括号) index(x) 返回链表中第一个值为 x 的元素的索引。如果没有匹配的元素则返回一个错误。 count(x) 返回 x 在链表中出现的次数。 sort() 对链表中的元素按升序进行排序。 reverse() 倒置整个链表(即最前的变成最后,最后的变成最前的)。 链表方法示例: >>> a = [66.6, 333, 333, 1, 1234.5] >>> print a.count(333), a.count(66.6), a.count('x') 2 1 0 >>> a.insert(2, -1) >>> a.append(333) >>> a [66.6, 333, -1, 333, 1, 1234.5, 333] >>> a.index(333) >>> a 1 >>> a.remove(333) >>> a [66.6, -1, 333, 1, 1234.5, 333] >>> a.reverse() >>> a [333, 1234.5, 1, 333, -1, 66.6] >>> a.sort() >>> a [-1, 1, 66.6, 333, 333, 1234.5]
七月
19
2016

Windows 下安装 PHPUnit

写在前面 最近换了系统,以前搭建的一些环境没了,又得重新搭建。而在 windows 环境下重新搭建 PHPUnit 的时候,我居然又遇到问题了。 所以说,好记性不如烂笔头,我还是得把具体的操作方法记录在自己的 PHP 博客中。 安装方法 环境介绍 操作系统 windows 10 PHP版本 PHP 5.6 PHPUnit版本 PHPUnit 4.8.23 下载软件包 到 PHPUnit 官方网站下载软件包,我下载的软件包全名是:phpunit-4.8.23.phar。为了方便,这里将软件包直接重命名为 phpunit。 安装步骤 我的电脑 -> 属性 -> 系统高级设置 -> 系统属性 -> 高级 -> 环境变量 将 php.exe 和 刚才重命名的 phpunit 两个软件所在的目录加入到环境变量的 PATH 变量中 调出 CMD(快捷键:win + R),进入 phpunit 所在的目录,然后执行命令: echo @php "%~dp0phpunit" %* > phpunit.cmd 这样,便会在 phpunit 所在的目录下生成一个 phpunit.cmd 文件,而文件内容会是:@php "%~dp0phpunit" %* 这也就意味着,你直接在 phpunit 文件所在目录下创建一个 phpunit.cmd 文件,并且录入上述内容,可以实现完全一样的效果,哈哈。 至此,安装完成。 安装检测 在 CMD 中执行命令: phpunit --version 正常情况下,你就可以得到 phpunit 的版本号了。如果在这时提示找不到文件之类的错误,意味着环境变量没有得到更新,此时最简单的一个办法是:重启你的电脑。
七月
13
2016

扩展表达式语言

表达式语言可以通过添加自定义函数进行扩展。例如,在 Symfony 框架中,Security 实现了一个自定义函数用于检查用户角色。 如果想要了解如何在表达式中使用函数,可参考 使用函数 (英文) 注册函数 函数会在每一个特定的 表达式语言 实例上进行注册。这意味着实例中这些被注册的函数可以被实例中的任意表达式执行。 要注册一个函数,需要使用 register() 方法。该方法有三个参数: name - 函数在表达式中的名称 compiler - 编译表达式时要使用的函数 evaluator - 执行表达式时要使用的函数 use Symfony\Component\ExpressionLanguage\ExpressionLanguage; $language = new ExpressionLanguage(); $languate->register('lowercase', function($str) { return sprintf('(is_string(%1$s) ? strtolower(%1$s) : $1$s)', $str); }, function ($arguments, $str) { if (!is_string($str)) { return $str; } return strtolower($str); }); var_dump($language->evaluate('lowercase("HELLO")')); 以上程序会输出 hello。compiler 和 evaluator 两个编译器都将 arguments 变量作为首个参数,该参数的性质等效于 evaluate() 或 comple() 方法的第二个参数(例如:执行时传递的 values,编译时传递的 names)。 使用表达式供应器 当项目中使用 ExpressionLanguage 类时,你经常会需要添加自定义函数。因此,你可以通过实现 ExpressionFunctionProviderInterface 接口创建一个新的表达式供应器。 该接口必须实现一个方法:getFunctions(),该方法需要返回一个值为需要注册的表达式函数(ExpressionFunction 类的实例)数组。 use Symfony\Component\ExpressionLanguage\ExpressionFunction; use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; class StringExpressionLanuageProvider implements ExpressionFunctionProviderInterface { public function getFunctions() { return array( new ExpressionFunction('lowercase', function($str) { return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str); }, function($arguments, $str) { if (!is_string($str)) { return $str; } return strtolower($str); } ); } } 你可以使用 registerProvider() 方法或者通过 ExpressionLanguage 类的构造方法的第二个参数来注册供给器: use Symfony\Component\ExpressionLanguage\ExpressionLanguage; // 通过构造器进行注册 $language = new ExpressionLanguage(null, array( new StringExpressionLanguageProvider(), // ... )); // 通过 registerProvider() 方法注册 $language->registerProvider(new StringExpressionLanguageProvider()); 推荐在项目中的创建自定义的 ExpressionLanguage 类。目前你可以通过重写构造器来添加扩展功能: use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage; use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface; class ExpressionLanguage extends BaseExpressionLanguage { public function __construct(ParserCacheInterface $parser = null, array $providers = array()) { // 预加载默认的供给器以便于用户进行重载 array_unshift($provider, new StringExpressionLanguageProvider()); parent::__construct($parser, $providers); } } 原文地址:Extending the ExpressionLanguage
七月
01
2016

近两天又折腾了一下 Markdown 编辑器

强迫症又犯了? 最近两天脑海里中是飘出一个念头,就是重新捣腾一下自己 PHP 博客的 Markdown 编辑器。至于原因嘛,或许是强迫症犯了吧。 在先前使用 Markdown 编辑器的过程中,发现当时的编辑器有着几个个人完全无法忍受的问题: 不能在编辑器内使用 Tab 键 这对我来说,可是致命的啊。不能使用 Tab 就意味着没法在编辑器内进行代码缩进操作,好歹我这个也是 PHP 博客不是,不能使用代码缩进的话,确实很坑啊。 在之前还能忍受的时候,我则是把代码复制到自己的 IDE 里面格式化一下再拷贝出来,可是现在确实不能忍了。 不能在编辑器内使用 Shift + Tab 键,理由同上 前后端 Markdown 解析器解析结果不一致 这个也是一个很坑的问题,由于前端使用 Javascript 进行解析,而后端使用 PHP 进行解析,所以难免出现解析不一致的问题 编辑器与预览器是上下排列的 这个也是自己捣腾出来的一个坑爹问题,由于之前的后台编辑界面实在太窄了,根本无法对编辑器与预览器进行并排排列,导致每次要看预览效果,必须鼠标滚动到下面去看,看完了又滚动回来继续编辑,想想都心累(看来懒毛病又发作了)。 没有代码高亮 其实吧,在之前的之前,是有代码高亮的功能的,只不过在加入 Markdown 之后呢,我把代码高亮的功能给切掉了。至于原因,呃,我也不知道啊。 好吧,动刀吧 基于以上几点原因呢,我在忍耐了无数个回合之后,终于决定再次对自己的 PHP 博客动刀了。美容,一定得给它美容。 在搜索引擎中折腾了很久,一直找不到合适的替代品啊。实在没法了,在一个 Markdown 的成品网站中去看了看源码,还真发现了端倪。我发现了一个可能的关键词: Ace。 然后呢,接着这个关键词,我发现了新大陆:居然又专门针对代码编辑的在线编辑器啊,而且这么火,这么牛逼的编辑器,我居然到现在才知道?? 看来,我是太过于孤陋寡闻了。 找到了代码编辑器,便解决了一个大问题,接下来便是解析器前后端一致的问题。 后端的解析器我依然还是决定继续使用 Parsedown,这个解析器速度挺快的。至于前端的解析器,则从 Pagedown 换成了 Markdown-it。把前端的解析器一换,效果就出来了,确实不错的样子。 而后便是代码高亮的问题,现在突然想起来了,之前把代码高亮砍掉的原因,是因为觉得那个代码高亮太丑了。新的代码高亮程序,使用的是 highlightjs,这下总是显得高大上了吧。至少我是这么认为的了。 OK,至此,我的强迫症终于被暂时治好了。 还是弄个后台的截图吧  
六月
23
2016

symfony 字符串驼峰式/下划线式互转方法

说明 在阅读 symfony 源码的过程中,发现了字符串驼峰式/下划线式互转方法。 虽然这类方法完全可以自己来写,但是每次遇到都要写一遍的话,从时间成本上来看,简直是浪费了。既然要使用 symfony 框架,那么为何要抛开其本身就提供了的功能,自己去另外搞一套呢。所以 Hy369 觉得还是有必要在自己的专用PHP博客中记录一下,以备将来可以直接拿来使用。 驼峰式字符串转换 symfony 中提供的驼峰式转换方法是: Container::camelize($id) 该方法会对以下字符进行转换: 首字母大写 _ 将被去掉,同时其后的字母大写 . 将被转换为 _,同时其后的字母大写 \ 将被转换为 _,同时其后的字母大写 从上面可以看出,这里得出的驼峰式字符串属于首字母大写型,若是需要一个首字母小写型的字符串,执行首字母小写函数 ` lcfirst()· 就可以了。 下划线式字符串转换 symfony 中提供的下划线式转换方法是: Container::underscore($id) 该方法会对以下字符串进行转换: 本身的 _ 被装换为 . 连续大写的字母,最后两个大写字母之间插入 _,然后字母全部小写,例如 IDTt 将转换为 id_tt 小写字母或者数字后面跟着一个大写字母,在大写字母前面插入 _,该大写字母小写,例如 abcTest 将转换为 abc_test 不匹配上述规则的所有大写字母直接转换为小写
五月
09
2016

类 Symfony\Component\Stopwatch\Section

类简介 秒表节点,实现了秒表的节点计时功能,秒表节点可嵌套、可串联 类摘要 Section { private StopwatchEvent[] $events = array() private null|float $origin private string $id private Section[] $children = array() public __construct($origin = null) public null|Section get() public Section open() public string getId() public Section setId() public StopwatchEvent[] startEvent() public boolean isEventStarted() public void stopEvent() public StopwatchEvent[] lap() public StopwatchEvent[] getEvent() public StopwatchEvent[] getEvents() } 属性 events 秒表事件实例集合 origin 秒表节点的起始时间(毫秒) id 秒表节点的 ID children 秒表节点的子节点实例集合 方法 Section::__construct 秒表节点的构造方法 Section::get 根据秒表节点的 ID,获得当前秒表节点的子节点 Section::open 根据节点 ID 开启当前秒表节点的子节点 如果对应的子节点不存在,即返回 null,则实例化一个指定 ID 的子节点 Section::getId 获得当前秒表节点的 ID Section::setId 设置当前秒表节点的 ID Section::startEvent 开始一个秒表事件 若指定名称的秒表事件不存在,则实例化一个秒表事件 Section::isEventStarted 判断指定名称的秒表事件是否开始 Section::stopEvent 结束指定名称的秒表事件 Section::lap 结束某个秒表事件的最后一个事件周期,并开启一个新的事件周期 Section::getEvent 根据名称获得某个秒表事件实例 Section::getEvents 获得所有的秒表事件实例集合
五月
06
2016

文件系统组件(Filesystem Component)

组件介绍 文件系统组件用于提供对文件系统的基本操作。 用法实例 Filesystem 类是该文件系统组件的唯一操作端口。 use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Exception\IOExceptionInterface; $fs = new Filesystem(); try { $fs->mkdir('/tmp/random/dir/'.mt_rand()); } catch (IOExceptionInterface $e) { echo "An error occurred while creating your directory at ".$e->getPath(); } 代码摘要 类 Symfony\Component\Filesystem\Filesystem 接口 Symfony\Component\Filesystem\Exception\ExceptionInterface 接口 Symfony\Component\Filesystem\Exception\IOExceptionInterface 类 Symfony\Component\Filesystem\Exception\IOException 类 Symfony\Component\Filesystem\Exception\FileNotFoundException
二月
18
2016

Linux系统中为 PHP 安装 intl 扩展

安装 intl 扩展之前,需要安装 icu4c 。 下载地址: icu4c 下载地址 intl 下载地址 安装 icu4c 假设 icu4c 被解压到 icu/source cd icu/source ./configure –prefix=/usr/local/icu make make install 安装 intl 扩展 cd intl-3.0.0 /usr/local/php/bin/phpize ./configure –enable-intl –with-icu-dir=/usr/local/icu/ –with-php-config=/usr/local/php/bin/php-config make make install 启用扩展 在 php.ini 文件中添加 extension=intl.so 然后重启服务即可。