教你如何免费启用腾讯云服务器多个外网IP地址

无论是阿里云还是腾讯云的服务器,通常购买的云服务器只给我们提供1个外网IP地址。像腾讯云服务器,在条件充许的条件下,是可以更换IP的,没有太大问题。

我们做网站,有一台相对还可以的服务器,有的时候确实想在上面多放几个网站,我们需要每个网站的IP地址不一样。

除去购买多IP的VPS或站群服务器以外(费用很贵,多IP要收费,每一个IP每个月在15元左右),有没有免费且经济的实现方案呢?

这几天,我使用腾讯云服务器的过程中,看到《弹性网卡》的相关文档:https://cloud.tencent.com/document/product/576/18525

通过多网卡,可以实现一台云服务器的多IP策略,最主要核心的点是,这个多IP还是不收费(免费)供我们去使用。

有这么好的事情,我也就查看了相关资料,就开始整起来了。需要实现一台腾讯云服务器多IP,首要任务是先了解,咱们购买的服务器是否支持多网卡。

通过腾讯云文档介绍,可以确定,云服务器配置越高,可免费使用的IP数量会越多,

具体参考如下(有图片):https://cloud.tencent.com/document/product/576/18527

那接下来,我就以我自己的服务器为例子,一步一步教大家如何操作。

我本人的腾讯云服务器配置如下图,生产环境的系统为CentOS Linux release 7.2.1511:

2核8G的服务器,按上面图表,我这台机器最多只能有2个弹性网卡,一个弹性网卡上面,最多只能绑定10个IP地址,这个数据咱后面在创建网卡和生成IP的时候,就能知道。
话不多讲,简单“流水线”教程开始啦,

第一步:先启用主网卡剩余的内网IP【 云服务器 > 单击左侧目录中的【实例】> 单击需要查看的实例 ID,即可进入详情页 > 【弹性网卡】,进入弹性网卡列表页】。

点击:【分配内网IP】 就能弹出如下界面,可以看到内网IP配额,点增加就可以直接让系统自动分配 内网IP地址:

点【确定】增加后,就能在主网卡下面,出现在最新内网IP地址:

第二步:申请完这个内网IP后,接下来需要创建一个EIP(外网IP)进行绑定操作。
按上图片,点击【绑定】:

出现【新建】和【刷新】,这时候我们点【新建】操作,进入到【弹性公网IP】界面,

这一步后,点击蓝色按钮【申请】,就会出现提示,开始申请EIP

注意,如果你申请了EIP,请记住,一定要和网卡的内网IP绑定,要不然空置EIP是要收费。

申请EIP后,回到【绑定弹性公网IP】界面点【刷新】这个时候,就会出现在我们刚申请的EIP啦。

这个时候,我们只要点击【确定】进行内网IP与外网EIP就算绑定啦。

按照如上操作,可以把主网卡上所有IP配额使用完,这时候就有10个外网IP地址可用,


第三步:新增加绑定弹性(辅助)网卡并绑定云服务器。

能过前面两步,我们已针对腾讯云服务器的主网卡,绑定了10个外网IP地址,我们这台机器支持二块网卡,这个时候,我们还可以在后台再增加一块辅助网卡,再增加10个IP地址。

操作如下,【 云服务器 > 单击左侧目录中的【实例】> 单击需要查看的实例 ID,即可进入详情页 > 【弹性网卡】,进入弹性网卡列表页】

在弹出窗口选择【新建弹性网卡并绑定】,填入网卡名称后点【确定】,就新在此云服务器上增加了一个新的辅助网卡啦。

创建成功后,就是类似这个界面,

这样,我们针对新的辅助网卡,再按照上面第一,二步操作,新建10个外网IP。这台腾讯云服务器,就有了20个外网IP地址供我们使用。


第四步:调整腾讯云服务器配置,让外网IP地址生效。
1.修改主网卡配置文件

[root@VM_16_13_centos network-scripts]# cd /etc/sysconfig/network-scripts/
### 备份主网卡配置文件,万一出错(SSH就会导致连接不上服务器),可在腾讯云用VNC登陆后台恢复
[root@VM_16_13_centos network-scripts]# cp /etc/sysconfig/network-scripts/ifcfg-eth0{,.bak}
### 修改网卡配置
[root@VM_16_13_centos network-scripts]# vim /etc/sysconfig/network-scripts/ifcfg-eth0


# Created by cloud-init on instance boot automatically, do not edit.
#
# 此处修改为static
BOOTPROTO=static
DEVICE=eth0
HWADDR=52:54:00:78:cd:c7
NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
PERSISTENT_DHCLIENT=yes
#
# 添加如下几行
#
# 配置主ip
IPADDR0=172.19.16.13
NETMASK0=255.255.240.0
# 配置辅助ip1
IPADDR1=172.19.16.15
NETMASK1=255.255.240.0
# 配置辅助ip2
IPADDR2=172.19.16.16
NETMASK2=255.255.240.0
# 配置辅助ip3
IPADDR3=172.19.16.17
NETMASK3=255.255.240.0
IPADDR4=172.19.16.12
NETMASK4=255.255.240.0
IPADDR5=172.19.16.11
NETMASK5=255.255.240.0
IPADDR6=172.19.16.10
NETMASK6=255.255.240.0
IPADDR7=172.19.16.5
NETMASK7=255.255.240.0
IPADDR8=172.19.16.8
NETMASK8=255.255.240.0
IPADDR9=172.19.16.9
NETMASK9=255.255.240.0
GATEWAY=172.19.16.1


2.修改辅助网卡配置文件

[root@VM_16_13_centos network-scripts]# cp ifcfg-eth0 ifcfg-eth1
[root@VM_16_13_centos network-scripts]# vi ifcfg-eth1


# Created by cloud-init on instance boot automatically, do not edit.
#
BOOTPROTO=static
DEVICE=eth1
# 注释此行
#HWADDR=52:54:00:78:cd:c7
NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
PERSISTENT_DHCLIENT=yes
IPADDR0=172.19.16.6
NETMASK0=255.255.240.0
IPADDR1=172.19.16.14
NETMASK1=255.255.240.0
IPADDR2=172.19.16.18
NETMASK2=255.255.240.0
IPADDR3=172.19.16.2
NETMASK3=255.255.240.0
IPADDR4=172.19.16.25
NETMASK4=255.255.240.0
IPADDR5=172.19.16.3
NETMASK5=255.255.240.0
IPADDR6=172.19.16.31
NETMASK6=255.255.240.0
IPADDR7=172.19.16.4
NETMASK7=255.255.240.0
IPADDR8=172.19.16.45
NETMASK8=255.255.240.0
IPADDR9=172.19.16.7
NETMASK9=255.255.240.0
GATEWAY=172.19.16.1

3.调整/etc/sysctl.conf 内核参数

[root@VM_16_13_centos network-scripts]# vim /etc/sysctl.conf
文件最后增加,这四个参数配置:


net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.eth0.rp_filter = 0
net.ipv4.conf.eth1.rp_filter = 0


### 使其内核参数生效 ###
[root@VM_16_13_centos network-scripts]# sysctl -p


### 重启网卡 ###
[root@VM_16_13_centos network-scripts]# systemctl restart network.service
或指定某个(eth0)网卡重新并生效:ifdown eth0 && ifup eth0

在调整配置文件的时候,有几个点要注意:

a.内网IP地址(就是我们按第一二步新增的内网IP地址)要填写对

b.子网掩码对应值一定要填对(我这里网关是:255.255.240.0),参考腾讯云文档:https://cloud.tencent.com/document/product/576/18535#.E9.99.84.E5.BD.95

c. 所有配置重启后,可ping外网地址,如果不通,请看云服务器安全组有没有禁ping。


如果配置顺利的话,通过任意机器去ping这个外网EIP,能通就说明配置成啦。

至于Windows的配置,文章后面有别的朋友写的文章,大家可以参考一下。


到此,我们腾讯云服务器已有20个IP地址可用,还是免费的IP地址,你说是不是很香?


本文章相关参考文档有:

https://cloud.tencent.com/document/product/576/18535

https://cloud.tencent.com/developer/article/1360462

https://cloud.tencent.com/developer/article/1360461

优化并解决飞飞影视系统搜索卡顿问题

一朋友用飞飞影视系统,搭建了一个电影网站,总体流量不错,日流量有20万IP。

但是他反馈有一个问题,换了百独服务器,到晚上的时候,还是很卡很卡。

了解了一下,当前系统影片数量才6万不到,每到晚上9点左右就出现卡顿。让我帮看看是什么原因。

登陆到服务器,简单直接的top命令, 就能看到mysql数据库进程占用CPU资源300%多,

不用多想,登陆数据库直接查看是哪些SQL查询导致的问题,使用:show full processlist\G;

可以看到,都是Like 搜索电影的查询语句。类似这样的情况,是大部分系统都会遇到的,想要优化好,除去主从,查询数据加缓存等办法外,最直接的方式是去掉Like搜索,才是一劳永逸的办法。

优化全文章搜索,借助第三方工具相对比较理想,可以是Elasticsearch或Sphinx。这边直接用了Sphinx全文搜索(中文搜索coreseek已停),把软件安装好【这里百度如何安装coreseek,就不详情说明】,索引生成完后,就再调整搜索接口程序。

需要调整的程序主要有二个:

第一:Lib/Common/common.php 文件内的ff_mysql_vod函数,直接在这里做搜索处理

//当前只针对关键词搜索进行优化,其实还有几个接口需要处理

if($tag[‘wd’]){

$keyword = $tag[‘wd’];
$sphinx = new SphinxClient();
$sphinx->SetServer(‘localhost’,’9313′);
$sphinx->SetConnectTimeout(10);
$sphinx->SetLimits(0,100);

//排序方式,有改进空间,当前只是按点击量排
$sphinx->SetSortMode(SPH_SORT_ATTR_DESC, “vod_hits”);
$sphinx->SetMatchMode(SPH_MATCH_PHRASE); //全词查找
$search_result = $sphinx->query($keyword);
$total_found = (int)$search_result[‘total_found’];
$idArr = array();
if($total_found){
if(is_array($search_result[“matches”])) {
foreach ( $search_result[“matches”] as $doc => $docinfo ) {
$idArr[] = $doc;
}
}
}
$idString = implode(‘,’,$idArr);
$where[‘id_string’] = $idString;
$where[‘is_sphinx’] = 1;
$where[‘total_found’] = $total_found;
}

第二步: 把检索到的影片ID列表,传给/Lib/Lib/Model/VodViewModel.class.php 的函数 ff_select_page

//如果是全文检索,就直接调用查询到的ID

if($where[‘is_sphinx’]){
$page[‘records’] = $where[‘total_found’];
$id_string = $where[‘id_string’];
unset($where[‘total_found’]);
unset($where[‘id_string’]);
unset($where[‘is_sphinx’]);
$where[‘vod_id’] = array(‘IN’,$id_string);
}else{
$page[‘records’] = $this->ff_select_count($where);
}

通过上面二步调整,基本上就对飞飞影视系统的影片搜索优化完成啦。

当然这里还有改进的空间就是不一定要在 Lib/Common/common.php 文件内搜索,可以直接改成在 VodViewModel.class.php 文件中,只改一个地方。

但我为了更方便调整(上面已说过还有其他搜索接口可能还会需要调整)就在common.php里进行改进啦。

最后出来的效果就是这样子(因为是全文搜索,影片标题可能没有关键词,但电影介绍内有这关键词也会出来):

Jira的安装过程中可能会遇到的一些小坑

项目与事务跟踪工具有很多,有收费,有开源系统。但要找一个适合团队使用的系统,并不容易。

团队内部从之前的禅道到现在用的轻量级别在线管理工具Tower,

发现各有各的优点与短板,不同的人看法不一样。

在这过程中,一位同事建议用一下Jira 这款项目与事务跟踪工具,

JIRA是Atlassian公司出品的项目与事务跟踪工具,被广泛应用于缺陷跟踪、客户服务、需求收集、流程审批、任务跟踪、项目跟踪和敏捷管理等工作领域。
JIRA中配置灵活、功能全面、部署简单、扩展丰富,其超过150项特性得到了全球115个国家超过19,000家客户的认可。

为了完成体验一下这款工具,昨天参考这篇非常详细文章《烂泥:jira7.2安装、中文及破解》用时不到2小时完成安装。

具体的安装流程,我就不再描述,因为上面文章写的是很良心的一篇安装,汉化,破解的教程。

主要说一下在这安装过程中,可能因为每个人不同环境,在操作的过程中,会产生的各别不一样的差异(坑)。

第一:CentOS 7以上8080端口开放问题

当我们安装完成后Jira后,8080端口在我的服务器CentOS Linux release 7.2.1511 (Core) 并没有开放,导致输入:
http://xxx.xx.xxx.xxx:8080 你会发现并不能顺利地访问到Jira配置界面,可开放此端口来解决这问题。
解决办法:/sbin/iptables -I INPUT -p tcp –dport 8080 -j ACCEPT

 

第二:MySQL 版本与MySQL配置问题

上面教程并没的提及他自己的MySQL版本是多少,提供的Java连接MySQL数据库 mysql-connector-java 有可能因为我们本身安装的版本不一样,出现问题。

比如在配置Jira连接数据库的时候,因mysql-connector-java问题,会出现如下提示:

Error Connecting  to database    Unknown system variable ‘storage_engine’

 

出现上面这问题,主要无非是二种可能:

1: 数据库部分配置参数问题,可参考Jira连接数据文档说明。

解决方法:配置调整与解决办法可参考:Connecting JIRA applications to MySQL

 

2:Mysql 数据库版本5.7与上面教程给的mysql-connector-java不兼容,导致Jira无法识别MySQL的引擎。

解决方法:可以先参考这篇文章:http://www.cfanz.cn/index.php?c=article&a=read&id=316535,然后再去:https://github.com/yurii-github/mysql-connector-j 下载驱动:

这样就可以解决MySQl 5.7 驱动包可用的问题了,

在OOPHP博客也可下载:mysql-connector-java-5.1.39-SNAPSHOT-bin.jar

 

第三:关于Jira启动与关闭

如里参考上面文章进行安装的Jira,安装的目录应该是在系统目录:/opt/atlassian/jira/ 下,在些目录下:/opt/atlassian/jira/bin/*.sh有守护,启动,关闭,重启等脚本。

其实,解决上面几个问题,到这里已基本完成Jira的安装,配置,汉化,破解等工作。

最后上一张已安装完成后,体验图:

 

Phalcon 初体验的安装问题

人是有惰性的,工作时间太久了,就容易忽视技术成长与关注。

这几年,记忆中最早(2010年)团队管理后台项目,用得最多的开发框架是Zend Framework 1.6版本。

前台业务逻辑根据不同的需求,做了不一样的选择。

比如说团队刚开始,就我一个技术的时候,最早为了网站最快上线,就直接用DEDECMS改进业务逻辑,

后面再根据运营需求,找时间去优化CMS逻辑,

当然,在业务改进的过程中,就有内部自己写的一些小型MVC,

后面人员越来越多后,技术团队根据业务要求,陆续有用到ThinkPHP,CodeIgniter,Yii等框架。

其实在这过程中,一个技术团队按不同的业务,更换不一样的开发框架,

有优点,也有的缺点(这个很要命):

优点:

1. 比较能锻炼团队成员学习成长的能力,可以让成员更加全面。

2. 技术上有尝试,团队整体保持对行业的关注度,后期对公司新业务的开展有技术的保障。

缺点:

1. 学习需要时间,时间就是创业团队最重要的成本。

2. 团队人员流失后,项目后期维护成本非常之高,新人进来要学习时间。

无认优缺点,团队在发展过程中,各种问题都会有,这其实就是人或团队成长的过程。

我们的初心,还是希望业务能稳定,效率高,易维护,同时团队成员也可以有更好的成长空间。

这不,咱还是要折腾一下,Phalcon 虽然是2012就出来一个C 扩展编写的框架,听说是高效率。上周就抽时间给尝试了一下。

关于Phalcon介绍,简单百度百科:

Phalcon 是开源、全功能栈、使用 C 扩展编写、针对高性能优化的 PHP 5 框架。 开发者不需要学习和使用 C 语言的功能, 因为所有的功能都以 PHP 类的方式暴露出来,可以直接使用。 Phalcon 也是松耦合的,可以根据项目的需要任意使用其他对象。

 

Phalcon是一套实现MVC架构的高性能PHP应用程序框架。初始版本发布于2012年11月,开放源代码并基于BSD授权条款。与其他大部分的PHP框架不同,Phalcon是以扩展的方式以C语言所编写,因此Phalcon的执行速度高过其他PHP框架,并且消耗更少的资源,根据官方的测试,Phalcon是目前世界上速度最快的PHP框架, 没有之一

文档很完善,安装过程遇到一些小问题,就顺便记录了一下。

主要安装可参考文档: 安装Phalcon点这里

遇到的几个小问题:

第一:php-config is not installed

解决办法,写上php-config的路径就可。

./install –phpize /usr/local/php/bin/phpize –php-config /usr/local/php/bin/php-config

参考:https://segmentfault.com/q/1010000007067920?_ea=1258087

第二:phalcon configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers

解决办法:安装一下re2c。

参考:https://blog.slogra.com/post-421.html

 

最后可以通过phpinfo看到Phalcon框架已安装成功

然后再去Github 下一些实例(https://github.com/phalcon/mvc),就可以开始体验

看到上面例子,说明已是安装成功,接下来就是真正使用了。

计划在后面用这框架做个小的项目,逐步记录在博客上。

博客启用HTTPS,如何申请免费腾讯云SSL证书?

一回过头来,工作忙得团团转,博客又是一年多没更新~~

看着域名都快到期,转念一想,这博客还是得继续更新一些文章才行啊。

重新安装了一下博客皮肤,顺便申请了一个免费的腾讯云SSL证书,就顺便给配置了一下,让这博客也启用一下https。

至于申请流程,简单写下流程,新人可能帮助会有一些,老手的话,就可以略过了。

第一步:注册腾讯云账号,有QQ的话,就直接登陆,做个实名认证。

第二步:就是进到SSL证书管理后,申请证书。

 

第三步:填写你要申请证书的域名,再设置一个私钥密码。

 

第四步:选择验证域名属主方式,这里我直接是通过DNS验证,文件验证感觉会更方便。

 

第五步:域名确认验证通过后,腾讯云会自动通知CA机构方可颁发证书,理论值等待1-3分钟证书就下发完成。

 

第六步:下载域名证书,参考这里的配置文档,就可以去Nginx(可能是其他服务器)增加配置啦。

 

第七步:参考配置文档,完成https增加工作。

最后,为什么要加Https ?有什么好处?请参考这里:网站启用Https协议有哪些好处?

[转]Magento产品属性设置与数据库设计分析

原创文章 永久链接:http://blog.ifeeline.com/577.html
产品的默认属性(字段),Catalog->Attributes->Manage Attributes 或 Manage Attribute Sets都是针对产品实体的。虽然使用EAV模型的实体不仅仅是产品实体,但是只有产品实体提供了添加自定义属性的功能。

下面这个就是一个产品必须具备的属性:
Magento产品属性组

接下来这个ER图涉及三十多个表:
Magento目录产品ER图

Magento实现的目录产品模型到达了一定复杂度(主要是EAV模型引入)。Magento中的EAV模型,必定有一个eav_entity_type和至少一个eav_attribute_set(它也是eav_entity_type相关的)。事实上,只有产品实体的类型设置了多个属性集(创建一个产品时首先要求选择属性集),其它的EAV实体类型也可以设置多个属性集,但是Magento没有实现(也没有必要),所以,除了产品实体类型,其它的实体类型都仅对应了一个属性集。

看看目录实体属性集合和分组情况:
SELECT et.entity_type_id, et.entity_type_code, es.attribute_set_id, es.attribute_set_name, eg.attribute_group_id, eg.attribute_group_name
FROM eav_entity_type et, eav_attribute_set es, eav_attribute_group eg
WHERE es.entity_type_id = et.entity_type_id
AND es.attribute_set_id = eg.attribute_set_id
ORDER BY et.entity_type_id, es.attribute_set_id, eg.attribute_group_id

Magento属性集合分组情况

Magento中的实体类型,除了产品类型,其它的都只有一个属性集,并且除了目录都只有一个属性组。目录只有一个属性集,这个属性集分了多个组。产品有多个属性集,每个属性集有多个属性组。

目录这三个分组,在创建目录时可以看到:
Magento目录分组

问题:使用Magento提供的方法建立一个EAV模型,它实际会为这个模型建立一个实体类型,然后还会建立一个属性集,在这个属性集中有一个属性组,这个组中是否包含所有已定义的属性呢(自定义属性都会插入eav_attribute中)?

这个问题的答案是:只有定义的属性是系统属性时,才会插入默认的属性组中。在eav_attribute表中有一个字段is_user_defined用来标识是系统属性还是用户自定义属性。

Magento的内置的EAV模型默认的属性都是系统属性。Magento只为产品类型添加自定义属性提供了实现,这些自定义的属性都不是系统属性(可以通过其它方法让它变成系统属性,一般不这样弄),而且添加的自定义属性只是往eav_attribute表中插入了记录,并没有分配到属性组,所以要进入如下界面把自定义属性添加到分组(也可以建立自定义分组):
Magento分配属性到属性组

最右边的是没有分配到当前属性集的属性(注意是当前属性集,属性可以关联到多个不同的集)

还需要注意,不管设置了多少个属性集,系统属性一定都在这个这个属性集的分类中,意思是说,你可以把具备某些特征的产品添加自定义属性(系统属性都会包含),从水平表角度来看,每种属性集的产品,字段(属性)不一样,有些多些字段,有些少些字段,但是基本的字段都必须具备(系统属性),正是如此,产品的EAV模型是一个极致的,几乎完美的实现。

EAV模型的查询已经到达了关系数据库中SQL复杂度的极限。大部分的查询都非常复杂,甚至很难理解。

从关系图中可知,属性分别存放到了以属性类型命名的表中,比如varchar、text等,实际上除了常见的类型,比如MySQL中还提供了枚举和SET类型,由于EAV模型的引入,使得类型丢失,所以为了模拟这两种类型,这里引入了eav_attribute_option。

当添加一个属性时:
Magento添加属性


设置的值都存入eav_attribute和catalog_eav_attribute,注意,这里添加是Products Attribute(不是别的)。

catalog_eav_attribute表结构:


Magento catalog_eav_attribute 表结构

除了以上红色圈出来部分没有提供设置外,其它都设置了。注意is_visible默认是1,is_configurable默认也是1。is_wysiwyg_enabled是针对输入区的类型是否启用编辑器(也没有提供给用户)。[更正:当is_global为1和frontend_input为下拉框时,is_configurable选项就会显示,它专门用来表明是否可以用于可以配置商品]

eav_attribute表结构:


Magento eav_attribute 表结构

这里也有很多字段没有提供给用户设置,有些也是没有必要提供的。比如entity_type_id,记录了属性的实体类型,backend_type虽然没有提供给用户设置,但是在设置frontend_input时会根据选择的值自动设置,它决定了属性的值存储在那个类型表中。

Catalog Input Type for Store Owner表示输入类型,比如下拉块还是单选等,是一个属性输入的方式。如果这里选择的是下拉或多选,那么Manage Label / Options就会多出一个让你填入选项的按钮:
Magento属性选项

这些信息就保存到eav_attribute_option 和 eav_attribute_option_value中。它们分别模拟了枚举类型 和 SET类型。eav_attribute_option_value跟商店相关,每个选项会由于不同语言保存了不同的值。如果属性是下拉或多选,就应该分配值,否则它根本没有意义。

另外,每个属性还有一个Label,它是内部使用的,和商店相关,这些信息写入到eav_attribute_label中,至少要输入一个作为管理使用的标识,其它的不设置也没有问题。

还有如下表没有涉及,查看了下,它们内容是空的,对比了下,估计是自建EAV模型的模板。
Magento EAV模型 模板

EAV是Magento数据库设计的基础,在很多的PHP应用甚至其它语言的应用中,应用EAV模型的非常罕见。这个也是Magento高度可扩展的基础,同时也是它确立王者地位因素之一。同时,EAV模型对资源消耗非常大,这个也是它缓慢的重要原因之一,虽然开启缓存可以有效提升系统性能,但是复杂的消耗资源的联合查询依然非常多发。另外,EAV设计模型的复杂性导致深入的二次开发对开发者要求非常高,难度也非常大。绝大部分所谓的二次开发者,都是只是对模板修修改改而已。Magento使用了很多“新技术”,很多实现构架在Zend Framework之上(注意:magento没有使用Zend Frmaework的MVC实现),代码优良,值得深入研究欣赏。

如何在Linux上配置自动打包并签名APK的环境

我们在开发Android APP的过程中,总会有一步,就是在完成开发后,会涉及到APP的打包与签名。一般情况下,打单个包的时候,时间上不会要很久。开发人员在开发环境下,就能直接打包并对包进行签名。
然后,当我们的APP需要做推广与合作时,我们就要分不同的渠道给到推广或合作方。这种情况下,会就遇到,经常需要打不同渠道号的包。这在10个包之内,开发人员手动打还可以接受。一旦出现100个渠道以上,开发人员就直接崩溃了。这手动打起一,保守估计要一天以上。渠道还不能出错。
要解决这个办法,就是批量打包了。 在Windows环境下打包,网上已经有很多了。像是还有批量打包的工具。这里就不再进行讨论。
现在我们直接说怎么在CentOS下配置这个批量打包并签名的环境,来进行批量打包。
在开始之前,最好有一些关于下面几个名词的了解,会更有助于我们理解这篇文章。什么是SDK, aapt, PATH。
目前,实行的思路如下:
a.先把线上主渠道号的包进行反编译。
b.修改APK的AndroidManifest.xml配置文件的渠道号(我们是放在配置文件内,不知道其他公司是否一样)
c.然后进行APK的打包并实现签名,新的渠道包就算完成。
现在先进行环境的安装:
1.安装aapt和apktool命令以及apktool.jar。
安装步骤直接参考:http://code.google.com/p/android-apktool/
在Linux环境下的安装步骤如下:
  1. Download apktool-install-linux-* file
  2. Download apktool-* file
  3. Unpack both to /usr/local/bin directory (you must have root permissions)
在这一步一定要注意【aapt command in a PATH】,就是说aapt命令要加入环境变量(PATH)。具体如何把aapt命令,加入环境变量(PATH)里。
#vi /etc/profile
编辑此文件在最后加上:
export PATH=$PATH:/usr/local/aapt:/usr/local/apktool
让刚加上的变量,立刻生效,直接执行:
#source /etc/profile
查看是否已生效,直接:
# echo $PATH
应该能看到如下图片:
2.安装 JRE 1.6 (Java Runtime Environment) JDK 的环境。
关于如何安装JDK以及Apktool的使用方法,请参考本博客另一篇文章,都有提到。在这里我就不再重复写了。
按上面二步操作完成以后,就可以进行反编译,修改AndroidManifest.xml配置的渠道,最后再打包签名了。
在进行打包的过程可能会遇到几个问题,以及对应的解决方法:
a.出错~~
I: Smaling...
I: Building resources...
aapt: /lib/libz.so.1: no version information available (required by aapt)
I: Copying libs...
I: Building apk file...
aapt: /lib/libz.so.1: no version information available (required by aapt)
这个在打包与签名的时候会提示,说明libz的版本与aapt不兼容。需要进行libz的版本升级。
这里要注意的重点是,如果我们的机器是64位的,因为Android都是基于32开发的,它依赖的是32位的libz。所以在升级的时候,需要特殊的操作。如下:
wget http://124.202.164.4/download/36593658/49562183/3/gz/12/28/1359618838796_796/zlib-1.2.7.tar.gz
tar zxvf zlib-1.2.7.tar.gz
cd zlib-1.2.7
export CFLAGS=-m32  【注意这里,这才是重点】
./configure --prefix=/usr/local/zlib-1.2.7-32
make && make install
ll /lib/libz.so.1
mv /lib/libz.so.1 /lib/libz.so.1_backup
ln -s /usr/local/zlib-1.2.7-32/lib/libz.so.1 /lib/libz.so.1
如果出现此问题,说明你java环境没有安装好,请仔细查看:
/usr/local/bin/apktool: line 78: exec: java: not found
反编译命令:
/usr/local/bin/apktool  d -f /mnt/html/shell/package/mumayi/mumayi.apk /mnt/html/shell/package/mumayi/cache/mumayipackage
打包命令:
/usr/local/bin/apktool b -f /mnt/html/shell/package/mumayi/cache/mumayipackage /mnt/html/shell/package/mumayi/apk/mumayipackage_mumayi.apk
 参考文章与资料:

2013年7月编程语言排行榜:PHP依然强势

2013年7月9日,Tiobe公司发布新一期编程语言排行榜。从下面的编程语言排行中,我们不难看出PHP这次的上升速度是最为迅速,跟2013 年1月份相比,PHP同比增长了+1.64%,其次就是数据库语言的Transact-SQL(+0.99%)和PL / SQL(+0.34%)。 Tiobe公司认为,PHP上升的背后主要是来自于2012年9月发布最新的PHP Zend Framework。

Zend Framework (ZF) 是用PHP 5来开发web 程序和服务的开源框架。ZF 用100% 面向对象编码实现。 ZF的组件结构独一无二,每个组件几乎不依靠其他组件。这样的松耦合结构可以让开发者独立使用组件。 我们常称此为“use-at-will”设计。

以下是前20名榜单排行榜:

Zend Framework 项目的主要赞助者是 Zend Technologies,但许多其它公司也贡献了组件或重大功能。例如 Google、 Microsoft 和StrikeIron作为伙伴提供了web服务接口和其它希望给 Zend Framework 开发者使用的技术。

没有活跃的ZF社区,Zend Framework 就不能交付和支持所有这些功能。社区成员包括贡献者都可以在这些地方找到:mailing lists, IRC channels 和其它论坛。无论你有什么关于ZF的问题,在社区总能找到答案。

Zend Framework (ZF) 是用 PHP 5 来开发 web 程序和服务的开源框架。ZF用100% 面向对象编码实现。 ZF的组件结构独一无二,每个组件几乎不依靠其他组件。这样的松耦合结构可以让开发者独立使用组件。 我们常称此为use-at-will设计。

虽然它们可以独立使用,但如果组合使用,Zend Framework 标准库理的组件也能形成一个强大而可扩展的web程序。 ZF 提供了强壮而高效的 MVC 实现,易于使用的数据库摘要和实现 HTML 表单解析、校验和过滤的表单组件,这样 开发者可以通过这些易用的、面向对象的接口联合所有这些操作。其它组件如 Zend_Auth 和 Zend_Acl 通过通用 的证书(credential)存储提供用户认证和授权。还有其它实现的客户库来简化访问最流行的可用的 web 服务。 不论你的程序需要什么,你都可能从 Zend Framework 中找到全面测试的组件来极大地减少开发时间。

Nginx服务器下最新版的Ecshop(2.7.3)的伪静态(Rewrite)规则

今天下午花时间整了一个购物网站,尝试了一下Ecshop的功能 。发现基本的网店功能足够使用。后台操作的程序反应效率也比较快(可能是因为现在没大量数据的原因)。

不过发现网站的URL没有重写,在后台看了一下系统配置,在Nginx要想一键设置还不是那么方便。如下系统后台的设置图片:
找了一下相关资料。参考了一下前二年,之前一些朋友改写的Nginx Rewrite规则【链接】。就对比现在版本(2.7.3)新加的几条。就得到了下面的Nginx规则。把这规则加到Nginx网站配置文件中,可以使用。具体有没有少规则,还需要测试。
规则如下:
location / {
if (!-e $request_filename) {# direct one-word access
rewrite “^/index\.html” /index.php last;
rewrite “^/category$” /index.php last;# access any object by its numeric identifier
rewrite “^/feed-c([0-9]+)\.xml$” /feed.php?cat=$1 last;
rewrite “^/feed-b([0-9]+)\.xml$” /feed.php?brand=$1 last;
rewrite “^/feed-type([^-]+)\.xml$” /feed.php?type=$1 last;
rewrite “^/feed\.xml$” /feed.php last;#category
rewrite “^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5&page=$6&sort=$7&order=$8 last;
rewrite “^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)(.*)\.html$” /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5 last;
rewrite “^/category-([0-9]+)-b([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /category.php?id=$1&brand=$2&page=$3&sort=$4&order=$5 last;
rewrite “^/category-([0-9]+)-b([0-9]+)-([0-9]+)(.*)\.html$” /category.php?id=$1&brand=$2&page=$3 last;
rewrite “^/category-([0-9]+)-b([0-9]+)(.*)\.html$” /category.php?id=$1&brand=$2 last;
rewrite “^/category-([0-9]+)(.*)\.html$” /category.php?id=$1 last;#goods
rewrite “^/goods-([0-9]+)(.*)\.html” /goods.php?id=$1 last;

#article
rewrite “^/article_cat-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /article_cat.php?id=$1&page=$2&sort=$3&order=$4 last;
rewrite “^/article_cat-([0-9]+)-([0-9]+)-(.+)(.*)\.html$” /article_cat.php?id=$1&page=$2&keywords=$3 last;
rewrite “^/article_cat-([0-9]+)-([0-9]+)(.*)\.html$” /article_cat.php?id=$1&page=$2 last;
rewrite “^/article_cat-([0-9]+)(.*)\.html$” /article_cat.php?id=$1 last;
rewrite “^/article-([0-9]+)(.*)\.html$” /article.php?id=$1 last;

#brand
rewrite “^/brand-([0-9]+)-c([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)\.html” /brand.php?id=$1&cat=$2&page=$3&sort=$4&order=$5 last;
rewrite “^/brand-([0-9]+)-c([0-9]+)-([0-9]+)(.*)\.html” /brand.php?id=$1&cat=$2&page=$3 last;
rewrite “^/brand-([0-9]+)-c([0-9]+)(.*)\.html” /brand.php?id=$1&cat=$2 last;
rewrite “^/brand-([0-9]+)(.*)\.html” /brand.php?id=$1 last;

#tag
rewrite “^/tag-(.*)\.html” /search.php?keywords=$1 last;
rewrite “^/snatch-([0-9]+)\.html$” /snatch.php?id=$1 last;
rewrite “^/group_buy-([0-9]+)\.html$” /group_buy.php?act=view&id=$1 last;
rewrite “^/auction-([0-9]+)\.html$” /auction.php?act=view&id=$1 last;

#exchange
rewrite “^/exchange-id([0-9]+)(.*)\.html$” /exchange.php?id=$1&act=view last;
rewrite “^/exchange-([0-9]+)-min([0-9]+)-max([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /exchange.php?cat_id=$1&integral_min=$2&integral_max=$3&page=$4&sort=$5&order=$6 last;
rewrite “^/exchange-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /exchange.php?cat_id=$1&page=$2&sort=$3&order=$4 last;
rewrite “^/exchange-([0-9]+)-([0-9]+)(.*)\.html$” /exchange.php?cat_id=$1&page=$2 last;
rewrite “^/exchange-([0-9]+)(.*)\.html$” /exchange.php?cat_id=$1 last;

}
}

怎么解决Nginx执行PHP出现的shmget() failed: Invalid argument

最近两天发现,以前可以顺利执行的PHP采集的计划任务出现如下错误。

shmget() failed: Invalid argument
Failed to start up concurrent users module!

所有的程序都 跑不起来。经过查找原因。发现是linux系统参数设置问题,从而导致采集程序执行不了。用命令行查看:

[root@centosggk ~]# sysctl -a | grep shmm
kernel.shmmni = 4096
kernel.shmmax = 0

修改操作:

[root@centosggk ~]# vi /etc/sysctl.conf
kernel.shmmax =1523241824
kernel.shmall =573741
[root@centosggk ~]# sysctl -p
[root@centosggk ~]# sysctl -a | grep shm
kernel.shmmax = 1523241824
kernel.shmmni = 4096

修改后的结果是:

kernel.shmmax 数值说明:
单位:字节。一般建议使用物理内存的一半
以4G内存为例:4096/2*1024*1024=2147483648

kernel.shmall 数值说明:
单位:页。1页=4k,设置数值则为物理内存大小
以4G内存为例:4096*1024*1024/4000=1073742
注:以上两项数值如果填写大于本身物理内存则会不生效。

可参考的文章网址:
http://www.poluoluo.com/server/201306/215354.html
http://www.ablanxue.com/prone_8500_1.html

百度云付费系统是漏洞?还是营销策略?

       百度云盘100GB套餐 年付只要0.5元,升级为云盘会员,只需要0.1元整!听到群里发出这样的叫喊,我也忍不住去看了一下地址:http://yun.baidu.com/buy/center?tag=2
还确实真有此事。我这个人不太相信有免费的午餐。
头脑中马上就闪出一个念头,这不会是百度特意这样搞得吧?只为了做一次营销。理论上,不应该有这么大一个漏洞哇。一年500块的费用,一下变成0.5元。这可是1000倍的差距。这程序再怎么写,也不可能写成这样的BUG吧。这程序BUG要写的有多高啊,正好1000倍啊!。
不过为了体验一下,我也先没想那么多。管他是营销,还是BUG。我先买一年试试看。就这样,我花了0.5元,把百度云盘容量扩展到了225G,还又花了0.1元,买了一年的VIP会员,请说0.1元的VIP会员,哪里还能找到?只百度一家,而已!
回到百度云这个话题,这个是不是一个BUG,还真不好确定。不过在晚上22点的时候,发现已经不可以再购买了100G空间。所以我个人认为,这比较可能是一个营销造势,而不是所谓的BUG漏洞!
下面看一下微博上,热闹的都不行了:

[转]哪些PHP开源博客系统

以下列举的PHP开源Blog系统中,除了我们熟知的WordPress之外,大多都没有使用过,其中一些已经被淘汰,或者有人还在使用。除了做一个参考之外,也是想看看,PHP在个人网站应用系统中所发挥的作用和产生的影响。

1、WordPress

WordPress是最热门的开源个人信息发布系统(Blog)之一,闻名遐迩,基于PHP+MySQL构建,本博客现在就改用了WordPress博客系统。WordPress提供的功能包括:

1.文章发布、分类、归档。
2.提供文章、评论、分类等多种形式的RSS聚合。
3.提供链接的添加、归类功能。
4.支持评论的管理,垃圾信息过滤功能。
5.支持对样式CSS和PHP程序的直接编辑、修改。
6.在Blog系统外,方便的添加所需页面。
7.通过对各种参数进行设置,使你的Blog更具个性化。
8.静态html页面生成。
9.通过选择不同主题,方便地改变页面的显示效果。
10.通过添加插件,可提供多种特殊的功能。
11.支持Trackback和pingback。
12.支持针对某些其它blog软件、平台的导入功能。
13.支持多用户。
14.安装最简单。
15.Web标准支持非常好。
16.使用比较简单。
17.拥有大量的主题与插件。

2、LifeType

Lifetype同样是一个开源的Blog平台,在同一个系统中支持多个Blog和多个用户。它具有:

友好的用户界面
通过所见即所得文章编辑器,你可以编排出整齐漂亮包含图片,声音以及视频的的文章。做到 Podcasting的功能。此外通过摘要页面,你可以在每次登入管理者后台界面时就能够了解你Blog目前所有统计信息,包含最新文章,评论以及引用等等。

多媒体文档管理
通过管理者后台界面可以轻松做到自动图片缩放,上传大量文档,编写文档描述,让你可以很容易建立一个支持Podcasting的Blog。

多样化的主题
提供超过60个不同的精美模板供你选择。通过管理者界面,你可以安装,删除,编辑你当前所有的主题

丰富的插件程序
如果标准安装中没有你想要的功能,可以通过安装其提供的60多种插件来满足你的需求。其中最流行的插件有:Moblogging,Template Editor和Nested Comments。

垃圾信息过滤机制
内建采用贝叶斯判决规则的垃圾信息过滤机制,以保证你blog的评论和引用等不受垃圾信息的干扰。另外回复确认,回复验证CAPTCHAS,以及引用网址的检查都可以通过插件程序来新增。

支持引用
只要加入你所要引用的文章网址,通过引用自动查找的功能LifeType将会自动找出所有的引用网址来加以引用。

支持一个Blog多个作者
你可以给你的朋友权限来跟你一起写Blog,使你的Blog具有协同工作的功能。

安装简单
通过安装向导将会引导你轻松完成安装。并且你可以通过管理界面来控制所有设置,不需要去编辑配置文件。

移动功能
通过安装插件,你就可以在你的移动设备上Bloging。

支持多Blog与多使用者环境
利用支持多Blog与多使用者,单一的Blog后台管理以及全域的网站管理等功能,LifeType是非常适合用来架设Blog Hosting的社区网站平台。

统一的社区网站页面
简单的4个步骤就能够注册一个新的weblog,在社区网站的首页可以展示当前LifeType中最新和最热门的网记,文章或用户。

支持二级域名
让你的使用者能轻松的拥有自己的二级域名,比如:username.yourdomain.com或是blogname.yourdomain.com(你需要开启DNS中wildcards的设定,才可以使用这一功能)。

支持多国语言
其中包括中文。

高性能数据存取
利用Template Caching、Data Object Caching和全面的代码重整等技术来降低LifeType对系统资源的消耗,并且维持整个网站的稳定运作。这使得LifeType非常适合用来架设大型的社区网站。

此外LifeType是基于MVC模式架构开发具有很高的扩展性。相关的文档可以利用Doxygen自动生成。所有页面都符合XHTML1.0标准。拥有强大的插件框架。集成Smarty模板引擎。支持XMLRPC。

相比WP,其UI印象分是很差。 WordPress富有魅力的插件系统、模板结构,LifeType对此有不同意见,认为不含有php代码的模版更安全。

3、b2evolution

b2evolution同样采用PHP+MySQL开发的,成熟的,优秀的Blog引擎。它包含了一个Blog工具所应具备的所有功能。它的特点包括:
1.即时Blogging:可以直接在web页面中Blogging。还能通过发送email或MMS或使用客户端工具如w.bloggar来Blogging。
2.提供大量的漂亮的外观供你挑选。
3.防垃圾信息机制。
4.支持多种语言包括中文(简/繁体)。
5.支持多Blog系统:假如你需要放2,3或100个不同的Blog/新闻聚合在你的网站上,只需一次安装就能搞定。每一个blog放在自己的页面,也可以在同一个页面同时放置多个blogs。
6.支持多用户和多作者:每个blog都有一组属于它的用户,你可以对这些用户设置不同的读写权限。
7.灵活分类:每个blog都可以分成不同的子类,然后子类通过主题来组织管理你的posts/news item。每个post可分配给多个子类。
8.遵守Web标准:集成一个XHTML标准检查器。

4、Textpattern

Textpattern是一款简洁而又漂亮的Blog引擎,主题很素雅,留有很大的个性化空间。内置Textile写作语法,所以作者不必懂得 HTML标签语法也能轻松写作。预设主题非常简洁,但可定制程度很高。TXP采用php+mysql构建,代码体积小,效率高,网页访问速度快。目前已经 有中文语言包。适合做清新简练的风格。

5、F2blog

  • 它是一款基于PHP的、以MySQL为数据库支持的单用户blog(网络日志)程序。
  • 采用目前流行的技术 XHTML+CSS+div 布局的模板结构,多变、绚烂的模板可使您的blog与众不同,f2blog可以使用asp版本的pjblog中的skin,让您不要再为没有喜欢的skin而发愁。
  • 可自由定制的页面模块,添加代码不必修改程序,也可通过插件的方式自由的添减模块,满足各自的需求。移除与安装都非常方便,只需要把插件文件夹删除和复制就可以实现插件的移除与安装。
  • 部分功能采用基于Ajax技术,让您不需要再为等待页面装载而烦恼;以后将更多的使用此技术。
  • Tags功能,一个日志可以设定多个tags,便于你归类日志,同时在读取日志时,相关的tags日志会显示在下方,便于阅读者快速的取得相关信息。
  • 关键字功能,可以让您把重要的信息给予备注,让阅读者更能快速的知道此关键字的意思。
  • 过滤器功能,您可以设定ip,内容,网址等多种方式的过滤,让您免除广告垃圾,恶意的文字进入您的日志留言与评论中的烦恼。同时还可以限制某些ip在您的日志上留言。
  • 每次留言、评论时间的间隔的设定,可以防止恶意在短时间内输入内容。
  • 全面支持后台对日志、用户、链接等所有内容的批量化操作,省时省力;
  • 可自动检查是否有更新的程序,这样便于您及时更新程序,使用最新的功能。
  • 多语言包,内置简繁英三个语言包;
  • 以PHP5、MySQL5为主,全面向下兼容PHP4,mysql4.0。
  • 可设置隐藏分类,可撰写隐藏日志,可预览日志,自动保存日志,日志可以加密,以让特殊的人凭密码查看您的日志;
  • 使用功能强大的tiny_mce编辑器,您可以自定义编辑器的工具栏,以满足各自的需求。
  • 可以置顶日志,锁定日志,移动日志,限制评论,限制引用等批量化做业。
  • 支持Trackback,支持RSS 2.0(可追踪全部新日志、单篇日志或某个分类),Trackback采用了认证机制,防止了恶意,重复的引用。
  • 友情连接,日志类别,模块可以调整显示顺序,以满足您的需求。
  • 可自由设置列表或摘要两种查看方式;
  • 可自由开关日志、并可设置理由;
  • 时差调整功能;
  • 基于GD的验证码;
  • 日志类别可以分两层显示,这样便于您很多内容时,可以分子类来管理日志。
  • 评论与留言支持验证码功能,同时支持两层交互回复功能。
  • 完善的mysql的备份、恢复、和优化工具,在数据很大或网速很慢时,您可以设定分卷的大小,系统将分卷备份,分卷恢复。
  • 完美的图片播放,音乐播放,flash播放,图片插入,附件下载功能,这是f2blog的最为特别之处。
  • 强大的附件管理功能,可以让您删除不需要的文件,和上传独立于f2blog附件的资料,单独做为一个文件管理系统使用。特别是可以让您更改文件的备注性文字,以便于日志中播放图片时,在图片下面显示备注性文字。

6、Serendipity

Serendipity是一个采用PHP实现的weblog/blog系统。它功能丰富,符合标准,基于BSD License开源。它的特点包括:WYSIWYG与HTML编辑;内置强大的媒体数据库;多作者,可配置的权限/用户组系统;支持Threaded comment,嵌套分类;支持多种语言;丰富插件与模板库;强大的垃圾过滤功能;能够嵌到现有的Web页面中;支持XML-RPC;支持多种数据库 SQLite, PostgreSQL, MySQL, MySQLi;支持从其它Blog系统(WordPress,Textpattern,Moveable Type,bblog,…)导入的功能。

7、JBLOG

JBLOG是基于PHP+MySQL的开源博客程序,具有速度快、效率高、功能强大、操作体验佳等特点。支持生成HTML静态页面、URL Rewrite(需要服务器支持)、自定义URL、创建自定义页面、Meta Description标签等功能。

8、BLOG:CMS

BLOG:CMS是一个功能强大,最全面的个人信息发布系统。它包括最顶级Weblog,论坛,wiki引擎,新闻聚合器(atom/rss),相册。

9、Bo-Blog2.0

Bo-Blog2.0是一款基于PHP的、以MySQL为数据库支持的免费blog程序。

  • 易用的日志功能
    以易用性为出发点,可让大众迅速上手的日志程序。集成留言本、表情、天气等满足大众需求的功能。
  • 合理的信息组织
    通过置顶、Tags、二级分类、归档、星标等功能,将您的日志有效组织起来,方便查看和搜索。
  • 丰富的定制特性
    灵活的页面模块、插件系统、基于xhtml+css的模板和多语言架构,充分给予用户自定义的权利。
  • 适当的技术体验
    被Ajax、RSS、XML-RPC、Tags等名词搞晕了?那就亲自实践一下吧。您会喜欢它们带来的体验的。

继续阅读“[转]哪些PHP开源博客系统”

Sphinx如何实现搜索结果过滤功能

一般网站的搜索功能,用Sphinx做个没什么过滤条件的全文检索功能,基本上能满足网站的部分功能。然而,在很大部分情况下,是需要做检索的结果过滤(需求描述:假如我们要搜索学生档案。a.只需要查找性别为“男”的学生;  b:只要搜索学生年龄在:18至20岁之前的学生档案)。这个时候,我们就需要用到Sphinx的结果集过滤设置功能了。

通过Sphinx PHP API 文档(Sphinx 0.9.8),得到结果集过滤接口有以下几个方法:
  • 5.4.1. SetIDRange
  • 5.4.2. SetFilter
  • 5.4.3. SetFilterRange
  • 5.4.4. SetFilterFloatRange
  • 5.4.5. SetGeoAnchor
篇幅原因这里我不对接口一一做介绍,我只抽取其中两个方法做说明,正好解决上面提到的二个需求:
第一:SetFilter  (解决需求a:只需要查找性别为“男”的学生)
注意:必须是无符号整数属性(sql_attr_uint )
原型: function SetFilter ( $attribute, $values, $exclude=false )
增加整数值过滤器。
此调用在已有的过滤器列表中添加新的过滤器。$attribute是属性名。$values是整数数组。
$exclude是布尔值,它控制是接受匹配的文档(默认模式,即$exclude为假时)还是拒绝它
们。
只有当索引中$attribute列的值与$values中的任一值匹配时文档才会被匹配(或者拒绝,如
果$exclude值为真)
第二:SetFilterRange  (解决需求b:只要搜索学生年龄在:18至20岁之前的学生档案)
注:可以是浮点型属性(sql_attr_float ) 和 无符号整数属性(sql_attr_uint )
原型 : function SetFilterRange ( $attribute, $min, $max, $exclude=false )
添加新的整数范围过滤器。
此调用在已有的过滤器列表中添加新的过滤器。$attribute是属性名, $min、$max定义了
一个整数闭区间,$exclude布尔值,它控制是接受匹配的文档(默认模式,即$exclude为
假时)还是拒绝它们。
只有索引中$attribute列的值落在$min和$max之间(包括$min和$max),文档才会被匹配
(或者拒绝,如果$exclude值为真)。
在搜索的程序要用这几个接口,不是我们想像的那样,直接在程序里直接调用就能用的,如果你在Sphinx数据源配置文件里没有配置置对应的属性,用这个过滤是不生效的(搜索失败,直接报错)。
在使用过滤功能时,需要注意以下两点就行:
1.在sphinx.conf(名称换成您的数据源配置文件)文件里修改如下配置,如:
source main
 {
 type                    = mysql
 sql_host                = 127.0.0.1
 sql_user                = devel
 sql_pass                = oophp.cn
 sql_db                  = oophp
 sql_port                = 3306
 sql_query_pre            = SET NAMES utf8
 # [注:性别,这里要用SetFilter,就必须用sql_attr_uint这属于性。来源:www.oophp.cn]
 sql_attr_uint = gender

 # [注:年龄,SetFilterRange可以用,sql_attr_uint也可以用。来源:www.oophp.cn]
 sql_attr_float = age
}
2.在sphinx.conf的数据源SQL中,把需要过滤的字段相应增加到数据源中,如:
source main
 {
 type                    = mysql
 sql_host                = 127.0.0.1
 sql_user                = devel
 sql_pass                = oophp.cn
 sql_db                  = oophp
 sql_port                = 3306
 sql_query_pre            = SET NAMES utf8
 sql_query =  SELECT id, gender, age, username,
              introduction FROM student  ORDER  BY id  DESC
}
按上面的方式修改数据源配置,重新生成一次全量索引后。直接var_dump检测看是否属性设置是否生效,类似输出这个:
array(9) {
 ["error"]=>
 string(0) ""
 ["warning"]=>
 string(0) ""
 ["status"]=>
 int(0)
 ["fields"]=>
 array(2) {
 [0]=>
 string(5) "username"
 [1]=>
 string(12) "introduction"
 }
 ["attrs"]=>
 array(6) {
 ["id"]=>
 int(1)
 ["gender"]=>
 int(2)
 ["age"]=>
 ["@expr"]=>
 int(5)
 }
 ["matches"]=>
 array(10) {
 [266652]=>
 }
 .......
 }
如果能看到属性区有genderage,就证明修改的配置已生效。这个时候在程序里通过调用相应的接口就能得到正确数据的结果。类似如下:
<?php
$sphinx = new SphinxClient();
$sphinx->SetServer('127.0.0.1','9312');
$sphinx->SetConnectTimeout(1);
$sphinx->SetLimits(0,10);
$sphinx->SetMatchMode(SPH_MATCH_EXTENDED);
$sphinx->SetSortMode (SPH_SORT_EXPR,
            "@weight*50000+age+ln(id)*100000" );
//做相应的过滤处理
 //1代表男生
$sphinx->SetFilter('gender',array(1));
//取到18到20岁的学生档案
$sphinx->SetFilterFloatRange('age',18,20);

.......
参考资料:
http://blog.csdn.net/adparking/article/details/6445926
http://www.coreseek.cn/
http://www.wapm.cn/uploads/pdf/sphinx_doc_zhcn_0.9.pdf

什么是Redis

Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、 list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操 作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的 是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。

数据模型

作为Key-value型数据库,Redis也提供了键(Key)和键值(Value)的映射关系。但是,除了常规的数值或字符串,Redis的键值还可以是以下形式之一:

  • Lists (列表)
  • Sets (集合)
  • Sorted sets (有序集合)
  • Hashes (哈希表)

键值的数据类型决定了该键值支持的操作。Redis支持诸如列表、集合或有序集合的交集、并集、差集等高级原子操作;同时,如果键值的类型是普通数字,Redis则提供自增等原子操作。

持久化

通常,Redis将数据存储于内存中,或被配置为使用虚拟内存。[3]通过两种方式可以实现数据持久化:使用快照的方式,将内存中的数据不断写入磁盘;或使用类似MySQL的日志方式,记录每次更新的日志。前者性能较高,但是可能会引起一定程度的数据丢失;后者相反。

主从同步

Redis支持将数据同步到多台从库上,这种特性对提高读取性能非常有益。

性能

相比需要依赖磁盘记录每个更新的数据库,基于内存的特性无疑给Redis带来了非常优秀的性能。读写操作之间没有显著的性能差异,如果Redis将数据只存储于内存中。

提供API的语言

为以下语言提供API:

  • C
  • C++
  • C#
  • Clojure
  • Common Lisp
  • Erlang
  • Haskell
  • Java
  • JavaScript
  • Lua
  • Objective-C
  • Perl
  • PHP
  • Python
  • Ruby
  • Scala
  • Go
  • Tcl

[转]什么是独立磁盘冗余阵列 RAID

RAID,redundant array of independent disks,redundant array of inexpensive disks
RAID技术主要包含RAID 0~RAID 50等数个规范,它们的侧重点各不相同,常见的规范有如下几种:
RAID 0:RAID 0连续以位或字节为单位分割数据,并行读/写于多个磁盘上,因此具有很高的数据传输率,但它没有数据冗余,因此并不能算是真正的RAID结构。RAID 0只是单纯地提高性能,并没有为数据的可靠性提供保证,而且其中的一个磁盘失效将影响到所有数据。因此,RAID 0不能应用于数据安全性要求高的场合。
RAID 1:它是通过磁盘数据镜像实现数据冗余,在成对的独立磁盘上产生互为备份的数据。当原始数据繁忙时,可直接从镜像拷贝中读取数据,因此RAID 1可以提高读取性能。RAID 1是磁盘阵列中单位成本最高的,但提供了很高的数据安全性和可用性。当一个磁盘失效时,系统可以自动切换到镜像磁盘上读写,而不需要重组失效的数据。
[3]
RAID 01/10:根据组合分为RAID 10和RAID 01,实际是将RAID 0和RAID 1标准结合的产物,在连续地以位或字节为单位分割数据并且并行读/写多个磁盘的同时,为每一块磁盘作磁盘镜像

进行冗余。它的优点是同时拥有RAID 0的超凡速度和RAID 1的数据高可靠性,但是CPU占用率同样也更高,而且磁盘的利用率比较低。RAID 1+0是先镜射再分区数据,再将所有硬盘分为两组,视为是RAID 0的最低组合,然后将这两组各自视为RAID 1运作。RAID 0+1则是跟RAID 1+0的程序相反,是先分区再将数据镜射到两组硬盘。它将所有的硬盘分为两组,变成RAID 1的最低组合,而将两组硬盘各自视为RAID 0运作。性能上,RAID 0+1比RAID 1+0有着更快的读写速度。可靠性上,当RAID 1+0有一个硬盘受损,其余三个硬盘会继续运作。RAID 0+1 只要有一个硬盘受损,同组RAID 0的另一只硬盘亦会停止运作,只剩下两个硬盘运作,可靠性较低。因此,RAID 10远较RAID 01常用,零售主板绝大部份支持RAID 0/1/5/10,但不支持RAID 01。
RAID 2:将数据条块化地分布于不同的硬盘上,条块单位为位或字节,并使用称为“加重平均纠错码汉明码)”的编码技术来提供错误检查及恢复。这种编码技术需要多个磁盘存放检查及恢复信息,使得RAID 2技术实施更复杂,因此在商业环境中很少使用。
RAID 3:它同RAID 2非常类似,都是将数据条块化分布于不同的硬盘上,区别在于RAID 3使用简单的奇偶校验,并用单块磁盘存放奇偶校验信息。如果一块磁盘失效,奇偶盘及其他数据盘可以重

新产生数据;如果奇偶盘失效则不影响数据使用。RAID 3对于大量的连续数据可提供很好的传输率,但对于随机数据来说,奇偶盘会成为写操作的瓶颈。

RAID 4:RAID 4同样也将数据条块化并分布于不同的磁盘上,但条块单位为块或记录。RAID 4使用一块磁盘作为奇偶校验盘,每次写操作都需要访问奇偶盘,这时奇偶校验盘会成为写操作的瓶颈,因此RAID 4在商业环境中也很少使用。

RAID 5:RAID 5不单独指定的奇偶盘,而是在所有磁盘上交叉地存取数据及奇偶校验信息。在RAID 5上,读/写指针可同时对阵列设备进行操作,提供了更高的数据流量。RAID 5更适合于小数据块和 随机读写的数据。RAID 3与RAID 5相比,最主要的区别在于RAID 3每进行一次数据传输就需涉及到所有的阵列盘;而对于RAID 5来说,大部分数据传输只对一块磁盘操作,并可进行并行操作。在RAID 5中有“写损失”,即每一次写操作将产生四个实际的读/写操作,其中两次读旧的数据及奇偶信息,两次写新的数据及奇偶信息。
RAID 6:与RAID 5相比,RAID 6增加了第二个独立的奇偶校验信息块。两个独立的奇偶系统使用不同的算法,数据的可靠性非常高,即使两块磁盘同时失效也不会影响数据的使用。但RAID 6需要分配给奇偶校验信息更大的磁盘空间,相对于RAID 5有更大的“写损失”,因此“写性能”非常差。较差的性能和复杂的实施方式使得RAID 6很少得到实际应用。
RAID 7:这是一种新的RAID标准,其自身带有智能化实时操作系统和用于存储管理的软件工具,可完全独立于主机运 行,不占用主机CPU资源。RAID 7可以看作是一种存储计算机(Storage Computer),它与其他RAID标准有明显区别。除了以上的各种标准(如表1),我们可以如RAID 0+1那样结合多种RAID规范来构筑所需的RAID阵列,例如RAID 5+3(RAID 53)就是一种应用较为广泛的阵列形式。用户一般可以通过灵活配置磁盘阵列来获得更加符合其要求的磁盘存储系统。
RAID 5E(RAID 5 Enhancement): RAID 5E是在RAID 5级别基础上的改进,与RAID 5类似,数据的校验信息均匀分布在各硬盘上,但是,在每个硬盘上都保留了一部分未使用的空间,这部分空间没有进行条带化,最多允许两块物理硬盘出现故障。 看起来,RAID 5E和RAID 5加一块热备盘好象差不多,其实由于RAID 5E是把数据分布在所有的硬盘上,性能会比RAID5 加一块热备盘要好。当一块硬盘出现故障时,有故障硬盘上的数据会被压缩到其它硬盘上未使用的空间,逻辑盘保持RAID 5级别。
RAID 5EE: 与RAID 5E相比,RAID 5EE的数据分布更有效率,每个硬盘的一部分空间被用作分布的热备盘,它们是阵列的一部分,当阵列中一个物理硬盘出现故障时,数据重建的速度会更快。
RAID 50:RAID50 是RAID5与RAID0的结合。此配置在RAID5的子磁盘组的每个磁盘上进行包括奇偶信息在内的数据的剥离。每个RAID5子磁盘组要求三个硬盘。 RAID50具备更高的容错能力,因为它允许某个组内有一个磁盘出现故障,而不会造成数据丢失。而且因为奇偶位分部于RAID5子磁盘组上,故重建速度有 很大提高。优势:更高的容错能力,具备更快数据读取速率的潜力。需要注意的是:磁盘故障会影响吞吐量。故障后重建信息的时间比镜像配置情况下要长。

[转]如何配置Dell Raid

此文档为自行整理,非官方提供资料,仅供参考。疏漏之处敬请反馈。

对RAID进行操作很可能会导致数据丢失,请在操作之前务必将重要数据妥善备份,以防万一。

名称解释:
Disk Group:磁盘组,这里相当于是阵列,例如配置了一个RAID5,就是一个磁盘组
VD(Virtual Disk): 虚拟磁盘,虚拟磁盘可以不使用阵列的全部容量,也就是说一个磁盘组可以分为多个VD
PD(Physical Disk): 物理磁盘
HS:Hot Spare 热备
Mgmt:管理

【一】,创建逻辑磁盘
1、按照屏幕下方的虚拟磁盘管理器提示,在VD Mgmt菜单(可以通过CTRL+P/CTRL+N切换菜单),按F2展开虚拟磁盘创建菜单

clip_image002

2、在虚拟磁盘创建窗口,按回车键选择”Create New VD”创建新虚拟磁盘

clip_image004

3、在RAID Level选项按回车,可以出现能够支持的RAID级别,RAID卡能够支持的级别有RAID0/1/5/10/50,根据具体配置的硬盘数量不同,这个位置可能出现的选项也会有所区别。
选择不同的级别,选项会有所差别。选择好需要配置的RAID级别(我们这里以RAID5为例),按回车确认。

clip_image006

4、 确认RAID级别以后,按向下方向键,将光标移至Physical Disks列表中,上下移动至需要选择的硬盘位置,按空格键来选择(移除)列表中的硬盘,当选择的硬盘数量达到这个RAID级别所需的要求时,Basic Settings的VD Size中可以显示这个RAID的默认容量信息。有X标志为选中的硬盘。
选择完硬盘后按Tab键,可以将光标移至VD Size栏,VD Size可以手动设定大小,也就是说可以不用将所有的容量配置在一个虚拟磁盘中。如果这个虚拟磁盘没有使用我们所配置的RAID5阵列所有的容量,剩余的 空间可以配置为另外的一个虚拟磁盘,但是配置下一个虚拟磁盘时必须返回VD Mgmt创建(可以参考第13步,会有详细说明)。VD Name根据需要设置,也可为空。
注:各RAID级别最少需要的硬盘数量,RAID0=1  RAID1=2  RAID5=3  RAID10=4  RAID50=6

clip_image007

5、 修改高级设置,选择完VD Size后,可以按向下方向键,或者Tab键,将光标移至Advanced Settings处,按空格键开启(禁用)高级设置。如果开启后(红框处有X标志为开启),可以修改Stripe Element Size大小,以及阵列的Read Policy与Write Policy,Initialize处可以选择是否在阵列配置的同时进行初始化。
高级设置默认为关闭(不可修改),如果没有特殊要求,建议不要修改此处的设置。

clip_image008

6、上述的配置确认完成后,按Tab键,将光标移至OK处,按回车,会出现如下的提示,如果是一个全新的阵列,建议进行初始化操作,如果配置阵列的目的是为了恢复之前的数据,则不要进行初始化。按回车确认即可继续。

clip_image010

7、配置完成后,会返回至VD Mgmt主界面,将光标移至图中Virtual Disk 0处,按回车。

clip_image011

8、可以看到刚才配置成功的虚拟磁盘信息,查看完成后按esc键可以返回主界面

clip_image012

9、在此界面,将光标移至图中Virtual Disk 0处,按F2键可以展开对此虚拟磁盘操作的菜单。
注:左边有+标志的,将光标移至此处,按向右方向键,可以展开子菜单,按向左方向键,可以关闭子菜单

clip_image013

10、如下图红框所示,可以对刚才配置成功的虚拟磁盘(Virtual Disk 0)进行初始化(Initialization),一致性校验(Consistency Check),删除,查看属性等操作。

clip_image014

11、如果我们要对此虚拟磁盘进行初始化,可以将光标移至Initialization处,回车后选择Start Init。此时会弹出提示窗口,初始化将会清除所有数据,如果确认要进行初始化操作,在OK处按回车即可继续。
注:初始化会清除硬盘、阵列中的所有信息,并且无法恢复

clip_image016

12、确认后可以看到初始化的进度,左边红框处为百分比表示,右边红框处表示目前所作的操作。等待初始化进行为100%,虚拟磁盘的配置完成。

clip_image018

13、如果刚才配置虚拟磁盘的时候没有使用阵列的全部容量,剩余的容量可以在这里划分使用。将光标移至Space allocation处,按向右方向键展开此菜单

clip_image020

14、将光标移至*Free Space*处,按F2键,至第15步,或者直接按回车至第16步

clip_image022

15、在弹出的Add New VD处按回车键。

clip_image024

16、再次进入配置虚拟磁盘的界面,此时左边红框处为刚才配置的虚拟磁盘已经选择的物理磁盘信息,右边红框处可以选择这次要划分的容量空间。同样,如果不全部划分,可以再次返回第13步,进行再一个虚拟磁盘的创建。
注:由于虚拟磁盘的建立是基于刚才所创建的阵列,所以RAID Level与刚才所创建的相同,无法更改。

clip_image026

17、每一次创建,都会在Virtual Disks中添加新的虚拟磁盘。这些虚拟磁盘都是在同一个磁盘组(也就是我们刚才所配置的RAID5)上划分的。

clip_image028

【二】,配置热备(Hot spare)
配置Hot Spare有两种模式,一种是全局热备,也就是指这个热备硬盘可以做为这个通道上所有阵列的热备;另一种是独立热备,配置硬盘为某个指定的磁盘组中的所有虚拟磁盘做热备,也就是说这个磁盘组以外的其他阵列即使硬盘掉线,这个热备也不会去自动做rebuild
配置全局热备:
1、首先要已经有存在的磁盘组(阵列),我们这里举例为已经配置了两个阵列,阵列0是由0、1、2三块物理磁盘配置的RAID5,阵列1是由4、5两块物理磁盘配置的RAID1,如图:

clip_image030

2、按CTRL+N 切换至PD Mgmt界面,可以看到4号硬盘的状态是Ready。

clip_image032

3、将光标移至4号硬盘,按F2,在弹出的菜单中,选择Make Global HS,配置全局的热备盘

clip_image034

4、确认后,4号硬盘的状态变为Hotspare

clip_image036

5、配置完成后,可以看到磁盘组0与磁盘组1的热备盘都是同一个。

clip_image038

6、移除热备,进入PD Mgmt菜单,将光标移至热备盘处,按F2,选择Remove Hot Spare,回车移除

clip_image040

配置独立热备:
1、在配置好的虚拟磁盘管理界面下,将光标移至需要配置独立热备的磁盘组上,按F2键,在出现的菜单中选择 Manage Ded. HS

clip_image042

2、将光标移至需要配置为热备的硬盘上,按空格键,看到X标识,说明此硬盘被选择。将光标移至OK处回车,完成配置

clip_image044

3、可以看到磁盘组0已经有了热备盘,并且是Dedicated。而磁盘组1并没有热备盘。

clip_image046

4、移除热备,同第1步,将光标移至需要移除热备的磁盘组上,按F2键,在出现的菜单中选择 Manage Ded. HS

clip_image047

5、将光标移至需要移除的热备硬盘上,按空格键,去掉X标识,说明此硬盘被移除。将光标移至OK处回车,完成热备移除。

clip_image049
【三】删除虚拟磁盘:
1、将光标移至要删除的虚拟磁盘处,按F2,选择Delete VD按回车继续

clip_image051

2、在弹出的确认窗口,OK处按回车确认即可删除。
注:删除的同时会将此虚拟磁盘的数据全部删除。

clip_image053

3、删除磁盘组,将光标移至要删除的磁盘组处,按F2,选择Delete Disk Group按回车继续

clip_image055

4、在弹出的确认窗口,OK处按回车确认,即可删除
注:删除的同时会将此磁盘组的数据全部删除。

clip_image057

2013年最流行的php框架盘点

PHP框架的发展背景

毫无疑问,Web框架技术在近几年已经得到了突飞猛进的发展和普及,在过去几年里,框架技术的普遍经历了比较大的完善过程,很大一部分可以归因于Ruby on Rails,以及在其他编程语言中流露出的MVC框架思想。

如果你是一个PHP忍者,而不是一个铁杆的Ruby追随者,你也许会惊奇市面上已经有这么多的框架,哪一个才是适合你的。当然回答和个问题取决于的诸多因素,今天我们将会回顾一下这个典型的问题,如何为你的下一个应用系统选择适合你的PHP框架。

同时我们也来看一下比较流行的PHP框架,比较一下他们的区别,这样可以帮你自己做出明智的选择,找到最适合你项目的框架。

明确你的需求

在你决定为你的项目选择一个框架之前,你当先理解需要,需求和了解一些开发团队幕后的工作,我们总结出了如下几个问题,在开始下一步之前你可以试着问问自己。

 

你的应用程序主要集中于解决哪些问题?

你的应用可以是一个电子商务平台,一个社交网站,消息共享平台或者活动目录,举例来说,如果你正在构建一个电子商务网站,你也许更希望选用一些具有 用于处理信用卡和交易会话的成熟的扩展函数库的框架。另一方面,如果是一个轻量级的消息平台(比如说微博类系统),则你也许更应该注重快速的扩展和跨服务 器跨数据的支撑访问能力,为了实现负载均衡和快速连接访问。

 

你的主机运行环境将是什么?

有些特殊的框架会需要使用到一些非默认的其它PHP扩展或者软件安装在服务器上,比如,有些框架的数据抽象层必须要求通过PDO来实现访问,而非直 接调用更底层的MySQL或MySQLi,或者有些类似wiki类的程序的图像压缩和处理功能往往需要使用到ImageMagick 或 Graphiviz 这些外部程序。而这些扩展也许并不会被所有的共享主机环境(虚拟主机)支持,此外即便是一个轻量级的小型框架,而且自我集成了所有所需的函数库并且也具有 良好的可移植性和适应性,这样的框架应用在处理数据密集型的操作或者大型数据处理的系统时,性能又会成为它的主要瓶颈。

你的开发人员或团队的优势和劣势在于什么?

如果你是个项目经理,一个重要的事情是了解清楚你的具体开发人员他们的能力和弱势,因为他们是真的闷头干活儿人,所以也许你可以选择一些更加面向开 发人员友好的容易上手的框架。当然这个问题的也许并不是影响决定是否采用一个框架的决定性因素(不断地要求自己和团队学习新的技术总是好的),但着绝对是 一个会影响到你的时间表、预算和安全等多方面因素的重要考量条件。

如何在高耦合性” 还是 低耦合性” 的框架中做出选择?

如果从框架产品自身的耦合性来将目前主流的php框架产品分为高耦合性和低耦合性两类。低耦合性的框架看起来更像是一个丰富的函数库和逻辑封装的抽 象层,甚至有些好的框架自身就是PHP的一个高级扩展组件,比如PDO,它绝对算得上是一个数据访问的框架也是抽象层。还有一些其他值得一提的低耦合性框 架,比如Zend Framework,CakePHP,以及国内开发的ThinkPHP都属于这个范畴。 如果你将接手的项目历史问题比较多,并且对UI的自定义比较高,你恐怕需要一个低耦合性的框架来满足你灵活的需求。

 

目前主流的开发框架

现在我们已经对你将要开发的应用程序和你的开发团队有了足够的了解和认识,那么接下来让我们来测试几款比较流行的框架和他们所能提供给我们的功能特性吧。

CakePHP 开发框架

官方网址:http://cakephp.org/

下载地址:https://github.com/cakephp/cakephp/archive/2.3.0-RC2.tar.gz

如果你仍然需要编写面向PHP4兼容的代码,CakePHP 将是一个非常不错的选择, 在PHP 4 & 5的MVC式框架列表里面,CakePHP都曾经是最流行的。它还提供了很多种途径的技术支持(讨论组、留言板、IRC等)还有优秀的教程。 CackePHP是个很容易上手的框架,但是你并不容易在短短几周的时间就完全掌握它。

 

Zend Framework框架

官方网址:http://framework.zend.com

下载地址:http://www.zend.com/en/download/633

Zend Framework 是面对一些较有经验的开发者和从底层构建一些企业级应用程序而设计的。(例如:宣称面向企业应用而设计的 Openbiz Cubi 就是基于Zend Framework框架之上而构建的。)该框架是高度模块化的。这意味着你可以按你的实际需要来引用Zend的代码。有些函数库甚至可以很容的被提取出来 单独使用(例如Zend_Gdata,这也是个低耦合性的特点)使用Zend框架,你不必非要遵从它的MVC架构,(虽然你最好能这么做),并且它还提供 了许多内建的高级功能用于完成与现有的web服务整合,多语言化和实现单元测试这些任务。

 

CodeIgniter

官方网址: http://codeigniter.org.cn

下载地址:http://codeigniter.org.cn/download

CodeIgniter 是一个PHP5.2+ 的MVC框架,它体积小巧切具有丰富的文档资源。通常被称为初学者框架,因为它相对容易试用和较短的学习曲线,此外CodeIgniter也是十分灵 活和强大的。该框架拥有一个非常庞大的社区支持。并且在社区里面很容易找到大量的CI函数库,你可以大胆的梦想, 也许你正需要做的事情在社区的某个交流,某个人已经把它实现了。

 

Symfony

官方网址:http://symfony.com/

下载地址:http://symfony.com/download

这是一位老大爷向我推荐应该把它也收录进来。 

Symfony 是最古老的PHP框架之一(相信你从他的网站风格上也发现这一点了),他同样也是转为企业级Web应用程序而设计的。然而,对于他所能提供的所有动力和性 能而言,它只拥有很小的体积并且非常容易配置在大多数php的主机环境中。由于他的年头最长久,你会很容易找到许多关于Symfony的教程、书记等资 料,对于新手来说,这绝对是件好事儿。

Symfony使用命令行代码生成工具来为项目快速生成所需的代码,这种方式也许对于某些开发人员来说是前所未闻的(在那个年头,也许 吧。。。)然后,他可以帮助你在很短的时间里完成代码并是他们可以运行。Symfony的网站上手机了大量的教程和范例代码,来帮助你熟悉掌握他们。

 

Yii Framework

官方网址:http://www.yiiframework.com

下载地址:http://yii.googlecode.com/files/yii-1.1.13.e9e4a0.tar.gz

这也是近几年才出现的一匹黑马。

Yii 是一个高度模块化,高性能的PHP5框架,专门为了Web应用程序而开发。Yii采用了大量的命令行生成工具,让你可以快速的生成一些代码,因此,他最适 合于喜欢在命令行的黑窗口上敲敲打打的人。所有这些代码生成工具意味着你需要记住更多的命令和参数,但是一点你做到了,你会发现,它们将大大减少你所要花 费的时间来设置和配置你的应用程序。

这种开发方式 非常类似于Openbiz Appbuilder所提供的向导式的代码生成方式,最大的不同点是Yii是基于命令行去生成代码,Openbiz Appbuilder是在图形界面上生成代码。

 

最后,一家之见。有不同意见,请留言讨论。

 

分享:PHP怎么样去掉从word直接粘贴过来的没有用的格式

通常我们会遇到直接把word内的内容,直接粘贴到文本编辑器中。这时候会出现在文本编辑器中有一些word内的没用的标签内容。一般处理的方式有二种:1.通过编辑器的JS直接去除。2.提交到后台后,直接用程序去掉无效标签。下面我就分享一个通过PHP的处理方式,成功率可能不是100%。这程序也是在PHP官网上看到的,就顺便粘贴过来了。

function ClearHtml($content,$allowtags='') {
			
			mb_regex_encoding('UTF-8');
			//replace MS special characters first
			$search = array('/&lsquo;/u', '/&rsquo;/u', '/&ldquo;/u', '/&rdquo;/u', '/&mdash;/u');
			$replace = array('\'', '\'', '"', '"', '-');
			$content = preg_replace($search, $replace, $content);
			//make sure _all_ html entities are converted to the plain ascii equivalents - it appears
			//in some MS headers, some html entities are encoded and some aren't
			$content = html_entity_decode($content, ENT_QUOTES, 'UTF-8');
			//try to strip out any C style comments first, since these, embedded in html comments, seem to
			//prevent strip_tags from removing html comments (MS Word introduced combination)
			if(mb_stripos($content, '/*') !== FALSE){
				$content = mb_eregi_replace('#/\*.*?\*/#s', '', $content, 'm');
			}
			//introduce a space into any arithmetic expressions that could be caught by strip_tags so that they won't be
			//'<1' becomes '< 1'(note: somewhat application specific)
			$content = preg_replace(array('/<([0-9]+)/'), array('< $1'), $content);
			
			$content = strip_tags($content, $allowtags);
			//eliminate extraneous whitespace from start and end of line, or anywhere there are two or more spaces, convert it to one
			$content = preg_replace(array('/^\s\s+/', '/\s\s+$/', '/\s\s+/u'), array('', '', ' '), $content);
			//strip out inline css and simplify style tags
			$search = array('#<(strong|b)[^>]*>(.*?)</(strong|b)>#isu', '#<(em|i)[^>]*>(.*?)</(em|i)>#isu', '#<u[^>]*>(.*?)</u>#isu');
			$replace = array('<b>$2</b>', '<i>$2</i>', '<u>$1</u>');
			$content = preg_replace($search, $replace, $content);
			
			//on some of the ?newer MS Word exports, where you get conditionals of the form 'if gte mso 9', etc., it appears
			//that whatever is in one of the html comments prevents strip_tags from eradicating the html comment that contains
			//some MS Style Definitions - this last bit gets rid of any leftover comments */
			$num_matches = preg_match_all("/\<!--/u", $content, $matches);
			if($num_matches){
				$content = preg_replace('/\<!--(.)*--\>/isu', '', $content);
			}
			return $content;
}

测试使用结果:

<?php
$content = ' <!--[if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->
    			<p class="p0" style="text-indent: 24.0000pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="mso-spacerun: "yes"; font-size: 12.0000pt; font-family: "宋体";">《优伴户外旅行》&mdash;&mdash;让旅行成为习惯!</span></p>越发忙碌的你,是否想给自己放个假?专注工作的你,是否还记得上一次锻炼是什么时候?优伴户外旅行,给你不一样的旅行体验:给心自由,便处处都是风景!</span></p>';
echo ClearHtml($content,'<p>');

/*
得到的结果:
<p  >《优伴户外旅行》--让旅行成为习惯!</p>越发忙碌的你,是否想给自己放个假?专注工作的你,是否还记得上一次锻炼是什么时候?优伴户外旅行,给你不一样的旅行体验:给心自由,便处处都是风景!</p>
*/
?>

分享:PHP怎么样补齐关闭的HTML标签

很多时候,在我们做文章截取摘要的时候,如果出现HTML的内容,会出现截取的文章没有结束的HTML标签。这样的情况下就会出现页面样式错乱的问题。这 个时候我们需要的就是把缺少的结束标签加批量加上。在www.php.net官网看到一个比较好处理的一个函数,展示如下:

function CloseTags($html)
{
        // strip fraction of open or close tag from end (e.g. if we take first x characters, we might cut off a tag at the end!)
        $html = preg_replace('/<[^>]*$/','',$html); // ending with fraction of open tag
       
        // put open tags into an array
        preg_match_all('#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
        $opentags = $result[1];

        // put all closed tags into an array
        preg_match_all('#</([a-z]+)>#iU', $html, $result);
        $closetags = $result[1];

        $len_opened = count($opentags);

        // if all tags are closed, we can return
        if (count($closetags) == $len_opened) {
            return $html;
        }

        // close tags in reverse order that they were opened
        $opentags = array_reverse($opentags);

        // self closing tags
        $sc = array('br','input','img','hr','meta','link');
        // ,'frame','iframe','param','area','base','basefont','col'
        // should not skip tags that can have content inside!

        for ($i=0; $i < $len_opened; $i++)
        {
            $ot = strtolower($opentags[$i]);
            if (!in_array($opentags[$i], $closetags) && !in_array($ot,$sc))
            {
                $html .= '</'.$opentags[$i].'>';
            }
            else
            {
                unset($closetags[array_search($opentags[$i], $closetags)]);
            }
        }
        return $html;
}

测试使用的结果:

<?php
$content = '<div><p><span>越发忙碌的你,是否想给自己放个假?专注工作的你,是否还记得上一次锻炼是什么时候?优伴户外旅行,给你不一样的旅行体验:给心自由,便处处都是风景!';
echo CloseTags($content);

/*
返回的结果是:
<div><p><span>
越发忙碌的你,是否想给自己放个假?专注工作的你,是否还记得上一次锻炼是什么时候?优伴户外旅行,给你不一样的旅行体验:给心自由,便处处都是风景!</span></p></div>
*/
?>