风吹走了我

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的使用及生成方式说明:

 

  1. 为了保密appsecrect,第三方需要一个access_token获取和刷新的中控服务器。而其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则会造成access_token覆盖而影响业务;
  2. 目前access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器对外输出的依然是老access_token,此时公众平台后台会保证在刷新短时间内,新老access_token都可用,这保证了第三方业务的平滑过渡;
  3. 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"/>

PHP利用showmycode在线解密Zend加密的文件

PHP利用showmycode在线解密Zend加密的文件

 

 /**
     * 在线解密Zend加密
     * @author jakehu
     * @date   2014-06-10
     */
header("Content-Type: text/html; charset=utf-8");
if (@$_REQUEST['action']=='bomp') {
    if ($_FILES["file"]){      
        move_uploaded_file($_FILES["file"]["tmp_name"],"temp/" . $_FILES["file"]["name"]);
        $path = "temp/" . $_FILES["file"]["name"];
    }
 
    $decodingurl = $_REQUEST['decodingurl'];
    $captcha = $_REQUEST['captcha'];
    $cookies = $_REQUEST['cookies'];
    $query['MAX_FILE_SIZE'] = 2097152;
    $query['decodingurl'] = $decodingurl;
    $query['upload'] = '@'.dirname(__FILE__).'/'.$path;
    $query['captcha'] = $captcha;
    
    $url = 'http://www.showmycode.com/';
    $ch = curl_init ();
    curl_setopt ( $ch, CURLOPT_URL, $url );
    curl_setopt ( $ch, CURLOPT_HEADER, 0 );
    curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
    curl_setopt(  $ch, CURLOPT_REFERER, "http://www.showmycode.com");
    curl_setopt ( $ch, CURLOPT_POST, 1 );
    curl_setopt ( $ch, CURLOPT_POSTFIELDS, $query );
    curl_setopt ( $ch, CURLOPT_COOKIE, $cookies );
    $result = curl_exec ( $ch ); // 
    curl_close ( $ch );
    
    $result = explode('', $result);
    $result = explode('', $result[1]);   
    
    echo $result[0].', Here is the result:';
      
    $url = 'http://www.showmycode.com/?download';
    $ch = curl_init ();
    curl_setopt ( $ch, CURLOPT_URL, $url );
    curl_setopt ( $ch, CURLOPT_HEADER, 0 );
    curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
    curl_setopt(  $ch, CURLOPT_REFERER, "http://www.showmycode.com");
    curl_setopt ( $ch, CURLOPT_COOKIE, $cookies );
    $result = curl_exec ( $ch ); //
    curl_close ( $ch );
 
    echo "";
    //因博客代码高亮问题注释显示(使用时请打开上面注释)
    exit();
}
$url = "http://www.showmycode.com/?c";
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_HEADER, 1 );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt(  $ch, CURLOPT_REFERER, "http://www.showmycode.com");
curl_setopt ( $ch, CURLOPT_POST, 0 );
$result = curl_exec ( $ch ); // 
curl_close ( $ch );
 
list ( $header1, $body ) = explode ( "rnrn", $result );
preg_match_all ( '/set-cookie:([^;]*)/i', $header1, $matches );
echo "";
//因博客代码高亮问题注释显示(使用时请打开上面注释)
$cookies = trim($matches[1][1]);
echo "";
echo "action:";
echo "cookies:";
echo "file:";
echo "decodingurl:";
echo "captcha:";
echo "";
echo "";
echo "";