五月
23
2017

SSH 方式下为 Git 设置多用户登录 补充说明

之前在 SSH 方式下为 Git 设置多用户登录 中对 Git 配置多个不同的账号访问不同的仓库做了说明。今天早上提交代码的时候,意外发现提交者的信息有些问题。提交者的名称和邮箱,变成了公司仓库的名称和邮箱。 仔细检查了一下,发现自己在多用户登录不同仓库的配置上,配置得不够到位,这也是很多相关的配置教程中没有提到的。 现在,将遗漏的配置项,做一个补充说明。 取消全局用户设置 Hy369 在自己的 Git 配置中遇到的问题,就是所有仓库的提交者信息,都是统一的。问题就出在配置提交信息的时候,采用的 git config --global 进行配置的。这个时候,Git 软件自然就是取用全局配置了。因此,我们先把全局配置的用户信息去掉。相关命令为: git config --global --unset user.name git config --global --unset user.email 那个,至于不取消有没有影响,Hy369 还没有测试过,如果哪位朋友测试过了,烦请告知一下。 为 Git 仓库单独配置用户信息 直接到每个克隆的仓库中,单独配置用户信息即可。相关命令为: git config --add user.name xxx git config --add user.email xxx@xxx.com 至此,新的提交者信息就是你需要的了。
七月
29
2016

Python 字符串方法汇总

注意 需要注意的是,以下罗列的所有字符串方法,均不会修改原始的字符串数据。故需要返回字符串的那些方法,均是返回一个新的字符串。 字符串方法 方法 描述 s.captitalize() 首字母变大写 s.center(width [, pad]) 在长度为 width 的字段内将字符串居中,pad 为填充字符 s.count(sub [, start [, end]]) 计算指定子字符串 sub 出现的次数 s.decode([encoding [, errors]]) 解码一个字符串并返回一个 Unicode 字符串(只能用于字节字符串) s.encode([encoding [, errors]]) 返回一个字符串的编码版本(只能用于 Unicode 字符串) s.endswitch(suffix [, start [, end]]) 检查字符串是否以 suffix 结尾 s.expandtabs([tabsize]) 使用空格替换制表符 s.find(sub [, start [, end]]) 找到指定字符串 sub 首次出现的位置,否则返回 -1 s.format(*args, **kwargs) 格式化 s s.index(sub [, start [, end]]) 找到指定字符串 sub 首次出现的位置,否则报错 s.isalnum() 检查所有字符是否都为字母或数字 s.isalpha() 检查所有字符是否都为字母 s.isdigit() 检查所有字符是否都为数字 s.islower() 检查所有字符是否都为小写 s.isspace() 检查所有字符是否都为空白 s.istitle() 检查所有字符串是否为标题字符串(每个单词首字母大写) s.isupper() 检查所有字符是否都为大写 s.join(t) 使用 s 作为分隔符连接序列 t 中的字符串 s.ljust(width [, fill]) 在长度为 width 的字符串内左对齐 s.lower() 字符串转换为小写 s.lstrip([chrs]) 删掉字符串前面的空白或指定的 chrs 字符 s.partition(sep) 使用分隔符字符串 sep 划分一个字符串。返回一个元组(head, sep, tail),如果未找到 sep,则返回 (s, "", "") s.replace(old, new [, maxreplace]) 替换一个子字符串 s.rfind(sub [, start [, end]]) 找到一个字符串最后出现的位置,否则返回 -1 s.rindex(sub [, start [, end]]) 找到一个字符串最后出现的位置,否则报错 s.rjust(width [, fill]) 在长度为 width 的字符串内右对齐 s.rpartition(sep) 从字符串结尾开始,使用分隔符字符串 sep 划分字符串 s s.rsplit([sep [, maxsplit]]) 使用 sep 作为分隔符对 一个字符串从后往前进行划分。 maxsplit 决定划分的最大次数,省略 maxsplit 时,结果与 split() 方法完全相同 s.rstrip([chrs]) 删除字符串尾部的空白或者指定的 chrs 字符 s.split([sep [, maxsplit]]) 使用 sep 作为分隔符对一个字符串进行划分。 maxsplit 决定划分的最大次数 s.splitlines([keepends]) 将字符串分为一个行列表。如果 keepends 为 1,则保留各行最后的换行符 s.startswith(prefix [, start [, end]]) 检查一个字符串是否以 prefix 开头 s.strip([chrs]) 删掉字符串开头与结尾的空白或指定的 chrs 字符 s.swapcase() 将大写转换为小写,小写转换为大写 s.title() 将字符串转换为标题格式 s.translate(table [, deletechars]) 使用一个字符转换表 table 转换字符串,删除 deletechars 中的字符 s.upper() 将一个字符串转换为大写形式 s.zfill(width) 在字符串的左边填充 0,直至其宽度为 width 说明 下面是 s.format() 方法的应用举例: >>> a = "Your name is {0} and your age is {age}" >>> a.format("Mike", age=40) 'Your name is Mike and your age is 40' >>> table th:first-of-type { width:220px;}
七月
20
2016

由于PHP博客抽风引发的吐槽

Hy369 的 PHP 博客运行也有两年多了,原本就是弄着好玩的东西,却是不知不觉中记录了一些自己成长的足迹。 慢慢的,自己对博客的使用也频繁起来,虽然没有达到一日不看寝食难安的程度,却也能经常想起了,感觉已经是自己生活中的一部分。 也正是因为关注得多了一些,也就发现博客间歇性地无法访问。 按理说,我用的是国内的空间,也是经过了正规备案的,不应该出现这个问题吧?? 或者说是因为我用的虚拟空间的缘故?若真是这样,难道我还得换个 VPS 之类的不成??这样成本也太高了吧!! 要说编程方面,我还勉强没什么问题,可是涉及到这样的问题,我还真是不知道怎么办。 所以就随便吐槽一下,做个记录,以便于观察一段时间,再看看要不要换换服务商之类的吧。 只是换服务商,貌似备案这些又得怎么捣腾一下,真是麻烦!! 明天起有四天天府大道单双号限行,也就意味着周五我得坐车上班了,好在这几天坐公交车免费,哈哈!! 还有最近的伙食,以前吃九块吃到想吐,然后换了十五块的,觉得好贵,结果久了吧,也就觉得不贵了!!这是什么道理?? 随便吐槽,该文仅用于将来回看时给自己添一点小料!
七月
14
2016

使用解析缓存器缓存表达式

表达式语言(ExpressionLanguage)组件已经提供了一个 compile() 方法来允许缓存原生 PHP。事实上,该组件也可以缓存解析过的表达式,因此,重复的表达式可以更快地被编译和执行。 工作流程 在提供返回值之前,evaluate() 和 compile() 两个方法需要额外做一些工作。对于 evaluate() 方法,这些开销会更大。 两个方法均需要标记和解析表达式。这些工作都可以通过 parse() 方法来完成。它将返回一个 ParsedExpression 对象。目前,compile() 方法只是返回一个该对象转化而成的字符串。evaluate() 方法则还需要循环地动态执行 “节点(nodes)”(保存在 ParsedExpression 中的表达式片段)。 在保存阶段,表达式语言(ExpressionLanguage)将缓存解析后表达式(ParsedExpression),因此重复的表达式将跳过标记(tokenize)和解析(parse)步骤。缓存功能将被解析缓存器接口(ParserCacheInterface)的实例完成(默认情况下,会使用数组解析缓存器(ArrayParserCache))。你可以通过创建自定义的解析缓存器(ParserCache)然后注入到对象的构造方法中来实现缓存功能。 use Symfony\Component\ExpressionLanguage\ExpressionLanguage; use Acme\ExpressionLanguage\ParserCache\MyDatabaseParserCache; $cache = new MyDatabaseParserCache(...); $language = new ExpressionLanguage($cache); DoctrineBridge 提供了一个使用 doctrine cache library 的解析缓存器的实现,该实现为所有分类的缓存策略提供了缓存功能,例如:Apc,Filesystem 和 Memcached。 使用解析和序列化过后的表达式 evaluate() 和 compile() 方法均可以操作 ParsedExpression 和 SerializedParsedExpression: // ... // parse() 方法返回 ParsedExpression $expression = $language->parse('1 + 4', array()); var_dump($language->evaluate($expression)); // 输出 5 use Symfony\Component\ExpressionLanguage\SerializedParsedExpression; // ... $expression = new SerializedParsedExpression( '1 + 4', serialize($language->parse('1 + 4', array())->getNodes()) ); var_dump($language->evaluate($expression)); // 输出 5 原文地址:Caching Expressions Using Parser Caches
七月
07
2016

表达式语言(ExpressionLanguage)组件

表达式语言(ExpressionLanguage)组件是 Symfony 组件之一,该组件对表达式语言进行了功能支持。表达式语言(ExpressionLanguage)提供了一个用于编译和执行表达式的引擎。此篇文章是英文原文的翻译版本,原文地址已经在 PHP 博客的文尾附带。由于能力不足,翻译不准之处还望见谅!

阅读全文>>

六月
24
2016

symfony ParameterBag::resolveValue() 方法的用途

说明 symfony 中参数包 ParameterBag 的 resolveValue() 方法是个很常用的方法。 当然,我这里所谓的常用是指 symfony 系统内部,对于那些不在意 symfony 内部代码的朋友们,此处可以忽略了。 该方法很常用,Hy369 本身也觉得比较重要且时间一长就容易迷糊,所以特地记录在自己的 PHP 博客中。 方法解释 既然这里提到了 ParameterBag::resolveValue() 方法,那么就无法绕开 ParameterBag::get() 和 ParameterBag::resolveString() 方法了,因为这几个方法是紧密关联的。所以 ParameterBag::get() 和 ParameterBag::resolveString() 功能也会在这里一并记录。 ParameterBag::get($name) 参数: $name 需要获取的参数的名称 函数作用: 通过提供的参数名称,从 ParameterBag::parameters 参数包的参数属性中取得对应的值。 这里要特别提到一个功能,代码片段如下: $alternatives = array(); foreach ($this->parameters as $key => $parameterValue) { $lev = levenshtein($name, $key); if ($lev <= strlen($name) / 3 || false !== strpos($key, $name)) { $alternatives[] = $key; } } 这段代码在对应的参数名称不存在时,会遍历所有已经存在的参数,通过 levenshtein() 函数进行参数比较,从而筛选出比较相近的参数名称,然后在接下来抛出的异常中给出可能值的提示。不得不说,这是一个让我惊叹的代码,哈哈。 ParameterBag::resolveValue($value, array $resolving = array()) 参数: $value 需要进行解析的值,数组和字符串值会进行解析,其它值直接返回传递的值 $resolving 为已经解析过的字符串的集合,该参数用于避免死循环解析 函数作用: 数组类型的值则对该数组进行遍历,然后对数组的键与值均进行 ParameterBag::resolveValue() 递归解析 非数组非字符串类型的值,直接返回本身 字符串值调用 ParameterBag::resolveString() 方法进行字符串解析 ParameterBag::resolveString($value, array $resolving = array()) 参数: $value 是需要进行解析的字符串 $resolving 为已经解析过的字符串的集合,该参数用于避免死循环解析 函数作用: 匹配符合正则 /^%([^%\s]+)%$/ 的字符串,也就是匹配类似 %name% 格式的字符串,如果匹配成功: 如果匹配到的 name 在 $resolving 参数中存在对应的键,则说明出现了死循环解析,此时抛出异常 反之,说明可正常进行解析,在将 name 以 array(name => true) 的形式录入 $resolving 参数中后,通过 ParameterBag::get() 方法取得对应的值。 接下来有个小的分支,若是 ParameterBag::resolved 属性为真,则不对取得的值进行再解析;若属性为假,则继续对取得的值进行再解析 然后将能够匹配正则 /%%|%([^%\s]+)%/ 的字符串,类似 %% 或 %name% 的字符串进行处理后,返回处理后的结果 如果匹配到的字符串为 %%,表明这是一个 % 符号的转义形式,此时直接返回 %% 检测是否死循环解析,即检查 $resolving 参数中是否已经存在对应的键,死循环时抛出异常 获得 name 为名称的参数的值,若参数的值不为字符串或数字,则抛出异常,因为 symfony 本身要求参数必须是字符串或数字 然后判断 ParameterBag::resolved 属性的真假,决定是否进行再解析,最后返回解析后的值
五月
17
2016

我在想,以前为何没好好学英语

正如标题所言,我在想,为何我原来没有好好学英语呢? 随着对 PHP 的深入,尤其是接触 Symfony 以后,发现自己需要的资料的中文版是越来越少。 很多时候为了找到需要的答案,不得不翻阅大量的英文资料才行。 而且最开始的时候,觉得一个百度完全够用了,现在往往是百度一下关键词,瞄了一眼,然后就果断翻墙谷歌英文资料了。也就是这个时候,才觉得有些后悔,当初咋就没有好好学习英语呢? 其实在意识到英语开始变得重要的时候,我也就着手想把曾经死活塞不进脑袋的英语捡起来了,而且在主动的接触英语的过程中,也发现英语远远没有以前认为的那么坑爹!那我为何以前老是学不进呢? 再仔细想想,我又貌似知道了自己学不进英语的原因。 说起来,那还是我小学五年级的时候。(总觉得这句话,看的人得拿着板砖看) 我小学五年级转了一次学,从农村转入城市就读。作为一个农村娃,那时学校只教语文和数学,其它的一概没有!而进入城市就不一样了,什么课程都有开设。而且坑爹的是,英语课程是从小学二年级开始的。 那时候进入城市,啥都不懂,心头有些自卑啊,再加上没有朋友,英语课上啥都不懂,久而久之,我也就觉得我听不懂英语了。也开始无限讨厌英语,然后,这个影响一直持续到我大学毕业!!! 现在略后悔,略后悔,还好不是很后悔,好歹我现在觉得重学英语,虽然会是一段漫长的过程,但是迫于对阅读英文文档的渴望,我还是得努力下去!! 其实,英文文档我还是能看懂个大概的,就是有不少的词我不认识啊!! 好吧,其实我就是要说,我从词汇量太少了! 此处,其实是我作为一个 PHP 程序员,在一个心情有些烦躁的情况下,因为肚子有些饿,所以想晚饭吃什么的时候,莫名其妙的一些吐槽!! 貌似上面这句话还是不够混乱,算了,就这样吧!
五月
12
2016

秒表组件(Stopwatch Component)

组件介绍 秒表组件用于提供计时器功能,用于跟踪某个部分的代码执行用时。秒表组件由外到内,支持秒表节点、秒表事件、秒表周期。这意味着,对一个代码整体,可以对代码分节、分事件、每个事件还可以分不同的周期,然后分别计时与汇总。 Stopwatch 实例化以后,自带根节点 __root__。所有新的节点均是该节点的子节点。 代码摘要 类 Symfony\Component\Stopwatch\Stopwatch 类 Symfony\Component\Stopwatch\Section 类 Symfony\Component\Stopwatch\StopwatchEvent 类 Symfony\Component\Stopwatch\StopwatchPeriod
五月
10
2016

类 Symfony\Component\Stopwatch\Stopwatch

类简介 秒表类,统一调度秒表节点、秒表事件、秒表周期 类摘要 Stopwatch { private Section[] $sections private Section[] $activeSection public __construct() public Section getSections() public void openSection($id = null) public void stopSection($id) public StopwatchEvent[] start($name, $category = null) public boolean isStarted($name) public StopwatchEvent stop($name) public StopwatchEvent lap($name) public StopwatchEvent getEvent($name) public StopwatchEvent[] getSectionEvents($id) } 属性 sections 秒表节点实例集合 activeSection 已激活的秒表节点的实例集合 方法 Stopwatch::__construct 秒表的构造方法 Stopwatch::getSections 获取当前秒表的所有秒表节点 Stopwatch::openSection 打开一个秒表节点 Stopwatch::stopSection 结束最后一个开始的秒表节点 Stopwatch::start 开始已激活最后一个秒表节点的某个秒表事件 Stopwatch::isStarted 判断已激活最后一个秒表节点的某个事件是否开始 Stopwatch::stop 结束已激活最后一个秒表节点的某个秒表事件 Stopwatch::lap 结束已激活最后一个秒表节点的秒表事件,并开始一个新的秒表事件 Stopwatch::getEvent 获取已激活最后一个秒表节点的某个秒表事件 Stopwatch::getSectionEvents 获取某个秒表节点的所有秒表事件
五月
07
2016

类 Symfony\Component\Stopwatch\StopwatchPeriod

类简介 用于存储秒表某个周期的相关数据,开始时间,结束时间,周期内分配给 PHP 的内存大小 类摘要 StopwatchPeriod { private int $start private int $end private int $memory public __construct($origin, $category = null) public int getStartTime() public int getEndTime() public int getDuration() public int getMemory() } 属性 start 周期开始时间(毫秒) end 周期结束时间(毫秒) memory 分配给 PHP 的内存的大小 方法 StopwatchPeriod::__construct 秒表周期构造方法 StopwatchPeriod::getStartTime 获得秒表周期开始时间(毫秒) StopwatchPeriod::getEndTime 获得秒表周期结束时间(毫秒) StopwatchPeriod::getDuration 获得秒表周期结束时间与开始时间的时间差(毫秒) StopwatchPeriod::getMemory 获得分配给 PHP 的内存的大小