【YII2】操作redis(自己写类)

Continue Read..

先在web.php 里面加载redis

 'redis'=>[

            'class'=>'app\models\Redis',

            'hostname'=>'127.0.0.1',

            'port'=>6379,

            'database'=>15,      

        ],

 

然后在/model/里面写一个Redis.php文件

<?php

namespace app\models;

 

use Yii;

use yii\base\Model;

 

class Redis extends Model {

 

public  $hostname = "127.0.0.1";

 

public $port = "6379";

 

public $database = "0";

 

public $redis;

 

public function init() {

$redis = new \Redis();

$result = $redis->connect($this->hostname, $this->port);

if (empty($result)) {

die("connect redis error");

}

$redis->select($this->database);

$this->redis = $redis;

}

 

/**

* 设置redis缓存  字符串/哈希

* @param [string] $name

*         [键名]

* @param [string|array] $value

*         [缓存的数据]

* @param [int]   $cacheTimeOut [过期时间/单位秒]     

*/

function setStringOrHash($name, $value, $cacheTimeOut = 0) {

if (is_string($value)) {

$this->redis->set($name, $value);

} elseif (is_array($value)) {

$this->redis->hmset($name, $value);

}

if ($cacheTimeOut > 0) {

$this->redis->expire($name, $cacheTimeOut);

}

}

/*

* 设置redis 缓存  列表

* $key  string 键值

* $val  string 值

* $push  string 方位  默认 l

* $cacheTimeOut int  过期时间  /单位秒

*/

function setList($key,$val,$push="l",$cacheTimeOut=0){

if($push == "l"){

$this->redis->lPush($key, $val);

}else{

$this->redis->rPush($key, $val);

}

if ($cacheTimeOut > 0) {

$this->redis->expire($key, $cacheTimeOut);

}

}

/**

* @param [string] $key [键名]

* none(key不存在) int(0)

string(字符串) int(1)

set(集合) int(2)

list(列表) int(3)

zset(有序集) int(4)

hash(哈希表) int(5)

* return string|array

*/

function getRedis($key,$pop="l"){

$type = $this->redis->type($key);

switch ($type){

case 1 :

return $this->redis->get($key);

break;

case 3 :

if($pop == "l"){

return $this->redis->lPop($key);

}else{

return $this->redis->rPop($key);

}

break;

case 5 :

return $this->redis->hGetAll($key);

break;

default:return '';break;

}

}

}

 

 

最后在控制器里面调用

public function actionRedis(){

// $Redis = new Redis();

$key = "hx";

// $val = array(

// "k1"=>"v1",

// "k2"=>"v2",

// "k3"=>"v3",

// "k4"=>"v4"

// );

 

// $key = "str";

// $val = "str";

// Yii::$app->redis->setStringOrHash($key,$val);

var_dump(Yii::$app->redis->getRedis($key));die;

 

$key="list";

$val = ["id"=>1,"name"=>"cuzn","time"=>time()];

Yii::$app->redis->setList($key,json_encode($val));

$rpop = Yii::$app->redis->getRedis($key,"r");

var_dump($rpop);

Yii::$app->redis->setList("list1",$rpop,"r");

}

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

php 清除不可见字符

Continue Read..

最近碰到调用别人的接口,json_decode无法解出的情况,

是因为里面存在了不可见字符,

在stackoverflow找到一个讨论页

http://stackoverflow.com/questions/1176904/php-how-to-remove-all-non-printable-characters-in-a-string

 

大部分答案只考虑了英文系的场景,去掉了所有非asc字符,中文也被过滤了

下面有个答案则考虑了所有语音兼容,记录下函数

function clean_string($string) {
  $s = trim($string);
  $s = iconv("UTF-8", "UTF-8//IGNORE", $s); // drop all non utf-8 characters

  // this is some bad utf-8 byte sequence that makes mysql complain - control and formatting i think
  $s = preg_replace('/(?>[\x00-\x1F]|\xC2[\x80-\x9F]|\xE2[\x80-\x8F]{2}|\xE2\x80[\xA4-\xA8]|\xE2\x81[\x9F-\xAF])/', ' ', $s);

  $s = preg_replace('/\s+/', ' ', $s); // reduce all multiple whitespace to a single space

  return $s;
}

 

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

php中 50w ip 解析ip地址

Continue Read..

php中 50w ip 解析ip地址,在图形展示省份用户数据时使用

50w的ip数组大概占用内存80mb, 在实际使用过程中,从数据库取出ip数据,再加上其他变量使用的内存,就可有可能超出php默认的内存限制128mb了。

由于一下从mysql中取50w ip出来,默认情况下都会脚本报错,所以一般是分多次取。

解析省份信息用ipip.net的库,

50w ip解析大约10-50秒,92mb内存占用,其中80mb是ip数组的占用

代码如下

<?php
include './IP.class.php';
$re = [];
echo convert(memory_get_usage(true)).PHP_EOL;
$s = time();

for ($j=0; $j < 50; $j++) { 

	for ($i=0; $i <10000 ; $i++) { 
		$ipArr[] = '218.'.mt_rand(20,254).'.'.mt_rand(100,254).'.'.mt_rand(100,254);
	}

	for ($k=0; $k < 10000; $k++) { 
		$ipInfo = ip::find($ipArr[$k]);
		$re_tmp[] = $ipInfo[1];
	}

	$re_tmp_count = array_count_values($re_tmp);
	foreach ($re_tmp_count as $k => $v) {
		if(in_array($k, $re)){
			$re[$k] += $v;
		}else{
			$re[$k] = $v;
		}
	}

	//unset($ipArr);//打开内存变为500MB左右。。。
	unset($re_tmp);
}

var_dump($re);
echo time()-$s.PHP_EOL;
echo convert(memory_get_usage(true)).PHP_EOL;

function convert($size)
{
    $unit=array('b','kb','mb','gb','tb','pb');
    return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

【PHP】验证码

Continue Read..
function yzm(){
   Yii::$app->session->set("authnum","");
   //生成验证码图片
   $im = imagecreate(78,30);
   $back = ImageColorAllocate($im, 245,245,245);
   imagefill($im,0,0,$back); //背景
   
   srand((double)microtime()*1000000);
   $vcodes = "";
   //生成4位数字
   for($i=0;$i<4;$i++)
   {
   $font = ImageColorAllocate($im, rand(100,255),rand(0,100),rand(100,255));
   $authnum=rand(1,9);
   $vcodes.=$authnum;
   imagestring($im, 9, 10+$i*10, 10, $authnum, $font);
   }
   Yii::$app->session->set("authnum",$vcodes);
   
   for($i=0;$i<100;$i++) //加入干扰象素
   {
   $randcolor = ImageColorallocate($im,rand(0,255),rand(0,255),rand(0,255));
   imagesetpixel($im, rand()%70 , rand()%30 , $randcolor);
   }
   ob_clean();
   Header("Content-type: image/PNG");
    ImagePNG($im);
    ImageDestroy($im);
}

 

$code = strtolower($request->post('code'));

       if(Yii::$app->session->get("authnum") != $code){

           $url = "/login/index";

           $My_fun->ShowMessage("验证码不正确",$url);die;

       }

 

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

【PHP】根据IP获取地理位置(含数据包)

Continue Read..

打包插件了  里面有详细运行代码   可以单独返回 国家,省份,城市等 比纯真好用

 

http://www.ipip.net

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

【CSS】修改file样式

Continue Read..
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
<title>input file的另类做法</title> 
<style type="text/css"> 
<!-- 
* { font-size:12px} 
body { margin:0} 
.line { position:relative; float:left; padding:8px 0} 
.line span { float:left} 
input { border:1px solid #888; vertical-align:middle} 
.file { position:absolute; left:90px; top:8px; display:none;filter:alpha(opacity=0);opacity:0} 
.file1 { padding:2px 10px; display:block; float:left; background:#FF66CC; color:#fff; z-index:1; margin-left:5px; vertical-align:middle; cursor: pointer} 
.inputstyle { width:150px; border:1px solid #888; z-index:99} 
--> 
</style> 
</head> 
<body> 
<div class="line"> <span> 
<label>上传文件:</label> 
<input name="" type="text" id="viewfile" onmouseout="document.getElementById('upload').style.display='none';" class="inputstyle" /> 
</span> 
<label for="unload" onmouseover="document.getElementById('upload').style.display='block';" class="file1">浏览...</label> 
<input type="file" onchange="document.getElementById('viewfile').value=this.value;this.style.display='none';" class="file" id="upload" /> 
</div> 
</body> 
</html>

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

【YII2】配置dubug模式

Continue Read..

YII居然没有打印当前执行sql的东西  很不好用呀

只能用它自己的 debug来查询 一些东西

 

首先在 /config/web.php  里面加入

if (YII_ENV_DEV) {

    // configuration adjustments for 'dev' environment

    $config['bootstrap'][] = 'debug';

//     $config['modules']['debug'] = 'yii\debug\Module';

    $config['modules']['debug']['class'] =  'yii\debug\Module';   //这个是调用的模型

    //$config['modules']['debug']['allowedIPs'] =  ['192.168.9x.xx',  '::1'];  //这里是上线之后 可以指定访问的IP 不写的话 默认是本地的 127.0.0.1

 

    $config['bootstrap'][] = 'gii';

    $config['modules']['gii'] = 'yii\gii\Module';

}

 

 

然后在需要打印的controller 控制器中   把写了 public $layout = false;  这行注释 没写的不用管

然后就去extensions/debug  目录下找到DebugAsset.php  修改为

<?php

/**

 * @link http://www.yiiframework.com/

 * @copyright Copyright (c) 2008 Yii Software LLC

 * @license http://www.yiiframework.com/license/

 */

 

namespace yii\debug;

 

use yii;

use yii\web\AssetBundle;

 

/**

 * Debugger asset bundle

 *

 * @author Qiang Xue 

 * @since 2.0

 */

class DebugAsset extends AssetBundle

{

    public $sourcePath = '@yii/debug/assets';

    

    /**

     * 从github releser下回来再composer,与本地完全composer生成框架的路径不同

     * 默认的路径@yii/debug/assets 是 framework/debug/assets

     * 实际路径是/extensions/debug/assets

     * @see \yii\web\AssetBundle::init()

     */

    function init(){

    $this->sourcePath = yii::$app->basePath.'/extensions/debug/assets';

    parent::init();

    }

    

    public $css = [

        'main.css',

        'toolbar.css',

    ];

    

    public $depends = [

        'yii\web\YiiAsset',

        'yii\bootstrap\BootstrapAsset',

    ];

}

 

 

 

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

【Mysql】Mysql中EXPLAIN用法

Continue Read..
  写程序的时候,往往需要去查看sql语句的执行效率,以方便我们如何优化我们的程序,设计数据库。所以我们就不得不了解一些explain的用法。
   首先看看输出地参数:Mysql中EXPLAIN用法

这些参数中,我们常常需要关心的是这几个参数
1,select_type,就是select类型.
主要有这几种,
SIMPLE:这个是简单的sql查询,不使用UNION或者子查询
PRIMARY:子查询中最外层的select
UNION:UNION中的第二个或后面的SELECT语句
DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
UNION RESULT:UNION的结果。
SUBQUERY:子查询中的第一个SELECT.
DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
DERIVED:派生表的SELECT(FROM子句的子查询) 
2,table 输出行所引用的表
3,
type 结类型。各种类型的信息在下面给出。
system
表仅有一行(=系统表)。这是const联结类型的一个特例。
const
表有最多一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被剩下的优化器认为是常数。 const表很快,因为它们只读取一次!
eq_ref
对于每个来自于先前的表的行组合,从该表中读取一行。这可能是最好的联结类型,除了const类型。它用在一个索引的所有部分被联结使用并且索引是UNIQUE或PRIMARY KEY。
ref
对于每个来自于先前的表的行组合,所有有匹配索引值的行将从这张表中读取。
如果联结只使用键的最左面前缀,不或如果键不是UNIQUE或PRIMARY KEY(换句话说,如果联结能基于键值选择单个行的话),使用ref。如果被使用的键仅仅匹配一些行,该联结类型是不错的。
range
只有在一个给定范围的行将被检索,使用一个索引选择行。ref列显示哪个索引被使用。
index
这与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
ALL
对于每个来自于先前的表的行组合,将要做一个完整的表扫描。
如果表格是第一个没标记const的表,这通常不好,并且通常在所有的其他情况下很差。你通常可以通过增加更多的索引来避免ALL,使得行能从早先的表中基于常数值或列值被检索出。

从上面可以发现,从上至下依次是越来越坏的结果,当然最好的还是Null,没有查询本表。


4,possible_keys:possible_keys列指出MySQL能使用哪个索引在该表中找到行
5,key:key列显示MySQL实际决定使用的键。如果没有索引被选择,键是NULL。
6,key_len key_len列显示MySQL决定使用的键长度。如果键是NULL,长度是NULL。注意这告诉我们MySQL将实际使用一个多部键值的几个部分。
7 ref:ref列显示哪个列或常数与key一起用于从表中选择行。
8,rows rows列显示MySQL相信它必须检验以执行查询的行数。
9,Extra
如果是Only index,这意味着信息只用索引树中的信息检索出的。通常,这比扫描整个表要快。
如果是where used,它意味着一个WHERE子句将被用来限制哪些行与下一个表匹配或发向客户。
如果是impossible where 表示用不着where
如果是Using filesort表示用到了文件排序,通常在数据量大的情况下,要减少这种查询

【PHP】恶补下php的魔法函数

Continue Read..
<?php

class test {
	private $a1 = 1111;
	private $name = "";
	private $age = "";

	public function __construct($name,$age) {
		$this->name = $name;
		$this->age = $age;
	}

	public function __call($fun, $args) {
		echo "这里是调用__call魔术方法
";
		echo "函数名:" . $fun . "
";
		echo "参数:" . var_dump($args);
		echo "
----------------------------------
";
	}

	static function cc($cc) {
		echo $cc;
	}

	public function __get($property_name) {
		echo "在直接获取私有属性值的时候,自动调用了这个__get()方法
";
		if (isset($this->$property_name)) {
			return ($this->$property_name);
		} else {
			return (NULL);
		}
	}

	public function __set($property_name, $value) {
		echo "在直接赋值私有属性值的时候,自动调用了这个__set()方法
";
		$this->$property_name = $value;
	}

	public function __isset($property_name) {
		echo "当私有变量不存在的时候,自动调用了这个__isset()方法
";
		return isset($this->$property_name);
	}

	public function __unset($property_name) {
		echo "对未定义变量调用unset(),自动调用了这个__unset()方法
";
		return isset($this->$property_name);
	}

	static public function __callstatic($fun, $args) {
		echo "这里是调用__callstatic魔术方法
";
		echo "函数名:" . $fun . "
";
		echo "参数:" . var_dump($args);
		echo "
----------------------------------
";
	}

	function aa($aa) {
		echo $aa;
	}

	function say() {
		echo "我的名字叫:" . $this->name;
		echo " 我的年龄是:" . $this->age . "
";
	}

	function __clone() {
		$this->name = "我是假的";
		$this->age = 30;
	}
}
// 构造函数
$test = new test("童星",26);

// __call
// $test->bb(111);

// __set
// $test->a1 = 11111;
// __get
// echo $test->a1;

// __isset
// if(empty($test->a2)){ }

// __callstatic
// $test::test("asdfasdfasdf");

// __unset
// unset($test->dd);

//__clone
$test->say();
$test2 = clone $test;
$test2->say() ;


声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

budgetvm VPS 安装 PPTP VPN Server

Continue Read..

budgetvm vps ,openvz架构

这个是不加密的,windows创建vpn链接时,

vpn类型选择pptp

数据加密选择可选加密(没有加密也可以连接)


检测是否可以安装


cat /dev/ppp

#如果返回No such device or address 可以安装

#如果返回Permission denied 请到vps Control Panel控制面板中 Enable PPP ,TUN/TAP无需开启


安装相应软件包

yum update 

yum install ppp iptables 

rpm -Uvh http://poptop.sourceforge.net/yum/stable/rhel6/pptp-release-current.noarch.rpm 

yum install pptpd


编辑配置文件

$ vi /etc/pptpd.conf

# 最后

#这里的ip段,根据vps本地ip决定是127还是10网段

localip 10.168.0.1

remoteip 10.168.0.10-238,10.168.0.245

$ vi /etc/ppp/options.pptpd

# 找到

require-mschap-v2

require-mppe-128

ms-dns 8.8.8.8

ms-dns 8.8.4.4


开启ip转发,设定转发规则

$ vi /etc/sysctl.conf

#修改下面的等于1

net.ipv4.ip_forward = 1

#保存退出并另设置生效

$ sysctl -p

#添加转发规则 10.168.0.0/24 为上面设定的网段,xxx.xxx.xxx.xxx 为vps外网ip

$ iptables -t nat -A POSTROUTING -s 10.168.0.0/24 -j SNAT --to-source xxx.xxx.xxx.xxx

#上面这条,网上很多教程抄的同一个,有问题--to -source,中间多个空格

#保存规则

$ service iptables save

$ service iptables restart


如果重启后该文件值变为0请重新修改改文件为内容1,也可以加入开机启动

vi /etc/rc.local

加入

echo 1 > /proc/sys/net/ipv4/ip_forward


设置成服务,自动启动

$ chkconfig pptpd on

$ chkconfig iptables on


设定使用者的用户密码

$ vi /etc/ppp/chap-secrets

#密码格式为 用户名,服务名,密码,访问ip

#例如下面:

vpn pptpd vpn *

#用户名 连接方式 用户名 不限定IP地

到这里,vpn服务就基本设置好了,重启就可以使用了

这里后面修改的时候,重启pptpd服务也不生效,reboot服务器就好了


#重启vps

$ reboot

#重启服务

$ /etc/init.d/iptables restart

$ /etc/init.d/pptpd restart

参考:

budgetvm的openvz架构vps搭建pptp协议的vpn

budgetvm VPS 安装 PPTP VPN Server

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权