yii2 循环执行sql导致内存耗尽的问题解决

Continue Read..

yii2循环执行sql的时候

for ($i = 0; $i < $iterations; $i ++) {
    ...
    Yii::$app->db->createCommand()
        ->batchInsert(static::tableName(), $columns, $rows)
        ->execute();
    echo memory_get_usage();
}

会出现500错误,看下php错误日志,大概会看到内存耗尽的提示

[06-Apr-2017 15:55:43 PRC] PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 2077602 bytes) in E:\wamp\www\xxx\vendor\yiisoft\yii2-debug\LogTarget.php on line 57

 

这个是由于yii2的日志模块引起的,具体的大家看看代码,不多说了

解决方案

1、在处理循环sql的时候,替换掉自带的日志模块

2、关掉日志模块

 

具体的看这里

I think that problem is in logger of Yii2. Just try to use something like that:

common/components/EmptyLogger.php:

<?php
namespace common\components;

use yii\log\Logger;

class EmptyLogger extends Logger
{
    public function log($message, $level, $category = 'application')
    {
        return false;
    }
}

and then in your action of your controller include next code at the beginning:

Yii::setLogger(new EmptyLogger());

of course also add it in your uses:

use common\components\EmptyLogger;

after all you will receive something like that:

console\controllers\TempController.php:

<?php

namespace console\controllers;

use common\components\EmptyLogger;
use Yii;
use yii\console\Controller;

class TempController extends Controller
{
    public function actionIndex()
    {
        Yii::setLogger(new EmptyLogger());
        ...

        Yii::$app->db->createCommand()
            ->batchInsert(static::tableName(), $columns, $rows)
            ->execute();
        ...

    }
}

Hope it helps. But actually it's not the best solution. Just a hack..

参考:http://stackoverflow.com/questions/27420959/yii2-batchinsert-eats-all-server-memory

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

yii2 数据库字段加一

Continue Read..

YII2中数据库操作DAO中,update操作的时候,手册上好像看不到+1的办法,只有AR模式有+1写法,其实在源代码里有写

看代码

public function update($table, $columns, $condition, &$params)
    {
        if (($tableSchema = $this->db->getTableSchema($table)) !== null) {
            $columnSchemas = $tableSchema->columns;
        } else {
            $columnSchemas = [];
        }

        $lines = [];
        foreach ($columns as $name => $value) {
            if ($value instanceof Expression) {
                $lines[] = $this->db->quoteColumnName($name) . '=' . $value->expression;
                foreach ($value->params as $n => $v) {
                    $params[$n] = $v;
                }
            } else {
                $phName = self::PARAM_PREFIX . count($params);
                $lines[] = $this->db->quoteColumnName($name) . '=' . $phName;
                $params[$phName] = !is_array($value) && isset($columnSchemas[$name]) ? $columnSchemas[$name]->dbTypecast($value) : $value;
            }
        }

        $sql = 'UPDATE ' . $this->db->quoteTableName($table) . ' SET ' . implode(', ', $lines);
        $where = $this->buildWhere($condition, $params);

        return $where === '' ? $sql : $sql . ' ' . $where;
    }

如果值是Expression的实例,会取这个实例的expression属性去拼接sql,

这个类在yii\db\Expression,使用起来很简单

$cardData = [
            'uid' => $uid,
            'cnt' => new Expression('cnt+1')
        ];
$db->createCommand()->update($tableCard, $cardData, "id=5")->execute();
同理,使用mysql原生函数等操作都可以用这个方式来完成。

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

js 头像图片过滤器

Continue Read..
html:
<div class="user-icon user-icon-bg">
               <img :src="item.targetAnswerer.userInfo.avatarId | getThumbnail || 'images/mine/default-avatar1.png'">
               <div class="master" v-if="item.answerer.isAnswer == 1"></div>
           </div>

js:
Vue.filter("getThumbnail", function (url) {
            if (!url) {
                return "http://apr.qiniu.toon.mobi/FqnjLn8FzsD52rZatXzYKgwftS6A";
            }
            //静态服务器头像
            if (url.indexOf("http://img.icon.systoon.com") >= 0 || url.indexOf("http://static1.systoon.com") >= 0) {
                return url;
            }
            var w = 80, h = 80, q = 100;
            var path = url.substr(0, url.lastIndexOf("."));
            var mimeType = url.substring(url.lastIndexOf("."), url.length);
            return path + "_" + w + "_" + h + "_" + q + "_1" + mimeType;
        });

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

【mysql】mysql中FIND_IN_SET的使用方法

Continue Read..

mysql中,有时我们在做数据库查询时,需要得到某字段中包含某个值的记录,但是它也不是用like能解决的,使用like可能查到我们不想要的记录,它比like更精准,这时候mysql的FIND_IN_SET函数就派上用场了,下面来具体了解一下。

FIND_IN_SET(str,strlist)函数

str 要查询的字符串

strlist 字段名 参数以”,”分隔 如 (1,2,6,8)

查询字段(strlist)中包含(str)的结果,返回结果为null或记录

下面举例说明

test表中有如下字段及值

下面我想查询area中包含”1″这个参数的记录

SELECT * from test where FIND_IN_SET('1',area)

返回值

下面查询btype字段中包含”15″这个参数的值

SELECT * from test where FIND_IN_SET('15',btype)

返回值

下面查询btype字段中包含”5″这个参数的值

SELECT * from test where FIND_IN_SET('5',btype)

返回值为null,因为btype中没有”5”这个值,它不同于 like 模糊查询,它是以“,”来分隔值

接下面查询btype字段中包含”20″这个参数的值

SELECT * from test where FIND_IN_SET('20',btype)

当然它的返回值为null,因为字段中没有这个值

FIND_IN_SET和like的区别

like是广泛的模糊匹配,字符串中没有分隔符,Find_IN_SET 是精确匹配,字段值以英文”,”分隔,Find_IN_SET查询的结果要小于like查询的结果。

更多参考:http://www.devdo.net/mysql-find_in_set.html

转载 :http://www.cnblogs.com/manongxiaobing/p/4682698.html

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

js 移到端打电话

Continue Read..
<p class="rules">一键拨打客服电话:<span class="blue" @click="toCall">010-84871686</span></p>

toCall: function(){

var ifr = document.createElement('iframe');
document.body.appendChild(ifr);
ifr.src = 'tel:' + '01084871686';
setTimeout(function(){
ifr.remove();
}, 100);
}

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

【php】curl代理html file (分块)上传文件

Continue Read..

我目前要用php做个代理层

html file 上传的文件  我要直接获取文件流

然后吧文件流分块传出去

 

首先了解下 php的上传流程

php内置函数 $_FILES $_POST 在调用这2个函数的时候 会自动解析 php://input

而且php内核也会先处理 php://input  然后把流解析并生成到缓存文件里面

如果流呗读取过,那么这个流就不能再次读取,所以需要在php没有读取文件流之前 把文件流读取到

有2个方法

1.写一个php的C扩展 取代$_FILES  

2.修改php.ini (如果你的服务器只有一个程序,可以修改,不然就会影响其他程序)

    2.1 nginx.conf 

        proxy_request_buffering off;

        fastcgi_request_buffering off;

    2.2  php.ini

       memory_limit = 8M (忘记这个要不要改了)

       file_uploads = Off

       upload_max_filesize = 0M

       post_max_size = 0M


然后就可以直接获取流


 

    function actionImg4(){

        $fp = fopen("php://input", "r");

        $wfp = fopen("/data/1.png",'w+');

        while(!feof($fp)){

            $buffer = fread($fp,1000);

            fwrite($wfp, $buffer);

        }

    fclose($wfp);

    fclose($fp);

    }

    

    //前端上传文件时 调用这个接口

    function actionImg5(){

        $url = "http://xxxx.com/api/cuzntest/img4";  //接收方

        $fopen = fopen ("php://input", "r");

    $size = $_SERVER['HTTP_CONTENT_LENGTH']; //获取流大小

    $x = $this->curlUpload1($url,$fopen,$size);

    fclose($fopen);

    var_dump($x);

    }

    

    

    function curlUpload1($url,$fd,$size){

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_HEADER, false);

        curl_setopt($ch, CURLOPT_PUT, true);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/binary","Expect:") );

        curl_setopt($ch, CURLOPT_READFUNCTION,

            function ($ch, $fd, $length) {

                $data = fread($fd, 1000);

//                 file_put_contents('/data/1.txt', $data.'------------------------',FILE_APPEND);

                $len = strlen($data);

                return $data;

            }

   );

    curl_setopt($ch, CURLOPT_HTTPHEADER, array(

    'Accept: */*',

    'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)',

    'Connection: Keep-Alive'));

        curl_setopt($ch, CURLOPT_INFILE, $fd);

        curl_setopt($ch, CURLOPT_INFILESIZE, $size);

        $ret['tmpInfo'] = curl_exec($ch);

    $ret['error_code'] = curl_errno($ch);

        $ret['error_msg'] = curl_error($ch);

        $ret['getinfo'] = curl_getinfo($ch);

        curl_close($ch);

        return $ret;

    }


用postman 测试是 需要改 Content-Type  multipart/form-data  ->  x-multipart/form-data


跳转到代理下载文章


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

crontab 唯一执行与超时

Continue Read..

参考:http://huoding.com/2016/12/12/573

唯一执行

假如上一分钟的 A 请求还没退出,下一分钟的 B 请求也启动了,那么 B 请求会发现 A 请求还没有释放锁,于是它不会执行。

flock -xn /tmp/lock /path/to/php /path/to/file

 

带超时的唯一执行

假如上一分钟的 A 请求还没退出,下一分钟的 B 请求也启动了,那么 B 请求会发现 A 的请求还没有释放锁,于是它不会执行,不过下下分钟的 C 请求肯定能执行,因为在这之前,A 请求已经因为超时被 timeout 干掉了

timeout -s SIGINT 100 flock -xn /tmp/lock /path/to/php /path/to/file

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

js 获取url?后面的参数、当前路径

Continue Read..
一种:
调用:
var merchantCardId=getParameter("parkRecordId");

方法
function getParameter(name) { 
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); 
var r = window.location.search.substr(1).match(reg); 
if (r!=null) return unescape(r[2]); return null;
}

二种:
调用:
if (!utils.getQueryStringByName("qid")) {
    this.$dispatch("alert.show", "您所查看的问题无效");
    logger.error("问题无效");
}if (utils.getQueryStringByName("enter") == "100") {
    this.shareShow = false;
}this.questionid = utils.getQueryStringByName("qid");
方法
getQueryStringByName: function (name) {
    var result = location.search.match(new RegExp("[\?\&]" + name + "=([^\&]+)", "i"));
    if (result == null || result.length < 1) {
        return "";
    }
    return result[1];
},
 
 
getCurrentPath: function (opts) {
    var rtn = document.location.hash;
    if (opts && opts.pathOnly) {
        rtn = rtn.split('?')[0].replace(/#!\//g, '');
    }
    return rtn;
},

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

【Yii2】behaviors 控制器访问前和访问后的操作

Continue Read..
最近要做个控制机访问的日志功能,而且还要记录访问的返回值,又不想在每个控制器里面加代码,这时就用了   

新建一个php文件

<?php
namespace common\models;
use Yii;
use yii\base\ActionFilter;
use cpbackend\controllers\AgencyController;
class TestFilter extends ActionFilter {
    //在action之前运行,可用来过滤输入
    public function beforeAction($action) {
        return TRUE;//如果返回值为false,则action不会运行
    }
    //在action之后运行,可用来过滤输出
    public function afterAction($action, $result) {
        //获取控制器的对象属性
        $logArr['xx'] = empty($action->controller->_user['adminInfo']) ? 0 : $action->controller->_user['adminInfo']['xx'];
        //获取访问的控制器名称 比如  a/b
        $logArr['requste'] = json_encode(Yii::$app->requestedRoute);
        //获取请求的参数
        if(!empty($action->controller->actionParams)){
            $logArr['data'] = json_encode($action->controller->actionParams);
        }
        if(!empty(Yii::$app->getRequest()->getRawBody())){
            $logArr['data'] = Yii::$app->getRequest()->getRawBody();
        }
        //获取请求类型
        $logArr['type'] = "";
        if(yii::$app->request->isGet){
            $logArr['type'] = "GET";
        }
        if(yii::$app->request->isPost){
            $logArr['type'] = "POST";
        }
        //这里获取返回的值  
        if(!$this->is_json($result)){
            $result = json_encode($result);
        }
        $logArr['return'] = $result;
        AgencyController::createlog($logArr);
        return $result; 
    }
    function is_json($string) { 
        return (json_last_error() == JSON_ERROR_NONE);
    }
}



然后各个控制器里面加上
 public function behaviors()
    {
        return [
            'access' => [
                'class' => 'common\models\TestFilter',
                // 'only' => ['index'],   //这里是能访问的控制器
                // 'except' => ['getlist'],   //这里是不能访问的控制
            ],
        ];
    }


特别要注意 每个控制器比如是return xxx;结尾 并且不能die掉
感谢老外童鞋的帮助~~~~

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

培训相关:一行代码加边线,找标签

Continue Read..

点击查看原图

页面所有元素加上边线

$$("*").forEach(function(value){value.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)});

 

点击查看原图

页面上所用的标签数量:["HTML", "HEAD", "META", "TITLE", "LINK", "SCRIPT", "BODY", "DIV", "H1", "A", "SPAN", "FORM", "INPUT", "UL", "LI", "H2", "P", "IMG", "PRE", "BR", "TABLE", "TBODY", "TR", "TD", "CODE", "EM", "H3"]

$$("*").map(function(value){return(value.tagName)}).reduce(function(arr,item){if(arr.indexOf(item)===-1)arr.push(item);return arr},[]).length;

 

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