命令行:
wget –mirror -p –convert-links -P [本地路径] [要扒的网址]
Mac安装pyenv和pyenv-virtualenv
简介
pyenv:
说明: 轻量的Python版本管理器,帮助你在一台机子上建立多个版本的python环境,并提供方便的切换方法。
GitHub: https://github.com/yyuu/pyenv
pyenv-virtualenv:
说明: pyenv的扩展工具,可以搭建虚拟且独立的python环境,可以使每个项目环境与其他项目独立开来,保持环境的干净,解决包冲突问题。
GitHub: https://github.com/yyuu/pyenv-virtualenv
Mac安装
1、安装Xcode Command Line Tools
xcode-select --install
2、安装Homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
3、可选安装
brew install openssl readline xz
4、brew安装pyenv
brew update
brew install pyenv
echo 'eval "$(pyenv init -)"' >> ~/.zshrc
5、安装pyenv-virtualenv
git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv
6、virtualenvs的自动激活
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.zshrc
7、重新启动shell,以使路径更改生效
exec $SHELL
source ~/.zshrc
命令使用
pyenv命令集:
pyenv install --list
查询所有可以安装的版本
pyenv install 2.7.14
安装所需的版本
pyenv uninstall
卸载特定的Python版本。
pyenv version
显示当前活动的Python版本
pyenv global 2.7.14
Python的全局设置,整个系统生效
pyenv global 2.7.14
Python的局部设置,当前目录生效
pyenv local --unset
取消设置
更多参考GitHub...
pyenv-virtualenv命令集:
pyenv virtualenv 2.7.14 venv2714
制定版本创建virtualenv
pyenv virtualenvs
列出现有virtualenvs
pyenv activate virtualenv的名称
激活pyenv virtualenv
pyenv deactivate
停用pyenv virtualenv
pyenv uninstall my-virtual-env
删除现有virtualenv
更多参考GitHub...
参考
Mac OSX python多版本管理工具:pyenv 和 virtualenv搭建
Python版本管理
Centos7 最小安装
Centos7 最小安装
1.ifconfig
yum install net-tools
[它提供 ifconfig 工具,如果你不习惯 ip 命令,还可以使用它]
ifconfig
2.设置服务器的主机名称
hostnamectl set-hostname mini
echo $HOSTNAME
[检查主机名]
[root@mini ~]# echo $HOSTNAME
mini
3.更新或升级最小化安装的 CentOS
yum update -y
4.关闭SELINUX
sestatus
[查看selinux状态]
vi /etc/selinux/config
SELINUX=disabled
重启生效
5.设置静态IP地址
vi /etc/sysconfig/network-scripts/ifcfg-eno16777736
BOOTPROTO=”static”
IPADDR=”192.168.1.101″
NETMASK=”255.255.255.0″
NM_CONTROLLED=”no”
ONBOOT=”yes”
“NM_CONTROLLED=no”表示该接口将通过该配置文件进行设置,而不是通过网络管理器进行管理。“ONBOOT=yes”告诉我们,系统将在启动时开启该接口
重启网络服务
systemctl restart network.service
验证接口是否配置正确
ip add
因为我的DNS没有设置所以导致了ping外网ping不通
vi /etc/resolv.conf
search localdomain
nameserver 8.8.8.8
nameserver 114.114.114.114
service network restart
ping -c 3 www.baidu.com
[测试]
6.修改ssh端口
修改端口
vi /etc/ssh/sshd_config
修改去掉port前面注释,修改port值为21622
使用密钥登陆
mkdir ~/.ssh
chmod 755 ~/.ssh
vi ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
vi /etc/ssh/sshd_config
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile
.ssh/authorized_keys
禁止密码登陆
vi /etc/ssh/sshd_config
PasswordAuthentication no
重启ssh
service sshd restart
6.安装iptables
首先要停止 firewalld 服务
systemctl stop firewalld.service
禁止 firewalld 服务在系统启动的时候自动启动
systemctl disable firewalld.server
安装iptables 包
yum install iptables-services -y
设置iptables 防火墙服务开机自动启动
systemctl enable iptables
修改iptables配置
查看状态
service iptables status
查看规则
iptables -L -n
清除默认规则
iptables -F
iptables -X
iptables -Z
建立新的规则
允许本地回环 127.0.0.1
iptables -A INPUT -i lo -p all -j ACCEPT
允许已经建立的所有连接
iptables -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
允许内网的所有连接
iptables -A INPUT -s 10.0.0.0/8 -j ACCEPT
允许所有向外发起的连接
iptables -A OUTPUT -j ACCEPT
拒绝 ping 可选
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j REJECT
允许 SSH 服务端口(一定要打开,不然就不能ssh了)
iptables -A INPUT -p tcp --dport 21622 -j ACCEPT
允许 Web 服务端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
允许 https 服务端口
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
允许返回数据给所有ip所有端口 允许所有本机向外的访问
iptables -A OUTPUT -j ACCEPT
除上面允许的规则,抛弃所有INPUT请求 (注意:如果22端口未加入允许规则,SSH链接会直接断开。)
iptables -P INPUT DROP
除上面允许的规则,抛弃所有FORWARD请求
iptables -P FORWARD DROP
除上面允许的规则,抛弃所有OUTPUT请求
iptables -P OUTPUT DROP
保存(ArchLinux系统下的路径可能和其他系统下的路径不同)
sudo service iptables save
重新启动
sudo service iptables restart
列出规则,供查看
iptables -L -n
7.更新yum源
安装wget
yum install wget -y
备份一下源
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
转到源目录,按照自己的版本下载源
cd /etc/yum.repos.d/
wget http://mirrors.163.com/.help/CentOS7-Base-163.repo
运行以下命令生成缓存:
yum clean all
yum makecache
8.安装 GCC (GNU 编译器集)
yum install gcc -y
gcc --version
[root@mini yum.repos.d]# gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)
Copyright © 2015 Free Software Foundation, Inc.
本程序是自由软件;请参看源代码的版权声明。本软件没有任何担保;
包括没有适销性和某一专用目的下的适用性担保。
9.安装 7-zip 工具(压缩和解压所有已知类型文件的工具)
yum install p7zip -y
php获取客户端的操作系统类型
function
get_os(){
$os
=
''
;
$Agent
=
$_SERVER
[
'HTTP_USER_AGENT'
];
if
(
eregi
(
'win'
,
$Agent
)&&
strpos
(
$Agent
,
'95'
)){
$os
=
'Windows 95'
;
}
elseif
(
eregi
(
'win 9x'
,
$Agent
)&&
strpos
(
$Agent
,
'4.90'
)){
$os
=
'Windows ME'
;
}
elseif
(
eregi
(
'win'
,
$Agent
)&&
ereg
(
'98'
,
$Agent
)){
$os
=
'Windows 98'
;
}
elseif
(
eregi
(
'win'
,
$Agent
)&&
eregi
(
'nt 5.0'
,
$Agent
)){
$os
=
'Windows 2000'
;
}
elseif
(
eregi
(
'win'
,
$Agent
)&&
eregi
(
'nt 6.0'
,
$Agent
)){
$os
=
'Windows Vista'
;
}
elseif
(
eregi
(
'win'
,
$Agent
)&&
eregi
(
'nt 6.1'
,
$Agent
)){
$os
=
'Windows 7'
;
}
elseif
(
eregi
(
'win'
,
$Agent
)&&
eregi
(
'nt 5.1'
,
$Agent
)){
$os
=
'Windows XP'
;
}
elseif
(
eregi
(
'win'
,
$Agent
)&&
eregi
(
'nt'
,
$Agent
)){
$os
=
'Windows NT'
;
}
elseif
(
eregi
(
'win'
,
$Agent
)&&
ereg
(
'32'
,
$Agent
)){
$os
=
'Windows 32'
;
}
elseif
(
eregi
(
'linux'
,
$Agent
)){
$os
=
'Linux'
;
}
elseif
(
eregi
(
'unix'
,
$Agent
)){
$os
=
'Unix'
;
}
else
if
(
eregi
(
'sun'
,
$Agent
)&&
eregi
(
'os'
,
$Agent
)){
$os
=
'SunOS'
;
}
elseif
(
eregi
(
'ibm'
,
$Agent
)&&
eregi
(
'os'
,
$Agent
)){
$os
=
'IBM OS/2'
;
}
elseif
(
eregi
(
'Mac'
,
$Agent
)&&
eregi
(
'PC'
,
$Agent
)){
$os
=
'Macintosh'
;
}
elseif
(
eregi
(
'PowerPC'
,
$Agent
)){
$os
=
'PowerPC'
;
}
elseif
(
eregi
(
'AIX'
,
$Agent
)){
$os
=
'AIX'
;
}
elseif
(
eregi
(
'HPUX'
,
$Agent
)){
$os
=
'HPUX'
;
}
elseif
(
eregi
(
'NetBSD'
,
$Agent
)){
$os
=
'NetBSD'
;
}
elseif
(
eregi
(
'BSD'
,
$Agent
)){
$os
=
'BSD'
;
}
elseif
(
ereg
(
'OSF1'
,
$Agent
)){
$os
=
'OSF1'
;
}
elseif
(
ereg
(
'IRIX'
,
$Agent
)){
$os
=
'IRIX'
;
}
elseif
(
eregi
(
'FreeBSD'
,
$Agent
)){
$os
=
'FreeBSD'
;
}
elseif
(
$os
==
''
){
$os
=
'Unknown'
;
}
return
$os
;
}
微擎数据库操作相关函数文档说明
微擎系统数据库操作使用 PDO 兼容方式, 系统已对 PDO 兼容性进行检测及封装. 请使用以下函数进行数据库操作. 所有数据库操作均不进行错误提示, 如果要进行错误调试, 请在系统中配置为开发模式, 然后调用 pdo_debug 方法进行错误输出.
tablename – 转义数据表名
string tablename(string $table)
说明: 获取原始的数据表名, 微擎系统按照惯例在所有的表名增加了前缀来增强兼容性. 使用 tablename 函数, 方便将业务数据表名转换为原始的数据表名来进行数据库操作.
返回: 原始表名, 可以直接用于数据库查询操作
pdo – 初始化 pdo 对象实例
PDO pdo(bool $newinstance = false)
说明: 获取 pdo 对象实例, pdo 函数默认使用缓存起来的 PDO 对象, 可通过 $_W['pdo'] 或 $GLOBALS['pdo'] 方式直接获取默认的 PDO 对象. 如果要使用新的 PDO 实例, 请将 $newinstance 参数设置为 true
参数: $newinstance 是否要创建新实例
返回: PDO 对象
pdo_query – 执行一条非查询语句
int|bool pdo_query(string $sql, array $params = array())
说明: 执行一条非查询语句, 返回受影响的行数
参数:
$sql 要进行查询的语句, 其中可以包括查询绑定参数
$params 要绑定的参数集合
返回: 如果执行成功返回受影响的记录数, 失败将返回 false
pdo_insert – 执行一条数据插入
int|bool pdo_insert(string $table, array $data = array(), bool $replace = false)
说明: 对某条数据表插入一条新纪录
参数:
$table 指明要操作的数据表
$data 要插入的数据记录, 格式为与数据表字段对应的关联数组
$replace 指明插入方式使用 INSERT 语句或是 REPLACE 语句(区别请参阅MySQL手册)
返回: 如果执行成功返回受影响的记录数(一般为数字 1), 失败将返回 false
pdo_insertid – 获取上次插入的自增数字主键
int pdo_insertid()
说明: 获得最后一次插入的自增数字主键
返回: 成功将返回数字主键, 失败将返回 0. 使用此函数时, 请注意保证 PDO 实例正确. 只有使用默认实例才有效.
pdo_delete – 删除记录
int|bool pdo_delete(string $table, array $filter = array(), string $gule = 'AND')
说明: 对某条数据表删除纪录
参数:
$table 指明要操作的数据表
$filter 删除时要删选的条件数据, 格式为与数据表字段对应的关联数组
$gule 指明筛选条件的组合方式, 有效值为 AND(代表所有条件均需满足), OR(其中一种条件满足)
返回: 如果执行成功返回受影响的记录数(删除成功的行数), 失败将返回 false
pdo_update – 执行数据更新
int|bool pdo_update(string $table, array $data = array(), array $filter = array(), string $gule = 'AND')
说明: 对某条数据表更新特定纪录
参数:
$table 指明要操作的数据表
$data 要更新的数据记录, 格式为与数据表字段对应的关联数组
$filter 删除时要更新的条件数据, 格式为与数据表字段对应的关联数组
$gule 指明筛选条件的组合方式, 有效值为 AND(代表所有条件均需满足), OR(其中一种条件满足)
返回: 如果执行成功返回受影响的记录数, 失败将返回 false. 如果数据无变动将会返回数字 0, 注意与错误返回值 false 区别.
pdo_fetchcolumn – 查询 SQL 语句并获得首行指定列的值
mixed|bool pdo_fetchcolumn(string $sql, array $params = array(), int $column = 0)
说明: 执行制定的查询语句, 返回首行指定列的值, 默认返回首行首列
参数:
$sql 要进行查询的语句, 其中可以包括查询绑定参数
$params 要绑定的参数集合
$column 要返回的列
返回: 如果执行成功将返回查询出来的数据结果首行指定列的值, 如果执行失败或指定的列无效将返回bool值 false
pdo_fetch – 按照 SQL 语句查询一条记录
array|bool pdo_fetch(string $sql, array $params = array())
说明: 按照语句及绑定参数获取一条记录, 绑定参数部分请参阅PHP手册 PDO部分
参数:
$sql 要进行查询的语句, 其中可以包括查询绑定参数
$params 要绑定的参数集合
返回: 如果执行成功将返回查询出来的数据结果(关联数组结构, 格式与查询结果结构相同), 如果执行失败将返回bool值 false
pdo_fetchall – 按照 SQL 语句查询所有记录
array|bool pdo_fetch(string $sql, array $params = array(), string $keyfiled此 = '')
说明: 按照语句及绑定参数获取一条记录, 绑定参数部分请参阅PHP手册 PDO部分
参数:
$sql 要进行查询的语句, 其中可以包括查询绑定参数
$params 要绑定的参数集合
$keyfield 返回的数据结果将以此字段的值为键名呈现为关联数组
返回: 如果执行成功将返回查询出来的数据结果(关联数组结构, 格式与查询结果结构相同), 如果执行失败将返回bool值 false
pdo_debug – 获取数据库操作记录列表
array pdo_debug(bool $output = true, array $append = array())
说明: 获取本次请求周期内所有的数据库操作记录, 也可以用来记录操作记录. 这个函数只有将系统配置中设置为开发模式才会生效
参数:
$output 如果传递 true, 将会直接使用 print_r 打印所有操作记录; 如果传递 false, 则不会打印操作记录, 仅通过返回值返回
$append 用于记录操作记录, 开发者通常不需要使用这个参数
返回: 返回本次请求生命周期内所有的操作记录
PHP开发微信公众号 应用access_token缓存
在做微信开发时access_token是不可避免的,很多微信接口都需要access_token,这里我就分享一下在web开发中使用PHP如何获取access_token,并写入缓存文件。
首先看看微信官方文档的说明。
access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
公众平台的API调用所需的access_token的使用及生成方式说明:
- 为了保密appsecrect,第三方需要一个access_token获取和刷新的中控服务器。而其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则会造成access_token覆盖而影响业务;
- 目前access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器对外输出的依然是老access_token,此时公众平台后台会保证在刷新短时间内,新老access_token都可用,这保证了第三方业务的平滑过渡;
- access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程。
公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在微信公众平台官网-开发者中心页中获得(需要已经成为开发者,且帐号没有异常状态)。注意调用所有微信接口时均需使用https协议。
接口调用请求说明
http请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
grant_type | 是 | 获取access_token填写client_credential |
appid | 是 | 第三方用户唯一凭证 |
secret | 是 | 第三方用户唯一凭证密钥,即appsecret |
返回说明
正常情况下,微信会返回下述JSON数据包给公众号:
{“access_token”:”ACCESS_TOKEN”,”expires_in”:7200}
参数 | 说明 |
---|---|
access_token | 获取到的凭证 |
expires_in | 凭证有效时间,单位:秒 |
错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):
{“errcode”:40013,”errmsg”:”invalid appid”}
接下来就上PHP的具体实现方式。
access_token是通过get方式的来取的,所以我们要构建一下curl_get函数,以获取返回结果
function curlGet($url){
$ch = curl_init();
$header = “Accept-Charset: utf-8”;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, “GET”);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_USERAGENT, ‘Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)’);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$temp = curl_exec($ch);
return $temp;
}
PHP代码
/**********获取access_token(基础版)***************/
function getAccessToken($appid,$appsecret){
$url_get=’https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=’.$appid.’&secret=’.$appsecret;
$json=$this->json_decode(curlGet($url_get));
$access_token=$json->access_token
;}
由于asscess_token的过期时间只有7200秒,而接口调用次数是有限制的,所有我们可以把获取asscess_token的函数改进一下,把它存进数据库,然后再进行过期判断。
- 如果asscess_token还未过期,则直接调用;
- 如果已过期则获取asscess_token并更新数据库,以务下次使用;
function checkAccessToken($appid,$appsecret){
$condition = array(‘appid’=>$appid,’appsecret’=>$appsecret);
$access_token_set=M(‘AccessToken’)->where($condition)->find();//获取数据
if($access_token_set){
//检查是否超时,超时了重新获取
if($access_token_set[‘AccessExpires’]>time()){
//未超时,直接返回access_token
return $access_token_set[‘access_token’];
}else{
//已超时,重新获取
$url_get=’https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=’.$appid.’&secret=’.$appsecret;
$json=json_decode(curlGet($url_get));
$access_token=$json->access_token;
$AccessExpires=time()+intval($json->expires_in);
$data[‘access_token’]=$access_token;
$data[‘AccessExpires’]=$AccessExpires;
$result = M(‘AccessToken’)->where($condition)->save($data);//更新数据
if($result){
return $access_token;
}else{
return $access_token;
}
}
}else{
/*数据库中无$appid,$appsecret对应的记录需要再做处理,如插入到数据库
return 0;*/
}
}
TP3.2 的include如何引用common模块下的view
TP3.2 的include如何引用common模块下的view文件下的html文件作为公用文件
我在home模块引用这么写<include file=”Public/head”/>调用的却是Home模块下的head.html文件,如何用<include file=”Public/head”/>引用Common模块下的View下的head.html呢。求助。
<include file="Common@Public/head"/>
Thinkphp在Tpl中调用common.php中的公共函数
Common/common.php
//产生随机验证码 function random($length, $chars = '0123456789') { //随机生成的逻辑 return $hash; }
Tpl/index.html
{:random(5)}
得到的结果:9536
PHP根据数组某个键值相同合并数组
有时候我们需要将两个数组合并,并且将某些键值再次合并成一个数组。
想了很多方法,都不理想,最后百度看了一个不错的方法,在这里分享给大家。
<?php $a=array( array("username"=>"piaoyudesi","email"=>"piaoyudesi@163.com","address"=>"shenzhen","item_id"=>"10058","item_title"=>"BPS8"), array("username"=>"huakai","email"=>"huakai@163.com","address"=>"zhongshan","item_id"=>"10087","item_title"=>"BPS9"), array("username"=>"huakai","email"=>"huakai@163.com","address"=>"zhongshan","item_id"=>"10047","item_title"=>"BPS10"), array("username"=>"piaoyudesi","email"=>"piaoyudesi@163.com","address"=>"shenzhen","item_id"=>"10042","item_title"=>"BPS10"), array("username"=>"jimowenxin","email"=>"jimowenxin@163.com","address"=>"zhuhai","item_id"=>"10031","item_title"=>"BPS18") ); $u=array(); foreach($a as $k=>&$e){ $name=&$e['username']; if(!isset($u[$name])){ $u[$name]=$e; unset($u[$name]['item_id'],$u[$name]['item_title']); } $u[$name]['goods'][]=array('item_id'=>$e['item_id'],'item_title'=>$e['item_title']); } $a=array_values($u); unset($u); print_r($a); ========= Array ( [0] => Array ( [username] => piaoyudesi [email] => piaoyudesi@163.com [address] => shenzhen [goods] => Array ( [0] => Array ( [item_id] => 10058 [item_title] => BPS8 ) [1] => Array ( [item_id] => 10042 [item_title] => BPS10 ) ) ) [1] => Array ( [username] => huakai [email] => huakai@163.com [address] => zhongshan [goods] => Array ( [0] => Array ( [item_id] => 10087 [item_title] => BPS9 ) [1] => Array ( [item_id] => 10047 [item_title] => BPS10 ) ) ) [2] => Array ( [username] => jimowenxin [email] => jimowenxin@163.com [address] => zhuhai [goods] => Array ( [0] => Array ( [item_id] => 10031 [item_title] => BPS18 ) ) ) )