域名地址更新为levi.yii.so,之前的地址可直接跳转

levi.cg.am更换为levi.yii.so,而levi.cg.am将永久性跳转至levi.yii.so

说起来有点小炖都有点无奈,14号的时候收到管局短信通知cg.am被撤销备案。得不到原因,不排除有人举报。而在此期间,我做了以下几件事:

先购买一个国外的云服务器暂时代替。当时考虑的是这家:https://www.digitalocean.com/,号称SSD的硬盘,以及jquery之父推荐,于是就购买了。花了1天左右的时间,将大环境搭建上,结果有点差强人意,速度很慢就不说了。但是经常性的502,ping值也经常丢包。

调试花了大半天功夫,问题时断时续,决定放弃,不值得。

于是使用一个备案的域名作为替换,之前的域名进行301跳转,结果很顺利,大约就花了半天时间。

这就是这两天的经过,对于这件事我就暂且不发表看法。就当作吃饭吃到一粒沙子,吐了就好了。饭还是可以继续吃的。

说了这么多,最后我想告诉大家,乱炖还好,今后还是会继续提供技术交流、科学上网的方法,而cg.am这个域名,也在走重新备案的流程了,大家不必担心。

发表在 CSS/HTML | 22条评论

MAC系统默认命令行环境BASH版本升级修改

U5317U4eac这样的Unicode编码中文编码字符,经常会出现在iOS开发过程中。在断点调试的时候,控制台打印出来的都是这种编码,而不是中文,如何打印输出这种文字,真的很头疼。

之前在唐巧的博客中,看到他提到,可以在系统终端中,使用” echo”命令来将Unicode的字符转义成中文,可是在自己的mac上试验却始终不成功。

从万能的谷歌那里找到问题的根源,是由于Mac自带的终端bash版本过低,3.8.x的版本,无法支持echo 输出中文。那么只要将系统自带的bash升级到最新版本(至少要4.2.x以上)即可。

首先在终端中执行以下命令,用来安装bash最新版本:

brew install bash

如果没有安装homebrew,可以在这里查看相关帮助:http://levi.yii.so/archives/1742

安装完成后,你可以从opt目录下获得对应的文件,记录下来

/usr/local/opt/bash/bin/bash

修改/etc/shells文件,执行:

sudo vim /etc/shells

将刚才的完整路径复制到这一文件中,执行:wq!保存退出

执行: 继续阅读

发表在 Mac/ios | 标签为 | 一条评论

兼容移动端的轮播插件 – Camera

自此之前写了一篇关于移动端触屏事件的文章,感兴趣的童鞋,可以【点击此处查看原文】,不过由于Android各个机型都不一致,会存在问题,为了更方便在生产环境使用,在这里我介绍一款现成的轮播插件:camera,兼容性很好,兼容各大浏览器。

这里有几个DEMO,大家可点击查看下(可以使用手机访问以下地址):

Camera插件是一个基于jquery 插件的开源项目,功能是对所有指定的图片集实现轮播的效果,在轮播过程中,用户可以查看每一张图片的主题信息,手动终止播放过程,可以查看没有涨播放的图片。主要引入camera.js就可以实现。 继续阅读

发表在 jQuery | 标签为 , , | 2条评论

开发者福音,0费用,顺畅获取墙外开发资源~

作为开发者,很多时候可能会用到github、google,亦或者是需要通过Android Studio下载需要的SDK;当您处于一个封闭的网络环境,而受到限制的时候,请求这些资源就会难以实现。出于这个原因,小炖在此整理了一些免费的途径,帮助开发者能够更好的获取开发资源。

这篇文章会围绕以下集中情况进行说明(若有补充,欢迎在本日志中回复告知):

  1. 正常访问google搜索开发资料
  2. github请求代理,实现快速得push / fetch等操作
  3. 更新android sdk,Android开发者必备(附:编译Fresco)
  4. composer镜像,PHP开发者必备
  5. npm镜像,Node开发者必备
  6. HomeBrew镜像,Mac开发者必备

正常访问google搜索开发资料

适合开发人群:所有

可以选择以下方式中任意一种实现目的

github请求代理

适合开发人群:所有

添加代理连接至配置文件中:

git config --global http.proxy http://hx.gy:1080

如果要移除, 编辑~/.gitconfig
继续阅读

发表在 PHP, 软件、软件使用 | 标签为 , , , , | 11条评论

使用composer来管理wordpress

composer是一个好东西,类似node中的npm,在接触没多久的时候就一直有个想法,能不能在wordpress中使用composer,因为composer有大量非常好且实用的资源。

在早前的时候我的做法是这样的,先建立一个wordpress项目,在wordpress根目录中建立一个composer.json之后,执行`composer install`来进行包管理。那结果根目录就会像这样。

wp-admin/
wp-content/
wp-include/
vendor/
composer.json
composer.lock
index.php
license.txt
readme.html
wp-activate.php
wp-blog-header.php
wp-comments-post.php
wp-config-sample.php
wp-cron.php
wp-links-opml.php
wp-load.php
wp-login.php
wp-mail.php
wp-settings.php
wp-signup.php
wp-trackback.php
xmlrpc.php

使用过wordpress的朋友应该对这样的结构都不会陌生,他存在以下几个问题:

  • wordpress核心文件和composer参杂在一起
  • 结构不清晰,使用不方便
  • 看上去很不友好

最近在网上无意找了些资料,发现有种方法可以使得wordpress更好的搭配composer进行包的依赖管理。最终可以实现如下的目录结构

wp-content/
wp/
vendor/
composer.json
composer.lock
index.php

下面我将个人实践的方法做个简单的记录,和网上搜索到的普遍资料有些不一样,我个人做了一些优化,具体有哪些优化,请继续往下看。

初次安装wordpress的用户

1.初次安装需要先配置`composer.json`,我的配置信息如下 继续阅读

发表在 wordpress | 标签为 , , | 留下评论

CNNIC发布中间人攻击证书,及各种操作系统、浏览器清除方法

★CNNIC到底干了啥事?

最近这段时间,CNNIC 不甘寂寞,又在 CA 领域,搞了点小动作。今天先来说一下,CNNIC又“坑蒙拐骗”了哪些主?

  这件事情再次显示,互联网证书颁发机制公开透明的必要性。

谷歌英文博客原文:Maintaining digital certificate security

Mozilla英文博客原文:Revoking Trust in one CNNIC Intermediate Certificate

参考资料:中国互联网络信息中心(China Internet Network Information Center,缩写为CNNIC),是经中华人民共和国国务院主管部门批准,于1997年6月3日成立的互联网管理和服务机构。中国互联网络信息中心成立伊始,由中国科学院主管;2014年末,改由中央网络安全和信息化领导小组办公室、国家互联网信息办公室主管。

◇Mozilla.org

可能某些IT圈外的同学会问,Mozilla是嘛玩意?简单地说,“Mozilla 和 Firefox 的关系”就好比“微软和 Windows 的关系”。因此,Firefox 自带哪些 CA 根证书,是由 Mozilla 组织决定滴。
话说2009年初那会儿,CNNIC 里面的某个员工(liu_yan@cinic.cn)到 Mozilla 网站提交了一个申请:要求将 CNNIC 加入 Mozilla 的 CA 列表。此申请经过几个月的讨论。到了2009年底,审批获得通过。至此,CNNIC 正式成为 Mozilla 的 CA 之一(请看“Mozilla官方的CA列表”)。懂洋文的同学,请自行到“这里”看详细的申请过程。
因此,从 Firefox 的3.6版本开始,其内置的诸多根证书中,将会包含 CNNIC 提供的根证书。

◇微软(Microsoft)

说实在的,俺不清楚 CNNIC 是如何忽悠微软,让微软把它也加入到 Windows 内置的 CA 列表中的。不过这已经不重要了。现在,老流氓已经把它脏兮兮的触角,伸到了微软那儿。列位看官如若不信,可以去看“微软的CA列表”。
今后,如果你安装了微软新的操作系统,多半其已经包含了 CNNIC 的根证书;即便你一直使用老版本的 Windows,也可能在自动升级了某个Windows补丁之后,把CNNIC的根证书带到你的电脑中。

◇Entrust.net

除了 Mozilla 和微软,还有一个组织也被 CNNIC 牵连了,那就是 Entrust ——国外一家比较老牌的 CA。正是由于该 CA 比较老牌,因此 Windows 系统(至少包括 Win2000 之后的版本)中以及 Firefox 中,都已经内置了它的根证书。
老流氓大概是花了些银子,于是该CA提供的根证书就信任了CNNIC制作的某个SSL证书。
到了2010年下半年,Entrust 大概也意识到 CNNIC 的名声太臭,就解除了跟 CNNIC 的信任关系。所以,如今【新的】Entrust 证书,已经不再信任 CNNIC 的 SSL 证书了。如果你的浏览器是新版本或者 Windows 系统更新过新的补丁,其内置的 Entrust 证书应该是安全的,不用清理了。如果你吃不准Windows系统或浏览器内置的Entrust证书是否安全,请根据本文后续章节“★如何确认门户已经清理干净”介绍的方法判断。

用浏览器访问一下 https://www.cnnic.cn 记得用 HTTPS 协议哦,如果浏览器没有报告证书有问题,那么你很有可能受到CA证书的中间人攻击了

★这事儿对咱有啥影响?

那电脑中有了 CNNIC 的证书,会出现啥鸟事捏?俺大概说一下。

◇“中间人攻击”的风险

中间人攻击的风险,是最危险的,也是最经常被提及滴。
CA 证书对于 https 协议的重要性(可以防止攻击者伪造虚假网站)。既然 CNNIC 已经成为合法的 CA,那它就能堂而皇之地制作并发布CA证书。然后捏,再配合GFW进行DNS的域名污染。那GFW就可以轻松搞定任何网站的HTTPS加密传输。
可能有些小朋友心里会犯嘀咕:GFW 会有这么坏吗?GFW 和 CNNIC 一起进行中间人攻击(一个负责在 DNS 上做手脚、另一个负责伪造 CA 证书),简直是天生一对、黄金搭档!

◇ActiveX控件的风险

另外一个大伙儿不太关注的风险,是关于 ActiveX 控件的问题。前几年,很多恶意软件(包括流氓软件、木马)都是通过 IE 控件的技术,安装到大伙儿的电脑上。后来微软加强了对 ActiveX 控件的验证:在 IE 的默认设置下,对于【没有】数字签名的 ActiveX 控件,默认是拒绝安装滴;而对于有数字签名的控件,则会给出提示。
因此,老流氓 CNNIC 可以很轻松地给自己的 ActiveX 控件制作数字证书。然后把控件放到网上。某些粗心的电脑用户看到IE跳出的安装控件提示,多半没细看,直接就点了“确定”按钮。

★如何清理门户?

其实网上关于如何去掉证书的操作指南,多如牛毛,所以俺就简单说一下。
有些浏览器(IE、Chrome、Safari)使用的是操作系统的证书体系。这种情况下,你需要把 CNNIC 证书从操作系统的证书体系中去掉。还有些浏览器(比如Firefox、Opera)是自己带了一套证书体系。你只要在其配置界面,把不要的证书去除即可。下面分不同的浏览器,不同的操作系统,分别介绍。 继续阅读

发表在 网络产品、信息 | 标签为 , , | 8条评论

在Mac OS X上安装dnsmasq来支持hosts泛解析

最近访问谷歌系列网站越来越慢了,不探究原因,但这让我感到非常苦恼,如果连Google都使用不了的话,那我上网的意义就失去了一半了。不过好在我们有hosts,可以实现简单的翻墙,来解决大多数谷歌服务的访问问题。

Hosts地址见:

http://levi.yii.so/archives/3553

可是谷歌的域名实在是太多了,我们有没有什么办法来实现类似*.google.com/*的泛解析呢?很可惜,传统的hosts文件不可以。但是有一个叫做dnsmasq的软件,它能提供类似DNS缓存的功能,可以用它来实现很强大的泛解析功能。

下面以OS X Mavericks做例子,来讲述如何安装使用DNSMASQ,来实现谷歌服务直连。

Mac安装DNSMASQ

要安装dnsmasq,你需要先安装Homebrew

它自称“OS X不可或缺的套件管理器”。

安装Homebrew

请打开终端(应用程序>实用工具),并运行

ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

你需要按照提示来继续安装。这个过程或许会很慢,受限于网络状况。如果实在很慢,你可以在VPN环境下安装。

安装完成之后,你就可以使用brew命令来安装dnsmasq了。

安装并配置dnsmasq组件

仍然在终端运行

brew install dnsmasq

现在把/usr/local/opt/dnsmasq/dnsmasq.conf.example文件拷贝至并重命名为/usr/local/etc/dnsmasq.conf

在刚刚的/usr/local/etc/文件夹下新建一个resolv.dnsmasq.conf文件。

用sublime text,textmate,bbedit等纯文本编辑器打开这个resolv.dnsmasq.conf文件,输入以下内容

nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 42.120.21.30
nameserver 168.95.1.1

这些都是你常用的DNS地址,你可以添加更多,比如OpenDNS。

用sublime text,textmate,bbedit等纯文本编辑器打开同文件夹下的dnsmasq.conf文件,增加以下内容 继续阅读

发表在 Mac/ios | 标签为 , , | 一条评论

使用wordpress第三方补丁包,通用解决google字体问题

在网上搜索“wordpress google字体”能找到一大片资料。不过都存在一些问题,下面我将分别进行说明。需要解决这方面问题的朋友,无需手动操作,直接安装补丁包即可。

推荐下我开发的“wordpress 第三方补丁包”,详细说明见:http://levi.yii.so/archives/4603,需要安装的朋友可直接在wordpress后台搜索插件关键字“wp-patch”,即可找到并在线安装。

回到正题,先来看我第一个找到的解决方案

function devework_replace_open_sans() {
    wp_deregister_style('open-sans');
    wp_register_style('open-sans', '//fonts.useso.com/css?family=Open+Sans:300italic,400italic,600italic,300,400,600');
    wp_enqueue_style('open-sans');
}
add_action('wp_enqueue_scripts', 'devework_replace_open_sans');
add_action('admin_enqueue_scripts', 'devework_replace_open_sans');

他存在以下几个问题:

  1. 登录界面不好使
  2. 主题单独自带的google字体调用解决不了(更换一个主题可能就没办法了)
  3. URI老套,不能适应wordpress后续更新

于是有人有提供了下面这个解决方法 继续阅读

发表在 wordpress | 标签为 , , | 10条评论

wordpress第三方补丁包

本人新发表的第三方wordpress补丁包,插件官方页面下载地址是:https://wordpress.org/plugins/wp-patch-levi/,需要安装的朋友可直接在wordpress后台搜索插件关键字“wp-patch”,即可找到并在线安装。

补丁包说明

目前修复了几个问题,如下:

问题1:wordpress文章统计附件不准确,详细请看:http://levi.yii.so/archives/3849。这里就不详细说明了

问题2:大文件上传

对于大文件上传以往需要调整以下几个地方:

  • webserver:nginx、apache或其他程序
  • php.ini:需要调整post最大请求大小,文件最大上传大小以及内存大小

调整完毕之后,就是重启服务器啦。那么如果你是以下人群那么很有可能不那么容易达到目的。

  • 租用虚拟主机,并没有服务器修改权限
  • 对以上技术不是很精通
  • ok,即便以上技术你了解,但是有的时候我们只需要临时调整下
  • 懒得大费周章

于是我借用了HTML5的切割上传技术,解决这个问题,无需做任何设置、也无需调整服务器配置,即可上传GB级大小的文件。

技术剖析: 继续阅读

发表在 wordpress | 标签为 , , , , | 7条评论

友情招聘一枚:北京,移动开发主管,年薪10-25W,求扩散

帮群里的朋友,友情发布招聘一枚,感兴趣的朋友赶集的~

发送简历至:zhaopin@mexue.com.cn

PS:咱们的群号是:116589978,福利多多,欢迎朋友加入~

基本信息:

  • 年薪:10-25W
  • 工作地点:北京-海淀区
  • 所属部门:研发部
  • 汇报对象:总经理
  • 下属人数:4人

员工福利:

年底双薪、股票期权、绩效奖金、带薪年假、通讯津贴、午餐补助、年度旅游、弹性工作、定期体检

职位描述:

岗位职责:

  1. 移动开发团队的管理与分工;
  2. 负责完成软件设计文档;
  3. 负责iOS平台APP的架构设计、功能实现,支持iPhone、iPad、Android等硬件设备;
  4. 负责公司iOS、Android平台的技术研究。

继续阅读

发表在 网络产品、信息 | 标签为 | 一条评论

网络加速计划(免费VPN、Hosts)

为了更方便获取翻墙内容,请移步至:http://levi.yii.so/h-gate

(注意:若果您使用的是IE浏览器无法获取VPN,建议您尝试使用使用:chrome或火狐浏览器哦~)

发表在 CSS/HTML | 57条评论

网络加速计划

VPN、hosts

发表在 CSS/HTML | 一条评论

PHP DOMDocument 在 saveXML 时中文出现乱码

PHP的DOM内部是utf8机制的。在loadHTML时,是通过检查字符中meta的charset来设置编码的。如果没有charset,就当iso8859进行处理了。而这种情况下进行saveXML时,输出来的却是utf8,所以就看到乱码了。

这么说是不是还不太理解,举个例子:

$xml = new DOMDocument();
@$xml->loadHTML('<div>我就是测试看看 - http://levi.yii.so</div>');

$dom = new DOMXPath($xml);
echo $dom->query('//div')->item(0)->saveXML();

打开网页执行,你会发现输出乱码了。那如何解决这个问题呢?有两种方式。

第一种:在loadHTML的时候指定编码,下面这段代码引用自php.net官方文档中的回复

$doc = new DOMDocument();
$doc->loadHTML('<?xml encoding="UTF-8">' . $html);

// dirty fix
foreach ($doc->childNodes as $item)
    if ($item->nodeType == XML_PI_NODE)
        $doc->removeChild($item); // remove hack
$doc->encoding = 'UTF-8'; // insert proper

第二种方法,通过iconv对输出的字符重新转换,代码如下:

echo iconv("UTF-8", "GB18030//TRANSLIT", $dom->saveXML($n) );
发表在 PHP | 标签为 , , | 留下评论

测试你的VPN是否泄露了真实IP

@fightcensorship:VPN被认为是非常安全的网络匿名方法,但最近爆出它并不如人们认为的那样安全,只要在网站上放上一段简单的代码,就可以准确地测出浏览者的真实IP地址,这被称为WebRTC特征。下面这个页面就可以测试你的VPN是否泄露的真实IP(低版本IE无法查看)。

目前WebRTC特征漏洞主要体现在支持WebRTC的浏览器上,包括Firefox和Chrome浏览器,但可以防止。Chrome浏览器在下面两个插件中任意选择1个使用

针对WebRTC特征漏洞,Firefox可在浏览器上输入:about:config。之后搜索:media.peerconnection.enabled。找到它后双击,将其改成 false 即可。
B8tlpaGCQAEvRAf

给大家补充个笑话。由于长宽是“假带宽”的缘故,根本就不存在外网IP,所以无缘这次“漏洞”,上面的测试结果中也看不到外网IP。同样的也包括:华数、有线通、移动(铁通)、联通(网通,部分地区),电信(部分地区)等

发表在 软件、软件使用 | 标签为 , , | 6条评论

android studio升级失败提示 Connection failed解决方法

关于这个问题,查了不少地方,发现解决方法都差不多,但或多或少有些问题或没说清楚。关于在windows系统中的解决方法,基本没什么问题,都是如下修改:

在Android Studio安装目录“/bin/studio.exe.vmoptions”文件中追加以下几行

-Djava.net.preferIPv4Stack=true
-Didea.updates.url=http://dl.google.com/android/studio/patches/updates.xml
-Didea.patches.url=http://dl.google.com/android/studio/patches/

但有点要注意,64位系统就应该修改“/bin/studio64.exe.vmoptions”这个文件。
而下面主要说明修改mac中的升级问题:
在Mac和Linux版本中,网上提供的解决办法,差不多都是如下修改:
直接修改环境变量:

$ export REQUIRED_JVM_ARGS="-Didea.updates.url=http://dl.google.com/android/studio/patches/updates.xml -Didea.patches.url=http://dl.google.com/android/studio/patches/"
$ bin/studio

此方法多次尝试,均以失败告终。最后不得不自行想办法解决,发现如下修改可解决这个问题:

在“/Applications/Android Studio.app”中,右键点击“显示包内容”,打开“/bin/idea.vmoptions”文件,在后面追加入windows中的内容,即:

-Djava.net.preferIPv4Stack=true
-Didea.updates.url=http://dl.google.com/android/studio/patches/updates.xml
-Didea.patches.url=http://dl.google.com/android/studio/patches/

后保存退出,重新打开Android Studio,Check for Updates …就可以看到升级提示了。
注:此方法只是自己摸索尝试在本机上可行,非官方提供,失败勿喷,谢谢!

@lyx0206331

发表在 Mac/ios | 标签为 | 一条评论

Android修改hosts文件的方法和问题

之前有介绍过Mac、windows修改hosts的方法,详细可参考下面两个网址

有朋友问Android怎么修改Hosts?对于这个问题,由于手头并没有Android设备,所以只能从网上搜罗了几个方法,如果有朋友有更好的方法,不妨留言补充。

本文介绍三种Android手机修改hosts文件的方法,但修改hosts文件一定要谨慎:Android手机hosts文件的换行符必须是n而不是windows的rn,使用Notepad++打开hosts文件,依次点击菜单中的“视图–显示符号–显示所有字符”,如果行末是LF就没问题,CR LF结束则需要替换所有的CR LF为LF。

Android手机hosts文件路径:/system/etc/hosts

修改hosts方法一:需重启

  1. 修改host文件首先需要Android手机获取Root权限
  2. 使用Root Explorer管理器或ES文件浏览器装载/system可写状态,找到/system/etc/hosts的文件,使用文本编辑器打开编辑后保存
  3. 保存后重启手机即可生效

修改hosts方法二:不需重启

将hosts文件拷贝到电脑,电脑端修改后复制回手机,这种方法不需要重启

修改hosts方法三

各种android市场中寻找修改hosts的app,例如:

  • hosts 助手
  • smartHosts

至于iOS设备如何修改hosts,可能就需要越狱了,有些麻烦,这里暂且不提。本人目前使用的苹果设备用到的google服务不多,如果有朋友有什么好的方法,也可以留言告诉我

发表在 软件、软件使用 | 标签为 , , | 22条评论

Node.JS vs PHP CLI Server 简单的HTTP服务器性能测试

环境:

  • 64位Ubuntu14.04,i5-3230M
  • PHP5.4.31 with ZendOPcache
  • Node.JS 0.10.35

Node.JS 测试

var http = require('http'); 
http.createServer(function (req, res) { 
    res.writeHead(200, {'Content-Type': 'text/html;charset=UTF-8'}); 
    res.write('<!DOCTYPE html><html><head><meta charset="UTF-8" /><title>Node测试</title></head><body>'+new Date().getTime()+'</body></html>'); 
    res.end(); 
}).listen(8082, '127.0.0.1');

运行程序:

node t.js

查看系统CPU空闲率:

sar 1

压力测试,并发100,完成10万请求:

ab -c100 -n100000 http://127.0.0.1:8082/t.js

内存从11MB涨到61MB,系统CPU空闲率65%, RPS达到6049.

o_215125_VQRC_561214

o_215152_XAqa_561214

o_215210_Aduo_561214

PHP CLI Server 测试

<?php header('Content-Type: text/html;charset=UTF-8'); ?> 
<!DOCTYPE html><html><head><meta charset="UTF-8" /><title>PHP测试</title></head><body><?php echo time(); ?></body></html>

运行程序:

php -S 127.0.0.1:8081 -t ./

查看系统CPU空闲率:

sar 1

压力测试,并发100,完成10万请求:

ab -c100 -n100000 http://127.0.0.1:8081/t.php

内存从19.6MB涨到20.0MB,系统CPU空闲率57%, RPS达到11405.
不开启OPCACHE时,内存从8.3MB涨到9.0MB,系统CPU空闲率57%,RPS达到8851. 继续阅读

发表在 node, PHP | 标签为 , , | 留下评论

给wordpress附件打个补丁,小议三则

自补丁包0.2.6起,去除了新增的方法函数,而采取wordpress自带函数`get_attached_media`来获取文章附件,函数使用方法大家可以自行搜索,补丁说明见:http://levi.yii.so/wiki/wordpress-第三方补丁包/文章附件统计修复

起初做这个研究之前是想了解“wordpress 设置默认特色图片”,这个问题我放后面说,先来看看之前我研究过的一个话题“wordpress统计附件不准确”的问题。

修正wordpress附件统计不正确

具体内容可以在这里查看:http://levi.yii.so/archives/3415,主要原因是因为wordpress为所有的post数据以parent_post方式进行统计的,而这个字段是数字型,如果有多篇文章使用同一个附件的时候怎么办呢?

在之前就已给出了一个解决办法,这里我将其完善,先来看代码,如下:

function save_post($post_id, $post)
{
    global $wpdb;
    if (empty($_POST))
    {
        return ;
    }

    $data = array();
    $content = $post->post_content;
    if (stristr($content, '/wp-content/uploads/') &&
        preg_match_all('/(href|src)=[^>]+/wp-content/uploads/(sites/d+/)?([^"'>s]+)["'>s]/is', $content, $match))
    {
        $files = array_flip(array_flip($match[3]));
        $sql = "SELECT `post_id` FROM `%s` WHERE `meta_key`='_wp_attached_file' AND (`meta_value`='%s');";
        (FALSE != ($row = $wpdb->get_col(sprintf($sql, $wpdb->postmeta, implode("' OR `meta_value`='", $files))))) && $data = $row;
    }

    if (stristr($content, 'gallery') && preg_match_all('/[gallerys+ids=(["']?)([^"']]*)1s*]/is', $content, $gallery))
    {
        $where = array();
        $gallery = explode(',', implode(',', $gallery[2]));
        foreach ($gallery as $val)
        {
            $where[] = '`post_id`='.trim($val);
        }

        $sql = sprintf("SELECT `post_id` FROM `%s` WHERE `meta_key`='_wp_attached_file' AND (%s);", $wpdb->postmeta, implode(' OR ', $where));
        (FALSE != ($row = $wpdb->get_col($sql))) && $data = array_merge($data, $gallery);
    }

    if (FALSE != ($thumb_id = get_post_meta($post_id, '_thumbnail_id')))
    {
        $data[] = $thumb_id[0];
    }

    $data = apply_filters('wp_post_attach_total', $data, $post_id);
    if (!empty($data))
    {
        $data = array_flip(array_flip($data));
        update_post_meta($post_id, '_wp_post_attach_total_', implode(',', $data));
    }
    else
    {
        delete_post_meta($post_id, '_wp_post_attach_total_');
    }

    wp_cache_delete('attach_meda-'.$post_id, 'wp-plus');
}

function get_attached_from_post($post_id, $type = '', $must = false)
{
    $key = sprintf('attach_meda-%d', $post_id);
    if (!$must && false != ($cache = wp_cache_get($key, 'wp-plus')))
    {
        return $cache;
    }

    if (false == ($meta = get_post_meta($post_id, '_wp_post_attach_total_', true)))
    {
        return array();
    }

    $arg = array(
        'include' => $meta,
        'post_type' => 'attachment',
        'post_mime_type' => $type,
        'posts_per_page' => -1,
        'orderby' => 'menu_order',
        'order' => 'ASC'
    );

    if (false == ($data = get_posts($arg)))
    {
        return array();
    }

    return wp_cache_set($key, $data, 'wp-plus', 900);
}

add_action('save_post', 'save_post', 100, 2);

改进如下:

  1. 避免设置回收站时,重复操做文章,关于这个优化,详细可以看这里:http://levi.yii.so/archives/3842
  2. 图片和相册分别判断
  3. 增加一个查询数据的函数
  4. 增加缓存机制,缓存获取的数据,减少服务器压力

这里说下查询函数,之前在文章中有提供一个查询附件统计的方法 继续阅读

发表在 wordpress | 标签为 , , | 11条评论

Chrome强制http定向到https方法

在此之前曾推荐过一款chrome插件

KB SSL Enforcer:强制使用安全加密连线

http://levi.yii.so/archives/3666

但是有人反馈使用插件过程中会出现问题,例如有道使用不了等情况。而今天我要介绍一款更好用的方法,使用chrome浏览器本身实现网页定向到https,无需安装任何插件

此前分享过,修改Hosts的方式实现翻墙,但是就如果访问Google+(plus.google.com)一样不能直接访问,而是需要https的安全连接才行。你会发现有不少通过修改hosts的方式访问的网站都需要这么做,因此你会觉得很烦琐,比如google groups,Twitter等等。其实如果你使用的是Chrome浏览器,只需几个简单的步骤即可: 继续阅读

发表在 软件、软件使用 | 标签为 , , , | 一条评论

WordPress 添加Meta Box中几个关键点

什么是wordpress的Meta Box

Meta Box就是wordpress中的自定义数据信息组合,当我们发表一篇文章的时候会作为一个额外的表单区域添加进来作为信息编辑。在数据库中的字段分别为:

  • meta_id:Meta Box的ID
  • post_id:文章ID
  • meta_key:Meta Box的关键字段
  • meta_value:关键字段值

这个就不多提了,有兴趣大家可以自己搜索资料

如何添加Meta Box

网上文章很多,这也不是今天要说的,有兴趣大家可以看看一位朋友写的技术文章:WordPress 添加Meta Box,比较通俗易懂。而今天我主要提的是添加Meta Box的几个关键事项,我会拿这篇文章作为示范举例;其中包括几个没有被提到的点,下面的内容需要对wordpress有一定了解

添加Meta Box

在示例中有段代码:

add_meta_box(
    'rating_meta_box_id', '推荐指数', 'render_rating_meta_box', $type, 'side', 'default'
);
  • 第三个参数为回调函数,作为展示用
  • 第四个参数为文章类型,支持自定义文章类型
  • 第五个参数为展示位置,分别有:normal、advanced、side,默认是advanced
  • 第六个参数为展示优先级,分别有:high、core、default、low,默认是default

接着来说说展示内容需要注意的几个地方

判断文章类型

尤其是给自定义文章类型添加Meta Box尤其重要,你可能不是为所有文章都添加自定义字段。在添加Meta Box的时候会指定一个回调函数,回调函数的第一个参就是当前文章对象,可以根据当前对象来判断文章类型,类似下面这段代码: 继续阅读

发表在 wordpress | 标签为 | 3条评论

mysql 存储过程简单学习

存储过程 Stored Procedure

存储过程就是保存一系列SQL命令的集合,将这些sql命令有组织的形成一个小程序,这样会实现很复杂的处理。SQL基本是一个命令一个命令执行,虽然可以通过连接、子查询等实现些高级的处理,但局限性是显而易见的

存储过程的优势

  1. 提高执行性能(存储过程事先完成了解析、编译的处理,执行时能减轻数据库负担)
  2. 可减轻网络负担(比起多次传递SQL命令本身,这大大减轻了网络负担)
  3. 可防止对表的直接访问(可只赋予用户对相关存储过程的访问权限)
  4. 存储过程会保存在数据库中,应用程序只需要知道调用哪个存储过程就可以完成相应处理

使用存储过程

参数种类分为:

  • IN:输入型
  • OUT:输出型
  • INOUT:输入输出型
SELECT column1.. INTO 变量1... FROM table1 WHERE xxx; //这个变量1对应OUT,INOUT

格式:

create procedure 存储过程名(
    参数种类1 参数1 参数类型1
    参数种类2 参数2 参数类型2...)
begin
    处理内容
end

示例:

DELIMITER //
CREATE PROCEDURE search_customer(
    IN p_nam VARCHAR(20))
BEGIN
    IF p_nam IS NULL OR p_nam = '' THEN
        SELECT * FROM customer;
    ELSE
        SELECT * FROM customer WHERE nam [LIKE] p_nam;
    END IF;
END
//
DELIMITER;

请将上面的[LIKE]替换为LIKE,SB度娘云加速以为我要攻击自己服务器。。。

注意事项

  1. DELIMITER命令改变分隔符
    默认分隔符是“;”存储过程中肯定会有“;”,所以使用其将分隔符改为“//”,创建好后,在将分隔符改回“;”
  2. 可使用的控制语句

简单的实例

创建存储函数 继续阅读

发表在 Mysql | 标签为 | 留下评论

如何在MAC OS、Linux和Windows清除本地DNS缓存

之前写过一篇刷新本地缓存的方法:http://levi.yii.so/archives/987,这篇算是在其基础上进行补充

对于经常携带笔记本办公的人士,有时候会发现在一个地方上网好好的,但是换了一个地方就上不了网,重复开关机也不行,但是别人电脑访问确实没有问题的。而且奇迹的是,过了一些时间,再访问同样的网站,竟然自己好了,这个有可能是本地DNS缓存在作祟。

下面分别介绍不同操作系统清除缓存的方法,以下都是在终端操作的指令:

Mac OS X

OS X 10.10

sudo discoveryutil udnsflushcaches

OS X 10.9

dscacheutil -flushcache; sudo killall -HUP mDNSResponder

OS X 10.7-10.8 继续阅读

发表在 软件、软件使用 | 标签为 , , | 5条评论

移动端屏幕适配viewport

pc上的网站在移动端上怎么办?

如果把移动端的可视区域(320-768)的话,大部分网站都会因为太窄而显示错乱;

所以浏览器默认把viewport设置为一个较宽的值 980px或1024px,至少保证PC网站在移动端上可以显示,只不过出现了横向滚动条而已。

几个概念

  • css像素
    • html中度量的单位 用“px”来计算,在“pc”中往往 “1 css像素” = “1 物理像素”
    • 在不同设备中1px对应不同的“设备像素”;iphone3分辨率是“320×480”即 “1 css像素” =“1 物理像素”;iphone4 分辨率“640×960”,但屏幕尺寸没有改变,意味着同一块区域像素多了1倍。即:“2 css像素” = “1 物理像素”;
  • 物理像素
    • 表示每英寸所拥有的像素数目,数值越高,代表屏幕能够以更高的密度来显示图像
  • 分辨率
    • 显示器所能显示的像素多少,显示器可以显示的像素越多,画面就越精细,同样的屏幕区域能显示的信息就越多
  • devicePixelRatio“window.devicePixelRadio = 物理像素/css像素” 在iphone4中“devicePixelRatio=2” 也就是“1css像素=2个物理像素”

    devicePixelRatio在不同浏览器中存在一些兼容性问题,并不是完全可靠的

  • layout viewport
    • 移动设备的默认“viewport”,css布局是以“layout viewport”来做为参考系计算的
    • “document.documenElement.clientWidth”获取
    • 该尺寸时动态设置
  • visual viewport
    • 代表浏览器窗口的尺寸,当用户放大浏览器时这个尺寸就会变小
    • “window.innerWidth”获取
  • ideal viewport
    • “屏幕尺寸”设备屏幕的尺寸单位是“物理像素”
    • “screen.width”获取 屏幕尺寸是不变的
    • 在该“viewport”中用户不需要缩放和横向滚动就可以正常查看网站的所有内容
    • 设置移动端网站一般以这个“viewport”为准,“ideal viewport”的宽度等于设备屏幕宽度,使得无论在什么分辨率下,那些针对“ideal viewport”设计的网站都可以完美的呈现给用户。

如何来实现屏幕适配

需要用到 继续阅读

发表在 Javascript | 标签为 | 2条评论

简谈wordpress中的ajax请求,为什么会一直返回“0”

最近我发布了一款数据导入wordpress的插件,有兴趣的可以看这里:http://levi.yii.so/archives/3759;优化这款插件的时候遇到一个问题,使用ajax向wordpress发起请求,返回回来的始终是0!

至于这个问题,我放后面谈,先简单说下wordpress的ajax请求。

发起请求

wordpress中要发起ajax请求不难,分别需要如下:

PHP记录一个ajax钩子,以便后续操作:

&lt;?php
function press_data()
{
    // do it...
    exit;
}

wp_register_script('request_data', plugins_url('request_data.js', __FILE__), array('jquery'));
wp_enqueue_script('request_data');

add_action('wp_ajax_press_data', 'press_data');

从上面可以得出以下结论:

  1. wordpress是通过add_action记录一个ajax请求的钩子
  2. 钩子的名称前缀必须是“wp_ajax_”
  3. 钩子回调方法中必须通过“exit”或“die”来结束输出(后面会继续说明)
  4. 通过“wp_register_script”注册一个js,用于发起请求

js发起ajax请求:

jQuery.ajax({
    type: 'POST',
    url: ajaxurl,
    data: {
        action: 'press_data'
    },
    success: function(res) {
        // get res
    }
});

从上面可以得出以下结论:

  • url请求地址为一个固定的变量:ajaxurl
  • 请求的“data”数据中必须有一个“action”属性,属性值必须和之前ajax记录请求的钩子名称对应

这些并不难,如果说还要增加点花样的话,比如说php传个值让ajax请求时带上,那么可以通过函数:wp_localize_script,如下:

// 注册一个钩子
wp_register_script('request_data', plugins_url('request_data.js', __FILE__), array('jquery'));

// 传递一个值
wp_localize_script('request_data', 'request_data', array(
    'url' =&gt; 'http://levi.yii.so'
));

// 调用这个js
wp_enqueue_script('request_data');

而之前的js也仅需要这么修改即可:

jQuery.ajax({
    type: 'POST',
    url: ajaxurl,
    data: {
        action: 'press_data',
        form: request_data.url
    },
    success: function(res) {
        // get res
    }
});

以上这些都不难,就提到这里,有不明白欢迎留言提问。

Ajax的流程

要搞清楚为什么ajax请求一直返回0这个问题,先要搞清楚整个请求流程。

wordpress注册ajax的流程: 继续阅读

发表在 wordpress | 标签为 , | 留下评论

wordpress插件:将博客园、开源中国的博客文章导入到wordpress中

插件已更新,文档已经重新整理规范至WIKI中,详细情况请参见:

http://levi.yii.so/wiki/cnblogs数据导入wordpress

在11年的时候就发布过一个数据导入的插件,最近有朋友反馈会报错。经过检查问题应该出在xml文件检测上。

在重新优化这款插件之前,就一直有个想法,希望能够按照官方提供的wordpress-importer的文件导入流程来优化这款插件流程。由于时间关系,一直搁置没有动过。介于这次机会重写了一遍这款插件。

这款插件已在wordpress插件中心上线,大家可以直接在wordpress控制台进行在线安装,安装方法:

  1. 在wordpress控制台,点击“安装插件”搜索“cnblogs”或搜索“osc”即可找到插件
  2. 点击安装,稍作等待即可
  3. 进入“已安装的插件”页面启动插件

你也可以通过离线的方式安装,安装方法

  1. 下载离线插件包并解压

    下载地址:https://downloads.wordpress.org/plugin/cnblogs2wp.0.2.1.zip

  2. 复制目录到/wp-content/plugins/目录下
  3. 进入wordpress控制台
  4. 插件管理中找到并启用“转换博客园、开源中国博客文章到wordpress

数据导入方法: 继续阅读

发表在 wordpress | 标签为 , | 43条评论

通过DateQuery完善倒计时、日历所需的常用功能

DateQuery是本人些的一个时间操作类,类库的文档可在此查看:

一行JS搞定时间增删改、倒计时,来自类库:lv-js

http://levi.yii.so/archives/3690

这个类库本身是作为方便操作时间的对象,不过发布后看来,不少朋友对“倒计时”这个功能很感兴趣,所以这里我就围绕这个来说说这个类库的特性,在篇尾还会顺带提一提,新增加的walk方法,对于需要做日历、时间提醒等插件的朋友,很有帮助哟~

倒计时

最简单的一个倒计时,核心代码:

setInterval(function() {
    lv.date().set('2015-11-12 11:00:20', true).get('g', true);
}, 100);

上面代码的意思是设置一个截止时间为:2015-11-12 11:00:20 的DateQuery对象,每100秒取一次时间差。当然如果将上面代码如下优化,可能会更好哦:

// 先申明一个DateQuery对象
var date = lv.date().set('2015-11-12 11:00:20', true);

// 每100毫秒获取一次时间差
setInterval(function() {
    date.set().get('g', true);    // 注意这里的set哦,他会自动更新当前时间
}, 100);

具体方法请参考文档:http://levi.yii.so/archives/3690

提供一个在线演示: 继续阅读

发表在 Javascript | 标签为 , , , , | 3条评论

神奇的Chrome QUIC,加速你的网络

magic
经常收到网友的问题,Chrome的Web Store打不开,无法下载扩展。对于Chrome来说这可是大事啊,使用起来真是大打折扣啊。
启用方法,新的版本,比如我的是40:

  1. 打开chrome://flags。
  2. 搜索QUIC,找到实验性QUIC协议,设为启用,重启Chrome。
    quic

老的版本要多一个步骤:

  1. 打开chrome://flags。
  2. 启用“实验性 QUIC 协议”和“经由实验性 QUIC 协议发出的 HTTPS 请求”,重启Chrome。

网上有人说Win 8.1开启后会崩溃,我看应该是Chrome早期版本,高版本应该稳定了。

其实这个方法早就在网上有介绍,由于 继续阅读

发表在 软件、软件使用 | 标签为 , , | 8条评论

像node加载包一样加载你的PHP,来自类库:lv

优化这个类库的初衷咱就不放在篇头来说了,直接进入主题。

安装和更新类库,见这里:

http://levi.yii.so/archives/3534#install

lv中类包特点

首先PHP没有明确的包概念,这个是借鉴了node;php只有调用文件的概念,需要这么做

include 'path/file.php';

那么问题来了,这样会导致可能重复引用一个文件,还会报错

于是PHP做了一个解决的办法

include_once 'path/file.php';

这样就解决了重复引用一个文件的问题,那么问题来了,这样做效率太差

于是就有了后来的spl的概念,而lv这个类库早前设计的时候就是按照psr的标准,用spl+namespace的方式来调用类文件,像这样

// 来自lv类库中的http的请求方法
use lv\request\HTTP;
$http = new HTTP('http://levi.yii.so');

他实现了几个优点:

  • 按需要加载,所有的对象不是说我使用了use了,就一定会inclued,而是说只有当我程序执行到一个未知调用的时候才会去加载类;这样操作的好处就在于,你可以use成千上百个类文件,但最终去调用、加载的只有当前需要的那么几个文件(对于这点不长篇解释,有兴趣的朋友请查看源文件)
  • 避免重复加载
  • 缓存已加载的文件

那么问题来了,每次我都需要使用一个长长的use 路径,这些路径你都能记住吗?

  • lv\request\HTTP
  • lv\file\Path
  • lv\data\Queue

现在可以直接引用一个包,简化了类路径容易记住,像这样

// 直接获取HTTP对象
lv('http')->create('http://levi.yii.so');

// 或者是先引一个包,然后再声明不同的HTTP对象
$http = lv('http');
$http->create('http://levi.yii.so')->get();
$http->create('http://levi.yii.so')->post(array('name' => 'levi'));

这个方法参考了node中的require:

var utils = require('./utils');

之所以没有使用require命名是因为:

  1. 这个名称是PHP保留函数
  2. 期间有考虑过import等诸如此类的名称,不过都没用,因为太多类库有类似名称了,会造成名称重复而引用报错
  3. 使用类库名称作为函数名更能体现类库特点

目前包含类库中的类,如下:

  • event:lv\event\Event
  • event_query:lv\event\EventQuery
  • http:lv\request\HTTP
  • http_proxy:lv\request\HTTP_Proxy
  • path:lv\file\Path
  • queue:lv\data\Queue
  • route:lv\route\Route

后续会根据更新情况继续添加其他包

进阶加载方法

继续阅读

发表在 PHP | 标签为 , , , | 6条评论

一行JS搞定时间增删改、倒计时,来自类库:lv-js

之前发布过一个PHP类库:lv、现在发布一个js的类库:lv-js。类库中第一个类为时间操作类:DateQuery;之前有写过很多时间操作的方法(篇尾提供),经过加工、修改提供。类库的风格和php类库一样,从简、方便使用。

类库git仓库

https://coding.net/u/levi/p/levi-js/git

最近更新日期:2014.11.08,最新稳定版为:0.1.3,点击查看更新说明 >

在说这个类库前,大家先自己想想这么几个问题:

  1. 如何获取当前时间、指定时间
  2. 如何添加时间
  3. 如何计算时间间隔
  4. 如何获取指定时间格式:时间戳、UTC、GMT、年月日

我先提供一个简单的倒计时,如果用原生的JS计算倒计时是一件很复杂的事情,而使用这个类库,那么你可以将其简化如下:

setInterval(function() {
    lv.date().set('2015-11-12 11:00:20', true).get('g', true);
}, 100);

当然,这只是举例,如果需要输出到Dom中,实际还需要添加一些其他方法,下面是一个简单的演示 继续阅读

发表在 Javascript | 标签为 , , , , | 6条评论

CentOS 配置安装node + SpookyJS + CasperJS + PhantomJS

之前写过一篇Mac篇,在开发环境中安装NSCP(node + SpookyJS + CasperJS + PhantomJS)。今天我在正式生产环境安装,脱离了brew,通过编译安装。

你可以点击下面的链接回顾之前的文章:

自动化测试工具小记:node + SpookyJS + CasperJS + PhantomJS

http://levi.yii.so/archives/3648

安装node

1.准备工作

wget http://nodejs.org/dist/v0.10.32/node-v0.10.32.tar.gz
yum install gcc openssl-devel gcc-c++ compat-gcc-34 compat-gcc-34-c++

2.开始安装node.js

tar -zvxf node-v0.10.32.tar.gz
cd node-v0.10.32
./configure --prefix=/usr/local/app/node
make
make install
ln -s /usr/local/app/node/bin/* /usr/bin/

漫长的等待,到此node就安装完了。感觉和PHP差不多,稍微简单点,不用配置那么多参数,依赖的开源程序也少很多,可以后期通过npm安装,很方便。而PHP就需要一遍又一遍编译了,这点node相对方便很多。

3.测试是否安装成功

var http = require('http');
http.createServer(function(req, res) {
    res.writeHead(200,{'Content-Type': 'text/plain'});
    res.end('Hello Worldn');
}).listen(8001, '0.0.0.0');

console.log('Server runing at http://0.0.0.0:8001/');

注意哦,这里绑定的IP是0.0.0.0,而不是,127.0.0.1;目的是为了能够外网访问。当然也可以安装webserver进行端口映射,不过目前我没有打算安装webserver,只是作为内部调试的工具,无需webserver,所以这里就不额外说明了。

– 建议使用3000以后的端口,来自前端群:116589978 @Monologue

执行node

node example.js

小提示:安装node后,自带的npm的版本是1.4.2,可自行升级至2.1.4

npm -g update

PhantomJS

按照官方提示,执行以下代码即可 继续阅读

发表在 Javascript, Linux/Shell | 标签为 , , , | 6条评论