PHP也支持多线程:cURL并发请求

PHP cURL所有函数列表:
https://secure.php.net/manual/zh/ref.curl.php

以下是PHP中cURL多线程相关函数:

  • curl_multi_add_handle — 向curl批处理会话中添加单独的curl句柄
  • curl_multi_close — 关闭一组cURL句柄
  • curl_multi_exec — 运行当前 cURL 句柄的子连接
  • curl_multi_getcontent — 如果设置了CURLOPT_RETURNTRANSFER,则返回获取的输出的文本流
  • curl_multi_info_read — 获取当前解析的cURL的相关传输信息
  • curl_multi_init — 返回一个新cURL批处理句柄
  • curl_multi_remove_handle — 移除curl批处理句柄资源中的某个句柄资源
  • curl_multi_select — 等待所有cURL批处理中的活动连接
  • curl_multi_setopt — 为 cURL 并行处理设置一个选项
  • curl_multi_strerror — Return string describing error code

一般来说,想到要用这些函数时,目的显然应该是要同时请求多个URL,而不是一个一个依次请求,否则不如自己循环去调curl_exec好了。

步骤总结如下:

1、调用 curl_multi_init,初始化一个批处理handle
2、循环调用 curl_multi_add_handle,往1中的批处理handle 添加curl_init来的子handle
3、持续调用 curl_multi_exec,直到所有子handle执行完毕。
4、根据需要循环调用 curl_multi_getcontent 获取结果
5、调用 curl_multi_remove_handle,并为每个字handle调用curl_close
6、调用 curl_multi_close

以下是一个通过并发请求抓取网页的demo

$urls = array(
    'https://979137.com/',
    'http://www.sina.com.cn/',
    'http://www.sohu.com/',
    'http://www.163.com/'
);

//1、初始化一个批处理handle
$mh = curl_multi_init();

//2、往批处理handle 添加curl_init来的子handle
foreach ($urls as $i => $url) {
    $conn[$i] = curl_init($url);
    curl_setopt($conn[$i], CURLOPT_HEADER, 0);   
    curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT, 60);
    curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($mh, $conn[$i]);
}

//3、并发执行,直到全部结束。
do {
    curl_multi_exec($mh, $active);
} while ($active);

//4、获取结果
foreach ($urls as $i => $url) {
    $data = curl_multi_getcontent($conn[$i]);
    echo ($data);
}

//5、移除子handle,并close子handle
foreach ($urls as $i => $url) {
    curl_multi_remove_handle($mh,$conn[$i]);
    curl_close($conn[$i]);
}

//6、关闭批处理handle
curl_multi_close($mh);

Redis、Memcache、MongoDB的区别与关系和作用

1、性能

都比较高,性能对我们来说应该都不是瓶颈
总体来讲,TPS 方面 Redis 和 Memcache 差不多,要大于 MongoDB

2、操作的便利性

Redis 丰富一些,数据操作方面,Redis更好一些,较少的网络IO次数
Memcache 数据结构单一MongoDB 支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富

3、内存空间的大小和数据量的大小

MongoDB 适合大数据量的存储,依赖操作系统VM做内存管理,吃内存也比较厉害,服务不要和别的服务在一起
Redis 在2.0版本后增加了自己的VM特性,突破物理内存的限制;可以对key value设置过期时间(类似Memcache)
Memcache 可以修改最大可用内存,采用LRU算法

4、可用性(单点问题)

对于单点问题,Redis,依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制,因性能和效率问题,
所以单点问题比较复杂;不支持自动sharding,需要依赖程序设定一致hash 机制。
一种替代方案是,不用Redis本身的复制机制,采用自己做主动复制(多份存储),或者改成增量复制的方式(需要自己实现),一致性问题和性能的权衡;
Memcache 本身没有数据冗余机制,也没必要;对于故障预防,采用依赖成熟的hash或者环状的算法,解决单点故障引起的抖动问题。
MongoDB支持master-slave,replicaset(内部采用paxos选举算法,自动故障恢复),auto sharding机制,对客户端屏蔽了故障转移和切分机制。

5、可靠性(持久化、数据恢复)

Redis 支持(快照、AOF):依赖快照进行持久化,aof增强了可靠性的同时,对性能有所影响
Memcache 不支持,通常用在做缓存,提升性能;
MongoDB 从1.8版本开始采用binlog方式支持持久化的可靠性

6、数据一致性(事务支持)

Memcache 在并发场景下,用cas保证一致性
Redis 事务支持比较弱,只能保证事务中的每个操作连续执行
MongoDB 不支持事务

7、数据分析

MongoDB 内置了数据分析的功能(mapreduce),
其他不支持

8、应用场景

Redis:数据量较小的更性能操作和运算上
Memcache:用于在动态系统中减少数据库负载,提升性能;做缓存,提高性能(适合读多写少,对于数据量比较大,可以采用sharding)
MongoDB:主要解决海量数据的访问效率问题

在新浪云SAE架构一个大型Web应用到底有多简单

一般大型Web应用是指具有大流量、高并发、海量数据等特征的Web应用,
支撑此类应用,必需要一个安全、高可靠、可扩展、易维护的动态平台,才能保证应用的平稳运行。

下面我们先来聊聊,如何架构一个支撑大型Web应用的动态平台?

上图是较多大型应用采用的架构模式(实际应用中,会随着业务和需求的复杂程度,而出现更多更复杂的多层架构)

1、分布式Web服务器

如前言所述,大型应用,具有大流量、高并发的特征,一台服务器,显然无法满足需求。
以一个日均8亿PV的网站为例,根据PV我们计算出每秒的并发为1万,并发峰值是3.7万(每天80%的访问集中在20%的时间里,这20%时间叫做峰值时间),如果要保证100QPS,则至少需要400台服务器一起分担压力。
另外,大型应用业务普遍比较复杂,业务拆分是很常见的架构模式,如微博平台针对用户的行为、关系、设置等从技术架构中进行了业务拆分。

2、负载均衡系统

负载均衡和分布式Web服务器可以说是“连体婴儿”,负载均衡系统是所有请求的入口,请求到达时,根据分发策略将请求分发到健康的Web服务器节点,从而实现对请求的合理调度。
负载均衡分为硬件和软件两种。硬件负载均衡效率高,但是价格贵。软件负载均衡系统价格较低或者免费,但效率较硬件负载均衡系统低,常见的如LVS、Nginx,软硬负载均衡系统并用也是常见的均衡方式。

3、CDN、反向代理

大型应用普遍用户量都非常庞大,遍布全国各地,甚至全球,并且处于不同的网络环境。所以需要CDN,去解决跨地区、跨运营商的访问速度问题。反向代理,则是部署在应用所在机房,请求到达时,首先访问反向代理服务器,反向代理服务器将缓存的数据返回给用户,如果没有缓存数据才会继续走应用服务器获取,减少获取数据的成本。反向代理有Squid、Nginx等

4、分布式数据库系统

很多大型应用都会面临一个数据库性能瓶颈问题,海量数据如何存储?高并发情况下如果保证数据库负载问题?复杂业务逻辑如何保证数据的一致性、安全性?大流量面前如果保证查询效率?
一个大型应用,必然需要一个高可靠的、可以提供大规模并发处理的数据库体系,如此才能保证整个应用的高可靠性。
一般数据库系统都会同时使用关系型(如MySQL)数据库和非关系型(即NoSQL,如MongoDB、Redis)数据库,以满足不同的业务场景。
在分布式部署的基础上,还会采用主从架构、读写分离,主库抗写压力,通过从库来分担读压力。

5、分布式缓存系统

在海量数据、大流量、高并发面前,光有高可靠的分布式数据库系统,是远远不够的!
缓存技术是关键,在大型Web应用中使用最多且效率最高的是内存缓存,最常用的内存缓存工具是Memcached。
一个好的缓存机制,可以提高访问效率、提高服务器吞吐能力、减轻数据库系统和文件系统的访问压力。
分布式缓存系统,则可以避免单点故障,提高性能,提供高可靠性和可扩展性,巨大容量的缓存池,也可以将发生宕机时缓存的穿透率维持在一个很低的水平。

6、分布式文件系统

大规模存储,也是大型应用一大特征,如图片、视频、音乐、压缩包等等。
因此高性能的分布式存储系统对于大型应用来说是非常重要的一环。

7、代码发布系统

从 本地开发 到 生产环境(测试),再到 灰度发布,再到 全网发布,
为了满足分布式环境下程序代码的批量分发和更新,大型应用都需要一个代码发布系统和机制。

8、分布式服务器管理系统

文章开头,我们提出一个 “易维护” 概念,何谓 “易维护”?
就是能够集中式的、分组的、批量的、自动化的对所有服务器进行管理,能够批量化的执行计划任务。
常见的集中配置管理系统和软件有:puppet、Cfengine

OK!到此,我们大概地全面描述了一个支撑大型Web应用的动态平台架构。
那么问题来了,架构一个这样的动态平台,需要多少人力成本?周期?IT成本?稳定性?安全性?可靠性?

你也许看到过诸如 “如何理解云计算中的IaaS、PaaS和SaaS”、“PaaS和IaaS的区别”、“为什么选择PaaS” 等等之类的文章。
现在请先忘了那些乱七八糟的概念,这一次,我们站在实际用例的角度,看看国内领先的 PaaS 云平台SAE是如何优雅的帮你解决以上问题的!

一张图告诉你,在SAE架构一个大型Web应用到底有多简单!

如你所见,SAE用成熟稳定的技术,帮您解决了所有问题,开发者只需专注于业务本身(写自己的代码,让别人加班去吧!)

1、分布式Web服务器

分布式部署是PaaS的天然特性,自然也是SAE的一大特性,在SAE的所有应用均是分布式部署,相当于每台Web服务器上都有代码,避开单点故障问题,稳定性不言而喻。
SAE的Web服务器,相当于纯粹的代码运行环境,我们先且称之为SAE Runtime吧!
SAE通过沙箱机制,将代码、数据、连接数、内存、CPU进行了安全隔离,保证了应用的绝对安全性。
看完这篇文章,你会发现,其实SAE全平台的Web服务都是分布式的。

2、负载均衡系统

SAE的Web服务器采用分布式部署的架构,这就需要均衡每一台服务器的负载,从而保证每一个请求的访问速度。
SAE通过7层(至于为什么叫7层,可能是因为它工作在OSI 7层网络模型的第7层应用层吧)经分析后转发到负载相对较小的Web服务器上。

3、CDN、反向代理

SAE的负载均衡服务器部署在电信机房,为了保证跨运营商访问速度,SAE在各大运营商的机房都有代理,代理通过专线和电信机房连接。
SAE拥有覆盖全国各大城市的多路(电信、联通、移动、教育)骨干网络CDN节点,用户只需简单的开启操作,就能使用高质量的CDN服务。

4、分布式数据库系统

SAE提供了MySQL、NoSQL(KVDB)两种分布式数据库服务,
SAE每组MySQL都采用 一主多从加一备份 的设计,充分保证了数据库的性能,以及数据的可靠性。
KVDB是SAE开发的分布式key-value数据存储服务,用来支持公有云计算平台上的海量key-value存储。KVDB支持的存储容量很大,对每个用户支持100G的存储空间,可支持1,000,000,000条记录。
KVDB是高性能高可靠存储,读写可达10W QPS。KVDB采用一主多从的分布式架构, SAE提供热备和定期冷备,发生宕机时,会自动切换到健康的DB上。

5、分布式缓存系统

SAE Memcache,是SAE为开发者提供分布式缓存服务。SAE Memcache采用企业级规模的缓存池。巨大容量的缓存池,将发生宕机时缓存的穿透率维持在一个很低的水平。同时支持无缝扩容,domain等概念。较传统Memcache更加稳定、可靠、高效。

6、分布式文件系统

Storage是 SAE 利用自身在分布式以及网络技术方面的优势为开发者提供的安全、高效的分布式对象存储服务,支持文本、多媒体、二进制等任何类型的数据的存储。开发者可通过客户端简单的完成文件的管理操作,SAE还提供了完整的 Storage API,以满足开发者的所有应用场景。

7、代码发布系统

在SAE,通过svn或git完成代码发布。代码提交后,SAE CodeFS会自动同步到所有Web服务器。

8、分布式服务器管理系统

......
(为什么是点点点??在SAE,你可以忘记这玩意了,因为在SAE是完全免运维的,开发者不需要管理自己的服务器,一切运维都交给了SAE!)

看到这里,你会发现,在SAE,其实每一个应用都是以大型应用的标准和规格运行着!

除此以外,SAE还提供了丰富的符合开发者实际业务场景的分布式Web服务,如:
DDoS防火墙/应用防火墙、FetchURL(分布式网页抓取服务)、Cron(分布式计划任务服务)、TaskQueue(分布式任务队列服务)、Channel(实时消息推送服务)、Push(手机通知推送服务,同时支持iOS、Android)等等,因为服务较多,为不使文章篇幅太长,就不一一介绍了!

如上,便是SAE(SinaAppEngine,http://sae.sina.com.cn)的魅力所在!

10分钟完成微信公众号第三方平台全网发布

背景:在微信公众平台配置服务器URL时,使用了新浪云SAE自带的二级域名,提交时出现一个安全风险的警告,网上查了下,许多服务平台和团队也遇到同样的问题。

经过一番研究 ...

为什么会有安全风险的警告?

微信公众平台针对有一定数量的公众号设置其域名为服务器地址的所属域名,判定为是一个平台,一个第三方平台。
如,有大量的公众号服务器地址使用了SAE自带的二级域名 *.sinaapp.com 这类URL,微信就认为所属域名sinaapp.com是一个第三方平台,
然后在他们的公众号第三方平台列表中,没找到和sinaapp.com这个域名匹配的第三方平台,
于是微信公众平台就以安全风险警告的方式强制要求sinaapp.com接入公众号授权机制,成为所谓的安全合规的第三方平台。

详见《微信公众平台关于公众号第三方平台安全风险管理的公告》

如何快速接入第三方平台?

标题说10分钟完成接入,只是就技术解决方案而言,完成接入,还需要你已经注册微信开放平台并通过开发者资质认证。
根据微信开放平台提供的全网发布接入检测说明,提交全网发布时,微信服务器有个自动化测试,检测步骤如下:
1、[组件ticket正确接收]
2、[生成预授权码]
3、[获取授权code]
4、[授权]
5、[返回Api文本消息]
6、[返回普通文本消息]
7、[发送事件消息]
8、[取消授权]
实际上,创建公众号第三方平台在选择权限集时,若没有选择【客服与菜单权限】,567是不会检测的,所以可以不去实现,笔者亲测!

注:本文提供的接入方式,并非以提供服务为目的,纯粹为了通过全网发布。

一、登陆微信开放平台在管理中心创建公众号第三方平台

1、填写基本信息,这里看心情随便写点,注意平台图片大小和格式

2、选择权限集,很关键的一步,为了省事,请只选择网页服务权限,否则审核的时候会更麻烦些。

3、填写开发资料,将abc.com替换成你自己的域名,剩下的直接复制粘贴即可。

登录授权的发起页域名:abc.com
发起授权页的体验URL:http://abc.com/mpthirdparty/exp.php
授权测试公众号列表:gh_31cdcd50525e
授权事件接收URL:http://abc.com/mpthirdparty/grant.php
公众号消息校验Token:uwU5ANAtbeNfVbu
公众号消息加解密Key:avAnztwetUbepplienNf4ureppixiappwANVbliuwma
公众号消息与事件接收URL:http://abc.com/mpthirdparty/event.php?appid=/]$APPID$
网页开发域名:abc.com(如果有多个域名,英文分号隔开,最多三个)
白名单IP地址列表:220.181.136.217;220.181.136.229

二、登陆新浪云进入SAE控制台,创建应用、绑定域名、初始化共享型MySQL并导入数据、上传代码包

1、创建应用,开发语言选择PHP
2、绑定独立域名,就是在这里绑定你要接入的域名,必须是你在创建第三方平台填写的那个域名噢

3、初始化共享型MySQL,并导入数据,请将AppID、AppSecret,替换成你自己的

CREATE TABLE IF NOT EXISTS `mp_thirdparty` (
  `item` char(10) NOT NULL,
  `value` varchar(255) NOT NULL,
  `uptime` datetime NOT NULL,
  PRIMARY KEY (`item`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `mp_thirdparty` (`item`, `value`, `uptime`) VALUES
('AppID', 'wxbb151168f786ae0d', '0000-00-00 00:00:00'),
('AppSecret', '9501452d07a723db75eae9cfbfa41dd8', '0000-00-00 00:00:00'),
('token', 'uwU5ANAtbeNfVbu', '0000-00-00 00:00:00'),
('aeskey', 'avAnztwetUbepplienNf4ureppixiappwANVbliuwma', '0000-00-00 00:00:00'),
('ticket', '', '0000-00-00 00:00:00'),
('debug', '0', '0000-00-00 00:00:00');


4、上传代码,关注微信公众号:程序员到架构师,回复mp_thirdparty_code获取代码包

三、全网发布

一切准备就绪之后,就可以全网发布了!提交之后,等待人工审核就行,说是需要三个工作日,笔者提交时,三个小时就给通过了。
注:如果代码刚部署完,[组件ticket正确接收]可能会检测失败,因为微信服务器推送ticket间隔是10分钟,过几分钟再检测就行了。

微信审核通过后,用户再使用平台的URL,就不会出现风险警告了!

附件

国内外免费CDN公共JS库,前端公共库、常用JavaScript库CDN服务

做前端的开发者们经常需要用到一些公共的JS库,用户量大了JS库会消耗不少服务器资源。
为了给用户更好的访问体验,给自己网站减小服务器压力,推荐大家几个我感觉比较好的国内互联网大佬们提供的免费公共JS库。

又拍云:http://jscdn.upai.com
支持HTTPS
库有点少

七牛云:http://www.staticfile.org
库很全

百度:
静态库版:http://cdn.code.baidu.com
开发者版:http://developer.baidu.com/wiki/index.php?title=docs/cplat/libs
百度实力强大

新浪:http://lib.sinaapp.com
SAE挂掉的时候会加载不出来
支持HTTPS
库有点老

奇虎360:http://libs.useso.com
支持Google公共库、字体库直接换域名加速
用起来总是不放心

Bootstrap:http://www.bootcdn.cn
资源丰富
与又拍合作
支持HTTPS

cdnjs.net:http://cdnjs.net
支持HTTPS
国内不知谁家提供的
库很全

Google:
部分国家地区已挂,不推荐了

微软:http://www.asp.net/ajax/cdn
国内速度不错
支持HTTPS
库较少

jsDelivr:http://www.jsdelivr.com
库很全
支持HTTPS

cdnjs:https://cdnjs.com
使用CloudFlare
支持HTTPS
库很全

不怕路长,只怕心老

QQ在线,点击与我聊天

任何一颗心灵的成熟,

都必须经过寂寞的洗礼和孤独的磨炼。

QQ在线,点击与我聊天

长大,成为你自己,是件需要很大勇气的事情。

有些失望是不可避免的,

但大部分的失望,

都因为你高估了自己。

QQ在线,点击与我聊天

不要把幸福的标准定得太高,

生命中的任何一件小事只要你细心品味过,

可以说都与幸福有关。

QQ在线,点击与我聊天

很多事,

唯有当距离渐远时,

才能回首看清它。

有时我们近视,

忽略了亲情;

有时我们远视,

错过了爱情。

QQ在线,点击与我聊天

如果你不喜欢某件事,

就改变它;

如果你不能改变它,

就改变你的态度。

不要抱怨。

QQ在线,点击与我聊天

爱情是:

当感觉、热情和浪漫统统拿掉之後,

你仍然珍惜对方。

QQ在线,点击与我聊天

接受现实是克服任何不幸的第一步;

唯有面对现实,

你才能超越现实。

QQ在线,点击与我聊天

想追求什么,

就去努力吧,

就这样。

QQ在线,点击与我聊天

微笑,原谅,遗忘,

然后继续向前。

QQ在线,点击与我聊天

回归你的简单生活

简单是一种选择,不简单是一种能力,能够简单而又不简单地生活是一种坚定。

不怕路长,只怕心老。

从阳光开始的地方,收拾好心情,背起简单的行囊,开始简单的生活,简单的满足,简单的幸福,简单的感动,简单到没理由,没理由的简单。

倒流’s Bolg

为了你在乎和在乎你的人,你必须足够爱自己,充满阳光

倒流’s Bolg

云淡风轻的日子里,一箪食、一瓢饮足矣。享受清晨这一刻咖啡,阅读,感受简单生活中的幸福!
然后,开始你一天最爱的工作。

早睡,第二天的你,肯定是满满的精气神、满满的正能量。

周末,约上你的闺密或朋友,关掉手机,一起咖啡馆闲聊、打台球、看电影、逛街、吃各种美食、野外烧烤、小派对、在日落东单看街头篮球夜赛。

倒流’s Bolg

跑步、游泳、冲浪、骑马、舞蹈、跆拳道、羽毛球……
所有你能想到的运动,你都可以去尝试。
享受一个人、一群人的运动时光!

去不同的地方走走看看,旅行、拍照和笑容一个都不能少。

倒流’s Bolg

记得把自己的房间收拾的干干净净,
和你爸妈一起视频,讲你最开心的事,
和你喜欢的人,一起听你们喜欢的音乐,
K厅、酒吧,或许是你生活的调味剂,不开心时,不妨约上几个朋友,一起去那里嗨皮吧。

都说化妆是一种礼貌,也有一种美丽,叫素颜,其实最好的保养品就是你的笑容。
愿你每天都能笑的没心没肺、阳光灿烂, 成为一个明媚的女子,简单而快乐、美丽而安静、优雅而从容,然后有一天,可以笑着讲述让你哭的瞬间。

JS实现完美身份证号有效性验证

根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
出生日期码表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。
顺序码表示同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。顺序码的奇数分给男性,偶数分给女性。
校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。

出生日期计算方法。
15位的身份证编码首先把出生年扩展为4位,简单的就是增加一个19或18,这样就包含了所有1800-1999年出生的人;
2000年后出生的肯定都是18位的了没有这个烦恼,至于1800年前出生的,那啥那时应该还没身份证号这个东东,⊙﹏⊙b汗...
下面是正则表达式:

出生日期1800-2099 (18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])
身份证正则表达式 /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i
15位校验规则 6位地址编码+6位出生日期+3位顺序号
18位校验规则 6位地址编码+8位出生日期+3位顺序号+1位校验位

校验位规则

公式:∑(ai×Wi)(mod 11)……………………………………(1)
公式(1)中:
i----表示号码字符从由至左包括校验码在内的位置序号;
ai----表示第i位置上的号码字符值;
Wi----示第i位置上的加权因子,其数值依据公式Wi=2^(n-1)(mod 11)计算得出。
i 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1

校验身份证号函数
//身份证号合法性验证 
//支持15位和18位身份证号
//支持地址编码、出生日期、校验位验证
function IdentityCodeValid(code) { 
    var city={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北 ",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏 ",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外 "};
    var tip = "";
    var pass= true;
    if(!code || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)){
        tip = "身份证号格式错误";
        pass = false;
    } else if(!city[code.substr(0,2)]){
        tip = "地址编码错误";
        pass = false;
    } else {
        //18位身份证需要验证最后一位校验位
        if(code.length == 18){
            code = code.split('');
            //∑(ai×Wi)(mod 11)
            //加权因子
            var factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ];
            //校验位
            var parity = [ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ];
            var sum = 0;
            var ai = 0;
            var wi = 0;
            for (var i = 0; i < 17; i++) {
                ai = code[i];
                wi = factor[i];
                sum += ai * wi;
            }
            var last = parity[sum % 11];
            if(parity[sum % 11] != code[17]){
                tip = "校验位错误";
                pass =false;
            }
        }
    }
    if(!pass) alert(tip);
     return pass;
}
测试
var c = '130981199312253466';
var res= IdentityCodeValid(c);
alert(res);

隐藏字符串中部分字符的PHP函数,如:姓名、用户名、身份证、IP、手机号等

<?php
/**
 * 将一个字符串部分字符用$re替代隐藏
 * @param string    $string   待处理的字符串
 * @param int       $start    规定在字符串的何处开始,
 *                            正数 - 在字符串的指定位置开始
 *                            负数 - 在从字符串结尾的指定位置开始
 *                            0 - 在字符串中的第一个字符处开始
 * @param int       $length   可选。规定要隐藏的字符串长度。默认是直到字符串的结尾。
 *                            正数 - 从 start 参数所在的位置隐藏
 *                            负数 - 从字符串末端隐藏
 * @param string    $re       替代符
 * @return string   处理后的字符串
 */
function hidestr($string, $start = 0, $length = 0, $re = '*') {
    if (empty($string)) return false;
    $strarr = array();
    $mb_strlen = mb_strlen($string);
    while ($mb_strlen) {
        $strarr[] = mb_substr($string, 0, 1, 'utf8');
        $string = mb_substr($string, 1, $mb_strlen, 'utf8');
        $mb_strlen = mb_strlen($string);
    }
    $strlen = count($strarr);
    $begin  = $start >= 0 ? $start : ($strlen - abs($start));
    $end    = $last   = $strlen - 1;
    if ($length > 0) {
        $end  = $begin + $length - 1;
    } elseif ($length < 0) {
        $end -= abs($length);
    }
    for ($i=$begin; $i<=$end; $i++) {
        $strarr[$i] = $re;
    }
    if ($begin >= $end || $begin >= $last || $end > $last) return false;
    return implode('', $strarr);
}

测试:
//隐藏手机号中间4位
hidestr('18600005940', 3, 4); //186****5940

//只保留姓名里的最后一个字,常见与ATM,网银等
hidestr('云厉', 0, -1); //*厉

//隐藏邮箱部分内容,常见网站帐号,如支付宝等
list($name, $domain) = explode('@', '979137@qq.com');
hidestr($name, 1, -1) . '@' . hidestr($domain, 0, 2); // 9****7@**.com

此函数用法和PHP系统函数函数substr原理和用法是一样的。只不过substr是用于截取你想要的字符串,而hidestr是隐藏你想要的字符串,用*号代替

如何保存一个网页至桌面上成为快捷方式,PHP生成桌面快捷方式

PHP生成桌面快捷方式,最核心就是通过header函数设置头部信息!

<?php
header("Content-Type: application/octet-stream; charset=utf8");
header("Content-Disposition: attachment; filename=云厉的博客.url");
$shortcut = array(
    '[InternetShortcut]',
    //链接地址
    'URL=979137.com',
    'IDList=',
    //ICON文件地址,必须是HTTP绝对地址
    'IconFile=(http://cdn.979137.com/favicon.ico)',
    'IconIndex=1',
    //注册表值
    '[{000214A0-0000-0000-C000-000000000046}]',
    'Prop3=19,2',
);
echo implode(PHP_EOL, $shortcut);

微信公众号:程序员到架构师

最新文章

Return Top