laravel记录

laravel开启跨域

//对于跨域访问并需要伴随认证信息的请求,需要在 XMLHttpRequest 实例中指定 withCredentials 为 true,在响应中指定 Access-Control-Allow-Credentials 为 true 时,Access-Control-Allow-Origin 不能指定为 *
<?php namespace App\Http\Middleware;

use Closure;
use Response;
class EnableCrossRequestMiddleware {

  /**
   * Handle an incoming request.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \Closure  $next
   * @return mixed
   */
  public function handle($request, Closure $next)
  {

    $response = $next($request);
        $response->header('Access-Control-Allow-Origin', config('app.allow'));
        $response->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Cookie, Accept');
        $response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS');
        $response->header('Access-Control-Allow-Credentials', 'true');
        return $response;
  }

}

laravel自定义artisan命令

//命令生成文件 app/Console/Commands/TopicMakeExcerptCommand.php
php artisan make:console TopicMakeExcerptCommand --command=topics:excerpt
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class TopicMakeExcerptCommand extends Command
{
    /**
     * 1. 这里是命令行调用的名字, 如这里的: `topics:excerpt`, 
     * 命令行调用的时候就是 `php artisan topics:excerpt`
     *
     * @var string
     */
    protected $signature = 'topics:excerpt';

    /**
     * 2. 这里填写命令行的描述, 当执行 `php artisan` 时
     *   可以看得见.
     *
     * @var string
     */
    protected $description = '这里修改为命令行的描述';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 3. 这里是放要执行的代码, 如在我这个例子里面,
     *   生成摘要, 并保持.
     *
     * @return mixed
     */
    public function handle()
    {
        $topics = Topic::all();
        $transfer_count = 0;

        foreach ($topics as $topic) {
          if (empty($topic->excerpt))
          {
              $topic->excerpt = Topic::makeExcerpt($topic->body);
              $topic->save();
              $transfer_count++;
          }
        }
        $this->info("Transfer old data count: " . $transfer_count);
        $this->info("It's Done, have a good day.");
    }
}
//在 app/Console/Kernel.php 文件里面, 添加以下
 protected $commands = [
        \App\Console\Commands\TopicMakeExcerptCommand::class,
    ];
//命令行调用
   php artisan topics:excerpt  

去除CSRF TOKEN的保护

Route::post('wechatmp', 'WechatController@responseMsg');

class VerifyCsrfToken extends BaseVerifier
{

 protected $except = [
    'wechatmp', 
 ];
}

DateTime非常方便快捷地计算出两个日期的diff

$datetime1 = new DateTime();
$datetime2 = new DateTime('2018-08-16');
$interval = $datetime1->diff($datetime2);
list($y, $m, $d) = explode('-', $interval->format('%Y-%m-%d'));

echo "距世界杯还有{$y}年{$m}个月{$d}天";
$now=time();
$end=strtotime('2018-8-16 00:00:00');
$d=$end-$now;

$y = date('Y', $d) - 1970;
$m = date('n', $d) - 1;
$d = date('j', $d) - 1;

printf('还有%d年%d月%d天', $y, $m, $d);

php里简单的对称加密算法

$content = "大家好,我是中国人,你是谁";

    /**
     * 简单对称加密算法之加密
     * @param String $string 需要加密的字串
     * @param String $skey 加密EKY
     * @return String
     */
    function encode($string = '', $skey = 'wenzi') {
        $strArr = str_split(base64_encode($string));
        $strCount = count($strArr);
        foreach (str_split($skey) as $key => $value)
            $key < $strCount && $strArr[$key].=$value;
        return str_replace(array('=', '+', '/'), array('O0O0O', 'o000o', 'oo00o'), join('', $strArr));
    }

    /**
     * 简单对称加密算法之解密
     * @param String $string 需要解密的字串
     * @param String $skey 解密KEY
     * @return String
     */
    function decode($string = '', $skey = 'wenzi') {
        $strArr = str_split(str_replace(array('O0O0O', 'o000o', 'oo00o'), array('=', '+', '/'), $string), 2);
        $strCount = count($strArr);
        foreach (str_split($skey) as $key => $value)
            $key <= $strCount && $strArr[$key][1] === $value && $strArr[$key] = $strArr[$key][0];
        return base64_decode(join('', $strArr));
    }

    echo '<pre>';
    echo "string : " . $content . " <br />";
    echo "encode : " . ($enstring = encode($content)) . '<br />';
    echo "decode : " . decode($enstring);

laravel eloquent 一对一关联后根据副表中的字段来排序

GoodsData::with('good')->whereHas('good', function($q) use ($brandId) {
    $q->where('brand_id', $brandId)
})->orderBy('click_count', 'desc')->paginate();

$goodIds = GoodsData::whereHas('good', function($q) use ($brandId) {
    $q->where('brand_id', $brandId)
})->orderBy('click_count', 'desc')->skip(10)->take(15)->pluck('id');

$goods = Good::whereIn('id', $goodIds)->get();

数字运算

function calc($m,$n,$x){
        $errors=array(
                '被除数不能为零',
                '负数没有平方根'
        );
        switch($x){
                case 'add':
                        $t=bcadd($m,$n);
                        break;
                case 'sub':
                        $t=bcsub($m,$n);
                        break;
                case 'mul':
                        $t=bcmul($m,$n);
                        break;
                case 'div':
                        if($n!=0){
                                $t=bcdiv($m,$n);
                        }else{
                                return $errors[0];
                        }
                        break;
                case 'pow':
                        $t=bcpow($m,$n);
                        break;
                case 'mod':
                        if($n!=0){
                                $t=bcmod($m,$n);
                        }else{
                                return $errors[0];
                        }
                        break;
                case 'sqrt':
                        if($m>=0){
                                $t=bcsqrt($m);
                        }else{
                                return $errors[1];
                        }
                        break;
        }
        $t=preg_replace("/\..*0+$/",'',$t);
        return $t;
}
/*用法举例*/
echo calc('11111111111111111111111111111111110','10','add');

计算2点经纬度之间的距离代码

function getDistanceBetweenPointsNew($latitude1, $longitude1, $latitude2, $longitude2) {  
    $theta = $longitude1 - $longitude2;  
    $miles = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta)));  
    $miles = acos($miles);  
    $miles = rad2deg($miles);  
    $miles = $miles * 60 * 1.1515;  
    $feet = $miles * 5280;  
    $yards = $feet / 3;  
    $kilometers = $miles * 1.609344;  
    $meters = $kilometers * 1000;  
    return compact('miles','feet','yards','kilometers','meters');  
}  
  
$point1 = array('lat' => 40.770623, 'long' => -73.964367);  
$point2 = array('lat' => 40.758224, 'long' => -73.917404);  
$distance = getDistanceBetweenPointsNew($point1['lat'], $point1['long'], $point2['lat'], $point2['long']);  
foreach ($distance as $unit => $value) {  
    echo $unit.': '.number_format($value,4).'<br />';  
}  

计算抽奖的概率

    function get_rand($proArr) {     
        $result = '';      
        $proSum = array_sum($proArr);       
        foreach ($proArr as $key => $proCur) {     
            $randNum = mt_rand(1, $proSum);     
            if ($randNum <= $proCur) {     
                $result = $key;     
                break;     
            } else {     
                $proSum -= $proCur;     
            }           
        }     
        unset ($proArr);      
        return $result;     
    }     
    $prize_arr = array(     
        '0' => array('id'=>1,'prize'=>'1000000514','v'=>2),     
        '1' => array('id'=>2,'prize'=>'1000000513','v'=>5),     
        '2' => array('id'=>3,'prize'=>'1000000512','v'=>13),     
        '3' => array('id'=>4,'prize'=>'1000000511','v'=>15),     
        '4' => array('id'=>5,'prize'=>'1000000510','v'=>25),     
        '5' => array('id'=>6,'prize'=>'1000000509','v'=>30),    
        '6' => array('id'=>7,'prize'=>'1000000508','v'=>10),   
    );     
    foreach ($prize_arr as $key => $val) {     
        $arr[$val['id']] = $val['v'];     
    }     
    $rid = get_rand($arr);    
    $res['yes'] = $prize_arr[$rid-1]['prize'];   
    unset($prize_arr[$rid-1]);      
    shuffle($prize_arr);    
    $prize_arrcount = count($prize_arr);   
    for($i=0;$i<$prize_arrcount;$i++){     
        $pr[] = $prize_arr[$i]['prize'];     
    }     
    $res['no'] = $pr;     
    //抽奖结果  
    $ro = $res['yes'];  
    print_r($ro);  

一维数据转多维

   $s =<<< TXT  
1 = 光电鼠标  
2 = 机械鼠标  
3 = 没有鼠标  
1.1 = 黑色光电鼠标  
1.2 = 红色光电鼠标  
1.2.1 = 蓝牙红色光电鼠标  
TXT;  
  
$res = array();  
foreach(preg_split("/[\r\n]+/", $s) as $r) {  
 list($k, $txt) = explode(' = ', $r);  
 $p =& $res;  
 foreach(explode('.', $k) as $v) {  
   if(! isset($p[$v])) $p[$v] = array('txt' => $txt, 'child' => array());  
   $p =& $p[$v]['child'];  
 }  
}  
  
print_r($res);  

打乱数组二维数组/多维数组

function shuffle_assoc($list) {   
if (!is_array($list)) return $list;   
  
$keys = array_keys($list);   
shuffle($keys);   
$random = array();   
foreach ($keys as $key)   
$random[$key] = shuffle_assoc($list[$key]);   
  
return $random;   
}   

function rec_assoc_shuffle($array)  
{  
  $ary_keys = array_keys($array);  
  $ary_values = array_values($array);  
  shuffle($ary_values);  
  foreach($ary_keys as $key => $value) {  
    if (is_array($ary_values[$key]) AND $ary_values[$key] != NULL) {  
      $ary_values[$key] = rec_assoc_shuffle($ary_values[$key]);  
    }  
    $new[$value] = $ary_values[$key];  
  }  
  return $new;  
}  

curl 上传文件


$curl = curl_init();
        
        if (class_exists('\CURLFile')) {// 这里用特性检测判断php版本
            curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true);
               $data = array('file' => new \CURLFile(realpath($source)));//>=5.5
        } else {
            if (defined('CURLOPT_SAFE_UPLOAD')) {
                curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false);
            }
            $data = array('file' => '@' . realpath($source));//<=5.5
        }
        
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, 1 );
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_USERAGENT,"TEST");
        $result = curl_exec($curl);
        $error = curl_error($curl);

数字递归组合并排列

function recursion($groups, $echo = '')
{
    $current = array_pop($groups);
    $end = empty($groups);

    $echo .= $echo ? ',' : '';

    foreach (str_split($current) as $item) {
        $rEcho = $echo . $item;

        if ($end) {
            echo $rEcho . "\n";
        } else {
            recursion($groups, $rEcho);
        }
    }
}

recursion(explode(',', '123,45,6789'));

php超出字符截取

 $text = '123456'; 
$charLength = 10; //字符串长度 
$content = mb_strlen($text, 'UTF-8') <= $charLength ? $text : mb_substr($text, 0,$charLength,'UTF-8') . '...';

post json

        // form post json
        $ch        = curl_init();
        $timeout   = 300;
        $useragent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)";
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $json = '{"name":"value"}';
        $data['data'] = $json;       
        $data = http_build_query($data);
        curl_setopt($ch, CURLOPT_URL, 'http://www.test.com/json.php');
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);                        
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        $body = curl_exec($ch);
        echo '<pre>';print_r($body);
        //json.php
        var_dump($_POST);
        
        // 正确的post json
        $ch        = curl_init();
        $timeout   = 300;
        $useragent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)";
        $header    = array(
                'Accept-Language: zh-cn', 
                'Connection: Keep-Alive', 
                'Cache-Control: no-cache', 
                'Content-Type: Application/json;charset=utf-8'
            );
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $json = '{"name":"value"}';
        curl_setopt($ch, CURLOPT_URL, 'http://www.test.com/json.php');
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json);                        
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        $body = curl_exec($ch);
        echo '<pre>';print_r($body);
        //json.php
        var_dump(file_get_contents('php://input'));
        #curl命令行 post json
        #获取本机ip地址
        $ curl http://httpbin.org/ip
        {"origin": "24.127.96.129"}
        $ curl -X POST -d '{"name":"value"}'  -H "Content-type: application/json" "http://httpbin.org/post"
        {
          "args": {},
          "data": "{\"name\":\"value\"}",
          "files": {},
          "form": {},
          "headers": {
            "Accept": "*/*",
            "Content-Length": "16",
            "Content-Type": "application/json",
            "Host": "httpbin.org",
            "User-Agent": "curl/7.30.0"
          },
          "json": {
            "name": "value"
          },
          "origin": "43.255.178.126",
          "url": "http://httpbin.org/post"
        }
        #python post json
        >>> import requests,json
        >>> headers = {'content-type': 'application/json'}
        >>> payload = {'name': 'value'}
        >>> r = requests.post('http://httpbin.org/post', data=json.dumps(payload), headers=headers)
        >>> print(r.json())
        
        

为 VerifyCsrfToken 添加过滤条件

//修改 app/Http/Middleware/VerifyCsrfToken.php 文件
<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
use Closure;

class VerifyCsrfToken extends BaseVerifier
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        //
    ];

    public function handle($request, Closure $next)
    {
        // 如果是来自 api 域名,就跳过检查
        if ($_SERVER['SERVER_NAME'] != config('api.domain'))
        {
            return parent::handle($request, $next);
        }

        return $next($request);
    }
}

自定义一个类文件让composer加载

//修改composer.json文件:
{
    "require": {
        "illuminate/container": "^5.2"
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    }
}
#composer install
// app/Test/Test.php文件
namespace App\Test;

class Test
{
    public function index()
    {
        echo "This is a custom class which will be autoload by composer\n";
    }
}

//index.php
require_once __DIR__.'/vendor/autoload.php';

$test = new App\Test\Test();
$test->index();

利用 macro 方法来扩展 Laravel 的基础类的功能

//创建一个ServiceProvider,并把扩充的方法,放入boot()的方法中
namespace App\Providers;

  use Collection;
  use Illuminate\Support\ServiceProvider;

  class CollectionMacroServiceProvider extends ServiceProvider {

      public function boot()
      {
         Collection::macro('uppercase', function () {
         //$this不是指向你文件类的对象,而是指向你marco扩充的类。比如例子中的$this是指向Collection的。
            return collect($this->items)->map(function ($item) {
                return strtoupper($item);
            });
        });
      }

  }
//在config/app.php中的providers中下面添加App\ProvidersCollectionMacroServiceProvider::class即可

从现有数据库表中生成 Model 模型文件

composer require ignasbernotas/laravel-model-generator
在 app/Providers/AppServiceProvider.php 文件的 register 方法里面,加入如下代码

public function register()
{
    if ($this->app->environment() == 'local') {
        $this->app->register('Iber\Generator\ModelGeneratorProvider');
    }
}
php artisan make:models

数组扁平化

$arrays = array(0 => Array (
                    0 => Array (
                        '社员' => 2,
                         0 => 'level4'
                    ),
                    1 => Array (
                        '社员' => 2,
                         0 => 'level4',
                         1 => 'level4'
                    )
               ),
               1 => Array (
                    0 => Array (
                        '小组长' => 2,
                        0 => 'level3'
                    ),
                    1 => Array (
                        '小组长' => 2,
                        0 => 'level3',
                        1 => 'level2',
                        2 => 'level3'
                    )
               )
    );
    dd(collect($arrays)->map(function($array){
        return $array[1]; //比如都取最里面数组的第二个值
    })->flatten(1));

Laravel 单点登录

php artisan make:middleware SsoMiddleware
将中间件添加到 Kernel.php
protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'SsoMiddleware' => \App\Http\Middleware\index\SsoMiddleware::class,
    ];

/**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $userInfo = \Session::get('user_login');
        if ($userInfo) {
            // 获取 Cookie 中的 token
            $singletoken = $request->cookie('SINGLETOKEN');
            if ($singletoken) {
                // 从 Redis 获取 time
                $redisTime = \Redis::get(STRING_SINGLETOKEN_ . $userInfo->guid);
                // 重新获取加密参数加密
                $ip = $request->getClientIp();
                $secret = md5($ip . $userInfo->guid . $redisTime);
                if ($singletoken != $secret) {              
                    // 记录此次异常登录记录
                    \DB::table('data_login_exception')->insert(['guid' => $userInfo->guid, 'ip' => $ip, 'addtime' => time()]);
                    // 清除 session 数据
                    \Session::forget('indexlogin');
                    return view('/403')->with(['Msg' => '您的帐号在另一个地点登录..']);
                }
                return $next($request);
            } else {
                return redirect('/login');
            }
        } else {
            return redirect('/login');
        }
    }
    // 有 Sso 中间件的路由组
Route::group(['middleware' => 'SsoMiddleware'], function() {
      # 用户登录成功后的路由
}

curl ssl


$url="https://api.shanbay.com/bdc/search/?word=hello";
$ch=curl_init();
$timeout=5;
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
$data=curl_exec($ch);
curl_close($ch);
echo $data;

base64_encode进行编码.同时替换其中的不安全字符


//处理为URL安全模式
function reflowURLSafeBase64($str){
    $str=str_replace("/","_",$str);
    $str=str_replace("+","-",$str);
    return $str;
}

//反解
function reflowNormalBase64($str){
    $str=str_replace("_","/",$str);
    $str=str_replace("-","+",$str);
    return $str;
}

PHP无限级分类

function data_to_tree(&$items, $topid = 0, $with_id = TRUE)
{
    $result = [];
    foreach($items as $v)
        if ($topid == $v['parent'])  {
            $r = $v + ['children' => _data_to_tree($items, $v['id'], $with_id)];
            if ($with_id)
                $result[$v['id']] = $r;
            else
                $result[] = $r;
        }
            
    return $result;
}
function _data_to_tree($items, $topid = 0, $with_id = TRUE)
{
    if ($with_id)
        foreach ($items as $item)
            $items[ $item['parent'] ]['children'][ $item['id'] ] = &$items[ $item['id'] ];
    else
        foreach ($items as $item)
                $items[ $item['parent'] ]['children'][] = &$items[ $item['id'] ];

         return isset($items[ $topid ]['children']) ? $items[ $topid ][ 'children' ] : [];
}
$data = [
   ['id' => 4, 'parent' => 1 , 'text' => 'Parent1'], 
   ['id' => 1, 'parent' => 0 , 'text' => 'Root'],
   ['id' => 2, 'parent' => 1 , 'text' => 'Parent2'], 
   ['id' => 3, 'parent' => 2 , 'text' => 'Sub1'], 
];
print_r ( _data_to_tree($data, 0) );

Array
(
    [1] => Array
        (
            [id] => 1
            [parent] => 0
            [text] => Root
            [children] => Array
                (
                    [4] => Array
                        (
                            [id] => 4
                            [parent] => 1
                            [text] => Parent1
                            [children] => Array
                                (
                                )
                        )
                    [2] => Array
                        (
                            [id] => 2
                            [parent] => 1
                            [text] => Parent2
                            [children] => Array
                                (
                                    [3] => Array
                                        (
                                            [id] => 3
                                            [parent] => 2
                                            [text] => Sub1
                                            [children] => Array
                                                (
                                                )
                                        )
                                )
                        )
                )
        )
)

判断是否为json格式

function is_json($string) 
{
 json_decode($string);
 return (json_last_error() == JSON_ERROR_NONE);
//return json_encode($json)!==false
}

$str = '{"id":23,"name":"test"}';
var_dump(is_json($str));

中文英文截取


/**
 * 移除字符串的BOM
 *
 * @param  string $str 输入字符串
 * @return string 输出字符串
 */
function removeBOM($str)
{
    $str_3 = substr($str, 0, 3);
    if ($str_3 == pack('CCC',0xef,0xbb,0xbf)) //utf-8
        return substr($str, 3);
    return $str;
}

/**
 * 按UTF-8分隔为数组,效率比MB_Substr高
 * 0xxxxxxx
 * 110xxxxx 10xxxxxx
 * 1110xxxx 10xxxxxx 10xxxxxx
 * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
 * 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
 * 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
 *
 * @param string $str 输入utf-8字符串
 * @return array 返回成一段数组
 */
function str_split_utf8($str)
{
    return preg_match_all('/./u', removeBOM($str), $out) ? $out[0] : FALSE;
}

/**
 * 按非ascii字符占有几个字宽的方式切分字符串,并且不会将汉字切成半个
 * 所谓字宽是指,使用默认字体显示时,非ascii字符相比英文字符所占大小,比如:宋体、微软雅黑中,汉字占两个宽度
 * @example $ansi_width = 2 表示汉字等非英文字符按照两个字宽长度
 * @example $ansi_width = 1 表示所有字符按一个字宽长度
 *
 * @param string $string 原始字符
 * @param integer $offset 开始偏移,使用方法和substr一样,可以为负数
 * @param integer $length 长度,使用方法和substr一样,可以为负数
 * @param integer $ansi_width 汉字等非英文字符按照几个字符来处理
 * @return string 返回裁减的字符串
 */
function substr_ansi($string, $offset, $length = 0, $ansi_width = 1)
{
    if (empty($string)) return $string;;
    $data = str_split_utf8($string);
    if (empty($data)) return $string;
 
    $as = $_as = array();
    $_start = $_end = 0;
 
    foreach($data as $k => $v)
        $as[$k] = strlen($v) > 1 ? $ansi_width : 1;
 
    $_as_rev = array_reverse($as,true);
    $_as = $offset < 0 ? $_as_rev : $as; 
    $n = 0; $_offset = abs($offset);
    foreach($_as as $k => $v) {
        if ($n >= $_offset) {
            $_start = $k;
            break;
        }
        $n += $v;
    }
    //echo $_start,',';
    $_as = $length <= 0 ? $_as_rev : $as;
    end($_as); list($_end) = each($_as); reset($_as);//给$_end 设定默认值,一直到结尾
    $n = 0; $_length = abs($length);
    foreach($_as as $k => $v) {
        if ($k >= $_start) {
            if ($n >= $_length) {
                $_end = $k + ($length <= 0 ? 1 : 0);
                break;
            }
            $n += $v;
        }
    }
    //echo $_end,'|||||';
    if ($_end <= $_start)
        return '';
 
    $_data = array_slice($data, $_start, $_end - $_start);
 
    return implode('',$_data);
}

/**
 * 按非ascii字符占有几个字宽的方式计算字符串长度
 * @example $ansi_width = 2 表示汉字等非英文字符按照两个字宽长度
 * @example $ansi_width = 1 表示所有字符按一个字节长度
 *
 * @param string $string 原始字符
 * @param integer $ansi_width 汉字等非英文字符按照几个字宽来处理
 * @return string 返回字符串长度
 */
function strlen_ansi($string, $ansi_width = 1)
{
    if (empty($string)) return 0;
    $data = str_split_utf8($string);
    if (empty($data)) return 0;
 
    $as = 0;
    foreach($data as $k => $v)
        $as += strlen($v) > 1 ? $ansi_width : 1;
    unset($data);
    return $as;
}

/**
 * smarty truncate 代码算法来自于Smarty
 * @param string
 * @param integer
 * @param string
 * @param boolean
 * @param boolean
 * @return string
 */
function truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false)
{
    if ($length == 0)
        return '';
    $ansi_as = 2;
    if (strlen_ansi($string, $ansi_as) > $length) {
        $length -= min($length, strlen_ansi($etc, $ansi_as));
        if (!$break_words && !$middle) {
            $string = preg_replace('/\s+?(\S+)?$/u', '', substr_ansi($string, 0, $length+1, $ansi_as));
        }
        if(!$middle) {
           return substr_ansi($string, 0, $length, $ansi_as) . $etc;
        } else {
            return substr_ansi($string, 0, $length/2, $ansi_as) . $etc . substr_ansi($string, -$length/2, 0,  $ansi_as);
        }
    } else {
        return $string;
    }
}
// substr_ansi ($offset, $length, $ansi_width)
// 如果ansi_width = 2,则表示将汉字当做2个宽度处理
// offset length 在实际截取过程中,以英文的长度为准即可

echo substr_ansi('汉字我爱你', 0, 5, 2);     //输出:汉字我
echo substr_ansi('汉字abc我爱你', 0, 5, 2);  //输出:汉字a
echo substr_ansi('abcdef', 0, 5, 2);        //输出:abcde

echo mb_substr('汉字我爱你', 0, 5);          //输出:汉字我爱你
echo mb_substr('汉字abc我爱你', 0, 5);       //输出:汉字abc
echo mb_substr('abcdef', 0, 5);             //输出:abcde

命令行获取ip地址

 curl http://ip.3322.net/ 
curl -4 -s icanhazip.com  
curl myip.ipip.net 
curl ip.cn 
curl httpbin.org/ip 
curl https://www.v2ex.com/ip | grep "ip="  
curl ifconfig.io 
curl ifconfig.me 
curl http://ip.taobao.com/service/getIpInfo2.php?ip=myip

颜值计算类

 

/**
* 排名算法
*/
class Rank
{
    private static $K = 32;
    private static $db;        //数据库连接对象
    function __construct()
    {
        require_once 'DBMysql.php';
        self::$db = DBMysql::connect();
    }

  //根据id值查询颜值
    public function queryScore($id)
    {
        $sql = "SELECT * FROM stu WHERE `id` = $id";
        $info = mysqli_fetch_assoc(self::$db->query($sql));
        return $info['score'];
    }
    //更新颜值
    public function updateScore($Ra,$id)
    {
        self::$db->query("UPDATE `stu` SET `score` = $Ra WHERE `id` = $id");
    }

  //计算二者的胜率期望值
    public function expect($Ra,$Rb)
    {
        $Ea = 1/(1+pow(10,($Rb-$Rb)/400));
        return $Ea;
    }

    //计算最后得分
    public function calculateScore($Ra,$Ea,$num)
    {
        $Ra = $Ra + self::$K*($num-$Ea);
        return $Ra;
    }

  //获取本次参与评选的两位美女id,以及获胜方id:0,1
    public function selectStu()
    {
        $id1 = $_POST['stu1'];
        $id2 = $_POST['stu2'];
        $victoryid = $_POST['vid'];
        return $this->getScore($id1,$id2,$victoryid);
    }

  //计算得分
    public function getScore($id1,$id2,$victoryid)
    {
        $Ra = $this->queryScore($id1);
        $Rb = $this->queryScore($id2);
        if ($Ra & $Rb) {
            $Ea = $this->expect($Ra, $Rb);
            $Eb = $this->expect($Rb, $Ra);
            $Ra = $this->calculateScore($Ra, $Ea, 1-$victoryid);
            $Rb = $this->calculateScore($Rb, $Eb, $victoryid);
            $Rab = array($Ra,$Rb);
            $this->updateScore($Ra, $id1);
            $this->updateScore($Rb, $id2);
            return $Rab;
        } else {
            return false;
        }
    }
}
$Rank = new Rank();
$Rank->selectStu();

第二个数组按第一个数组的键值排序

$a = [
    'id',
    'name',
    'identityId',
    'phone',
    'email',
    'schoolId'
];

$b = [
    'id' => '唯一标识',
    'identityId' => '身份证',
    'phone' => '手机号',
    'email' => '邮箱',
    'name' => '姓名',
    'schoolId' => '学校'
];

var_dump(array_merge(array_flip($a), $b));
$arr1 = array(
    'id',
    'name',
    'identityId',
    'phone',
    'email',
    'schoolId'
);
$arr2 = array(
    'id' => '唯一标识',
    'identityId' => '身份证',
    'phone' => '手机号',
    'email' => '邮箱',
    'name' => '姓名',
    'schoolId' => '学校',
);
array_multisort($arr1,SORT_DESC,$arr2);
print_r($arr2);
// 结果为:
Array
(
    [schoolId] => 学校
    [email] => 邮箱
    [identityId] => 身份证
    [phone] => 手机号
    [id] => 唯一标识
    [name] => 姓名
)
$c = array();
foreach ($a as $value) $c[$value] = $b[$value];
print_r($c);

正则

[] 的意思匹配指定字符,而不是字符串
(string1|string2) 才是匹配多个字符串
(?! string1) 匹配 非 字符串

$text = "<form name='loginpageform' method='post' action='www.baidu.com'>";
$pattern="/<.*?[input|textarea|select].*?>/i";///<.*?(input|textarea|select).*?>/is
preg_match($pattern1,$text,$matches);
var_dump($matches);


//正则
$p = '#<p(?<p>.*?)>(?<text1>.*?)(?<img>\<img.*?>)(?<text2>.*?)</p>#is';
//替换
$r = '<p$1>$2$4</p><figure>$3</figure>';
//原内容
$s = '<p class="asas">fsdfsdfsf<img src="" >kolja;<span>a</span>d;lasd</p>';

echo preg_replace($p, $r, $s);

// 结果:
// <p class="asas">fsdfsdfsfkolja;<span>a</span>d;lasd</p><figure><img src="" ></figure>

$s = '<p class="asas">fsdfsdfsf<img src="1" />kolja;<span>a<img src="2" ></span>d;lasd</p>asdaa<p><img src="3"></p>';

echo preg_replace_callback('#<p(?<p>.*?)>(?<text>.*?)</p>#is', function($matches) {
    preg_match_all('#<img.*?>#is', $str = $matches[0], $matches1, PREG_OFFSET_CAPTURE );
    foreach (array_reverse($matches1[0]) as $v)
        $str = substr_replace($str, '', $v[1], strlen($v[0]));
    return $str.'<figure>'.implode('',array_map(function($v){return $v[0];}, $matches1[0])).'</figure>';
}, $s);//https://segmentfault.com/q/1010000007018039

never use '+1 month' and '-1 month' in strtotime

>>> date('Y-m-28',  strtotime("2016-12-31 -1 month"))
=> "2016-12-28"
>>> date('Y-m-28',  strtotime("2016-01-31 +1 month"))
=> "2016-03-28"
>>> date('Y-m-d',  strtotime("2016-01-31 first day of +1 month"))
=> "2016-02-01"
$d = new DateTime('2015-01-31');
$d->modify('first day of next month');
echo $d->format('Y-m-28');
$d = new DateTime('2015-01-31');
$d->modify('first day of next month');
echo $d->format('Y-m-28');
MySQL: DATE_ADD('2011-01-31', INTERVAL 1 MONTH) returns 2011-02-28

浮点数


>>> (1400.20-1400)*100
=> 20.000000000005
>>> bcmul((1400.26-1400),100)
=> "25"
>>> 1400.26-1400
=> 0.25999999999999
>>> bcsub(1400.26,1400,2)
=> "0.26"
>>> $b=79.99
=> 79.99
>>> floor($b*100)
=> 7998.0
>>> floor(bcmul($b,100))
=> 7999.0
>>> floor(round($b*100))
=> 7999.0

php里简单的对称加密算法


$content = "大家好,我是中国人,你是谁";

    /**
     * 简单对称加密算法之加密
     * @param String $string 需要加密的字串
     * @param String $skey 加密EKY
     * @return String
     */
    function encode($string = '', $skey = 'wenzi') {
        $strArr = str_split(base64_encode($string));
        $strCount = count($strArr);
        foreach (str_split($skey) as $key => $value)
            $key < $strCount && $strArr[$key].=$value;
        return str_replace(array('=', '+', '/'), array('O0O0O', 'o000o', 'oo00o'), join('', $strArr));
    }

    /**
     * 简单对称加密算法之解密
     * @param String $string 需要解密的字串
     * @param String $skey 解密KEY
     * @return String
     */
    function decode($string = '', $skey = 'wenzi') {
        $strArr = str_split(str_replace(array('O0O0O', 'o000o', 'oo00o'), array('=', '+', '/'), $string), 2);
        $strCount = count($strArr);
        foreach (str_split($skey) as $key => $value)
            $key <= $strCount && $strArr[$key][1] === $value && $strArr[$key] = $strArr[$key][0];
        return base64_decode(join('', $strArr));
    }

    echo '<pre>';
    echo "string : " . $content . " <br />";
    echo "encode : " . ($enstring = encode($content)) . '<br />';
    echo "decode : " . decode($enstring);

使用 MPDF 将HTML转为PDF

$html = "对盲人初学者来说,它无需任何额外的修改。";
// $html = "These are the most used acronyms throughout this manual.";
include './mpdf/mpdf.php';
$mpdf=new mPDF('utf-8');   //这里改成UTF-8 即可 
$mpdf->autoScriptToLang = true;
$mpdf->autoLangToFont = true;
$mpdf->WriteHTML($html);
$mpdf->Output();

strtr vs str_replace

$arr = array('中国', '中国人'); //关键字
foreach($arr as $v) { $new[$v] = '<b>'.$v.'</b>'; }
var_export($new); //输出: array( '中国' => '<b>中国</b>', '中国人' => '<b>中国人</b>' )
$str = '我是中国人我爱中国';
echo strtr($str, $new)."\n"; //输出: 我是<b>中国人</b>我爱<b>中国</b>

//对比:str_replace会发生重复替换,下面代码会输出: 我是<b><b>中国</b>人</b>我爱<b>中国</b>
echo str_replace(array('中国人','中国'), array('<b>中国人</b>','<b>中国</b>'), '我是中国人我爱中国');

判断文件类型

$image=file_get_contents($url);
file_put_contents($imagePath, $image);   //将图片流存入服务器图片目录
$type=image_type_to_extension(exif_imagetype($imagePath));   //文件类型

$image = file_get_contents($url);

echo check_image_type($image);

function check_image_type($image)
{
    $bits = array(
        'JPEG' => "\xFF\xD8\xFF",
        'GIF' => "GIF",
        'PNG' => "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a",
        'BMP' => 'BM',
    );
    foreach ($bits as $type => $bit) {
        if (substr($image, 0, strlen($bit)) === $bit) {
            return $type;
        }
    }
    return 'UNKNOWN IMAGE TYPE';
}

$finfo = new finfo(FILEINFO_MIME_TYPE);
var_dump($finfo->file('t.jpg')); // ==> image/jpeg

php Unicode正则

$str=json_decode('"ux这\u202eわかぃまぃだDD"');
    var_dump($str);//string(28) "ux这‮わかぃまぃだDD"

    var_dump(preg_match('/^[\w\x{4e00}-\x{9aff}]{4,12}$/u', $str,$match));//int(0)
    var_dump($match);

数组order by

$arr = array(
 '中国' => array(
     '金牌' => 8,
     '银牌' => 3,
     '铜牌' => 6,
 ),
 '俄罗斯' => array(
     '金牌' => 3,
     '银牌' => 6,
     '铜牌' => 3,
 ),
 '美国' => array(
     '金牌' => 6,
     '银牌' => 8,
     '铜牌' => 8,
 ),
 '澳大利亚' => array(
     '金牌' => 4,
     '银牌' => 0,
     '铜牌' => 4,
 ),
 '意大利' => array(
     '金牌' => 3,
     '银牌' => 4,
     '铜牌' => 2,
 ),

);
// 实现 ORDER BY
foreach($arr as $k => $v) {
 $sort['金牌'][$k] = $v['金牌'];
 $sort['银牌'][$k] = $v['银牌'];
 $sort['铜牌'][$k] = $v['铜牌'];
}
array_multisort(
 $sort['金牌'], SORT_DESC, 
 $sort['银牌'], SORT_DESC, 
 $sort['铜牌'], SORT_DESC, 
 $arr);
var_export($arr);
arr = [
 {'name':'国家一','score':[10,7,5]},
 {'name':'国家二','score':[10,9,5]},
 {'name':'国家三','score':[11,7,5]},
 {'name':'国家四','score':[10,7,9]},
]

print sorted(arr, key=lambda a: '%03d%03d%03d' % tuple(a['score']), reverse=True)

base64图片处理

/**
 * 保存64位编码图片
 */

 function saveBase64Image($base64_image_content){

        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){

                  //图片后缀
                  $type = $result[2];

                  //保存位置--图片名
                  $image_name=date('His').str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT).".".$type;
                  $image_url = '/uploads/image/'.date('Ymd').'/'.$image_name;           
                  if(!is_dir(dirname('.'.$image_url))){
                         mkdir(dirname('.'.$image_url));
                        chmod(dirname('.'.$image_url), 0777);
                        umask($oldumask);

                  }
                 
                  //解码
                  $decode=base64_decode(str_replace($result[1], '', $base64_image_content));
                  if (file_put_contents('.'.$image_url, $decode)){
                        $data['code']=0;
                        $data['imageName']=$image_name;
                        $data['url']=$image_url;
                        $data['msg']='保存成功!';
                  }else{
                    $data['code']=1;
                    $data['imgageName']='';
                    $data['url']='';
                    $data['msg']='图片保存失败!';
                  }
        }else{
            $data['code']=1;
            $data['imgageName']='';
            $data['url']='';
            $data['msg']='base64图片格式有误!';


        }       
        return $data;


 }

php strtotime 获取上周一的时间

>>> date('Y-m-d H:i:s',strtotime('-2 monday'))
=> "2016-10-03 00:00:00"
$days = date('w')==0?13:date('w')+6;

echo date('Y-m-d',time()-$days*86400);
date('Y-m-d', strtotime('-' . (6+date('w')) . ' days'));

合并数组

$arr = array(
  '0' => array(
    'id' => 1,
    'count' =>1,
    ),
  '1' => array(
    'id' => 2,
    'count' =>1,
    ),
  '2' => array(
    'id' => 4,
    'count' =>1,
    ),
  '3' => array(
    'id' => 2,
    'count' =>1,
    ),
  );
$new = $news = $newss = array();
foreach ($arr as $key => $value) {
  
  if(!in_array($value['id'], $new)) {
    $new[] = $value['id'];  //$new保存不重复的id值
    $news[$key] = $value;   //$news保存不重复id的数组值
    $newss[$value['id']] = $key;  //$newss保存不重复的id的键值
  }else {
    $k = $newss[$value['id']];  //取出重复的id保存的第一个键值
    $count = (int)$news[$k]['count'];  //取出第一个相同id保存的count值
    $news[$k]['count'] = $count+1;     //赋值到新的数组
  }
}

var_dump($news);

https://github.com/iScript/YCms
https://phphub.org/topics/1759
http://blog.csdn.net/phpfengh...
https://phphub.org/topics/252...
http://www.xiabingbao.com/enc...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值