共计 24162 个字符,预计需要花费 61 分钟才能阅读完成。
https://cloud.tencent.com/dev… 电商 Sku 设计思维
https://xlswriter-docs.viest…. 借助 C 扩大来 解决百万 excel 文件的导入导出
https://juejin.im/post/686743… 数组巧用
https://juejin.im/post/684490… 起源不一样的数据分页
https://juejin.im/post/684490… curl_multi 并发申请
https://juejin.im/post/684490… 排查零碎为啥会运行迟缓
https://juejin.im/post/684490… 本地环境搭建 docker
集体微信音讯推送 http://sc.ftqq.com/?c=code
#php 调用代码
file_get_contents('https://sc.ftqq.com/SCU144549Te2356489fe44a621fd109f8f7484e9dd5ff2878ccf662.send?text=not_complete_sync_order 订单同步失败');
function sc_send($text , $desp = '', $key ='SCU144549Te2356489fe44a621fd109f8f7484e9dd5ff2878ccf662')
{
$postdata = http_build_query(
array(
'text' => $text,
'desp' => $desp
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
return $result = file_get_contents('https://sc.ftqq.com/'.$key.'.send', false, $context);
}
工夫范畴
// 获取今日开始工夫戳和完结工夫戳
$start = mktime(0,0,0,date('m'),date('d'),date('Y'));
$end = mktime(0,0,0,date('m'),date('d')+1,date('Y'))-1;
// 获取昨日起始工夫戳和完结工夫戳
$beginYesterday = mktime(0,0,0,date('m'),date('d')-1,date('Y'));
$endYesterday = mktime(0,0,0,date('m'),date('d'),date('Y'))-1;
// 获取上周起始工夫戳和完结工夫戳
$beginLastweek = mktime(0,0,0,date('m'),date('d')-date('w')+1-7,date('Y'));
$endLastweek = mktime(23,59,59,date('m'),date('d')-date('w')+7-7,date('Y'));
// 获取本月起始工夫戳和完结工夫戳
$beginThismonth=mktime(0,0,0,date('m'),1,date('Y'));
$endThismonth=mktime(23,59,59,date('m'),date('t'),date('Y'));
strtotime(date('Y-m-d 9:30:00',time()));
laravel whereor 查问
$extra = $params['extra'];
$handle->where(function ($query) use ($extra) {$query->where('admin_name', 'like', "%$extra%")->orWhere('title', 'like', "%$extra%");
});
array_walk 和 array_map && array_reduce && array_filter && array_flip 应用
#array walk 以援用传递的模式遍历你的数组,没有返回值,而且只能解决一个数组
$arr = ['a', 'b', 'c'];
array_walk($arr, function (&$item) {$item = $item . '_i';});
print_r($arr); // ['a_i', 'b_i', 'c_i'];
#array_map 应用匿名函数的形式,解决数组里的每个元素。遍历实现后返回一个新的数组, 并且能够同时解决多个数组
$arr_1 = ['a', 'b', 'c'];
$arr_2 = ['你', '好', '吗', '原', '罪'];
$arr = array_map(function ($item_1, $item_2) {return $item_1 . '_' . $item_2 . '_i';}, $arr_1, $arr_2); 如果须要获取下标的能够应用 array_keys($arr_1)代替 $arr_2
print_r($arr); // ['a_你_i', 'b_好_i', 'c_吗_i', '_原_i', '_罪_i']
#array_reduce() 函数向用户自定义函数发送数组中的值,并返回一个字符串。$arr = [
0 => '全副',
1 => 'a',
2 => 'b',
3 => 'c',
];
$index = 0;
$options = array_reduce($arr, function($carry, $item) use (&$index){
## $index 则为以后两个元素 $item 的索引
return $carry . '<option value="' . $index++ . '">' . $item . '</option>';
}, '');
var_dump($options);return;
#过滤数组中的内容
$data = [[ 'id' => 1, 'name' => '你好,234', 'cate' => '生存日记'],
['id' => 2, 'name' => '79798', 'cate' => '摄影美图'],
['id' => 3, 'name' => '567567', 'cate' => '生存日记'],
];
$filtered = array_filter($data, function($item){return $item['cate'] !== '摄影美图';
});
print_r($filtered);return;
#翻转数组去重
array_flip (array_flip($trans));
#移除数组中反复的值:array_unique($arr);
#array_flip 和 array_unique 区别 array_flip 会保留反复值最初一个,array_unique 只保留反复值的第一个
数组遍历思维
== 数组嵌套循环的时候最内层的遍历完之后指针为空才开始向外层一层一层遍历直到指针遍历完改层数组 ==
==foreach()嵌套 foreach 都会先把自身 {} 内的循环完, 再进行下一次循环,从里往外开始 ==
== 数组元素多的嵌套数组元素少的。小倡议 ==
== 循环从上往下 从左往右。循环套循环的, 程序执行到外面一次要循环完了,里面的才会进行第二次循环 ==
php 解决大数文件问题
尽可能应用文件操作,不要间接导入到数组库,过程很慢
php 操作大数组缩小内存办法
<?php
$start_mem = memory_get_usage();
function yield_range($start, $end){while( $start <= $end){
$start++;
yield $start;
}
}
foreach(yield_range( 0, 9999) as $item ){echo $item.',';}
$end_mem = memory_get_usage();
echo "use mem :". ($end_mem - $start_mem) .'bytes'.PHP_EOL;
# 操作大文件
<?php
header("content-type:text/html;charset=utf-8");
function readTxt()
{
# code...
$handle = fopen("./test.txt", 'rb');
while (feof($handle)===false) {
# code...
yield fgets($handle);
}
fclose($handle);
}
foreach (readTxt() as $key => $value) {
# code...
echo $value.'<br />';
}
mysql 罕用查问
导出数据表构造阐明
// 首先抉择 mysql 外面的 information_schema 库
SELECT
COLUMN_NAME 字段名称,
COLUMN_TYPE 数据类型,
IS_NULLABLE 是否为空,
COLUMN_COMMENT 字段形容
FROM
COLUMNS
WHERE
TABLE_NAME = 'fr_activity_component' group by COLUMN_NAME ORDER BY ORDINAL_POSITION
// 执行后导出 excel
批改一个字段为随机数
update fr_topic set post_num = ceiling(rand()*3000+9000) WHERE 1=1
工夫戳转换
FROM_UNIXTIME(a.end_time) 格式化工夫
UNIX_TIMESTAMP('2006-11-04 12:23:00'); 格式化成工夫戳
把查问进去的一个后果集的 sql 某个字段用标识符宰割
SELECT GROUP_CONCAT(a.`sku_id` separator ',;cc') 账号 from fr_goods_sku a LEFT JOIN fr_goods b on a.goods_id =b.goods_id where b.type = 1 AND sku_image_url !='' limit 20;
子查问操作
DELETE from fr_users_bargain where user_id IN (SELECT user_id from (SELECT user_id,count(slash_id) as ids FROM fr_users_bargain where cate = 2 GROUP BY user_id HAVING ids > 1) ee)
json 问题 中文和反斜杠被本义
json_encode($post_data,JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)
curl 申请问题排查
$response = curl_exec($ch);
$errorno = curl_errno($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
先依据 curl_errno 查看状态码 而后去
https://www.php.net/manual/zh… 查看状态码的对应报错
读取大文件
读取大文件办法
<?php
function yieldCommand($fileName) {$line = [];
$handle = fopen($fileName, "r");
while (!feof($handle)) {yield ltrim(fgets($handle));
}
fclose($handle);
}
foreach (yieldCommand("name.txt") as $key => $value) {echo $value;}
require "memory.php"; ?>
装置 pcntl
https://icharle.com/macpcntl….
sudo wget https://www.php.net/distribut…
tar -zxvf php-7.1.26.tar.gz
cd php-7.1.26 && cd ext && cd pcntl
/Applications/MAMP/bin/php/php7.1.26/bin/phpize php –ini 找到装置的 php 门路 应用外面的 phpize 在 pcntl 目录下执行
/configure –with-php-config=/Applications/MAMP/bin/php/php7.1.2/bin/php-config
make && make install
php –ri swoole
php -i | grep php.ini
sudo wget https://www.php.net/distribut…
数组操作
if (!function_exists('hideStr')) {
/**
* [hideStar 用户名、邮箱、手机账号两头字符串以 * 暗藏]
* @param [string] $str [传过来字符串]
* @return [string] [返回带 * 字符串]
*/
function hideStr($str)
{if (strpos($str, '@')) {$email_array = explode("@", $str);
$prevfix = (strlen($email_array[0]) < 4) ? "" : substr($str, 0, 3);
$count = 0;
$str = preg_replace('/([\d\w+_-]{0,100})@/', '***@', $str, -1, $count);
$rs = $prevfix . $str;
} else {$pattern = '/(1[3458]{1}[0-9])[0-9]{4}([0-9]{4})/i';
if (preg_match($pattern, $str)) {$rs = preg_replace($pattern, '$1****$2', $str);
} else {$rs = substr($str, 0, 3) . "***" . substr($str, -1);
}
}
return $rs;
}
}
if (!function_exists('format_timestamp')) {function format_timestamp($timestamp, $format = "Y.m.d H:i:s")
{return $timestamp <= 0 ? '-' : date($format, (int)$timestamp);
}
}
if (!function_exists('get_countdown_second')) {function get_countdown_second($time)
{return $time - time() < 0 ? 0 : $time - time();}
}
if (!function_exists('get_countdown_second')) {function number_format($number, $flag = 2)
{return sprintf("%" . $flag . "f", $number);
}
}
/**
* 保留几位小数,向下取整
*$num 要解决的浮点数
*$digits 要保留的小数位数
* 实现思路:先乘以 10 的小数位数次方,用 floor 向下取整,再除以除数失去舍去前面位数的后果
* 最初再用 sprintf 配合位数再取一次值(此处是为了解决有些数字属,最初一位为零时不显示问题)*/
if (!function_exists('floorFloat')) {function floorFloat($num, $digits)
{$num = floatval($num);
$multiple = pow(10, $digits);
$tempNum = floor($num * $multiple);
return sprintf('%.' . $digits . 'f', $tempNum / $multiple);
}
}
二维数据进行排序
if(!function_exists('arraySequence')){
/**
* 二维数组依据字段进行排序
* @params array $array 须要排序的数组
* @params string $field 排序的字段
* @params string $sort 排序程序标记 SORT_DESC 降序;SORT_ASC 升序
*/
function arraySequence($array, $field, $sort = 'SORT_ASC')
{$arrSort = array();
foreach ($array as $uniqid => $row) {foreach ($row as $key => $value) {$arrSort[$key][$uniqid] = $value;
}
}
array_multisort($arrSort[$field], constant($sort), $array);
return $array;
}
}
二维数组转一维数组 array_column();
二维数组去重
function remove_duplicate($array){$result=array();
foreach ($array as $key => $value) {
$has = false;
foreach($result as $val){if($val['id']==$value['id']){
$has = true;
break;
}
}
if(!$has)
$result[]=$value;}
return $result;
}
过滤一个数组在另一个数组中呈现的。var arr1 = ["i", "b", "c", "d", "e", "f","x"]; // 数组 A
var arr2 = ["a", "b", "c", "d", "e", "f", "g"];// 数组 B
var temp = []; // 长期数组 1
var temparray = [];// 长期数组 2
for (var i = 0; i < arr2.length; i++) {temp[arr2[i]] = true;// 奇妙中央:把数组 B 的值当成长期数组 1 的键并赋值为真
}
for (var i = 0; i < arr1.length; i++) {if (!temp[arr1[i]]) {temparray.push(arr1[i]);// 奇妙中央:同时把数组 A 的值当成长期数组 1 的键并判断是否为真,如果不为真阐明没反复,就合并到一个新数组里,这样就能够失去一个全新并无反复的数组
}
}
document.write(temparray.join(",") + "");
/*
* 计算倒计时
* @param unix 工夫格局
* @return string
*/
function dealTime($endTime) {$t = $endTime - time();
if ($t <= 0) return '';
$str = '';
if ($t > 86400) {$days = floor($t / 86400);
$t = $t - (86400 * $days);
$str .= $days . '天';
}
if ($t > 3600) {$hours = floor($t / 3600);
$t = $t - (3600 * $hours);
$str .= $hours . '时';
}
if ($t > 60) {$minu = floor($t / 60);
$t = $t - (60 * $minu);
$str .= $minu . '分';
}
$str .= $t . '秒';
return $str;
}
/**
* 暗藏局部电话号码,手机号暗藏两头四位
* @param strint $phone
* @return string
*/
function hidetel($phone){$IsWhat = preg_match('/(0[0-9]{2,3}[-]?[2-9][0-9]{6,7}[-]?[0-9]?)/i', $phone); // 固定电话
if ($IsWhat == 1) {return preg_replace('/(0[0-9]{2,3}[-]?[2-9])[0-9]{3,4}([0-9]{3}[-]?[0-9]?)/i','$1****$2', $phone);
} else {return preg_replace('/(1[35678]{1}[0-9])[0-9]{4}([0-9]{4})/i','$1****$2', $phone);
}
}
/**
* 随机生成色彩值
*
*
*/
function randcol()
{
$str='0123456789ABCDEF';
$estr='#';
$len=strlen($str);
for($i=1;$i<=6;$i++)
{$num=rand(0,$len-1);
$estr=$estr.$str[$num];
}
return $estr;
}
/**
* 将 xml 转为 array
* @param string $xml xml 字符串或者 xml 文件名
* @param bool $isfile 传入的是否是 xml 文件名
* @return array 转换失去的数组
*/
function xmlToArray($xml,$isfile=false){
// 禁止援用内部 xml 实体
libxml_disable_entity_loader(true);
if($isfile){if(!file_exists($xml)) return false;
$xmlstr = file_get_contents($xml);
}else{$xmlstr = $xml;}
$result= json_decode(json_encode(simplexml_load_string($xmlstr, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $result;
}
/**
* 数组转 xml 字符
* @param string $xml xml 字符串
**/
function arrayToXml($data){if(!is_array($data) || count($data) <= 0){return false;}
$xml = "<xml>";
foreach ($data as $key=>$val){if (is_numeric($val)){$xml.="<".$key.">".$val."</".$key.">";}else{$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
htmlspecialchars,strip_tags 来过滤 html,js 代码
设计模式
__get __call abstract 灵活运用实例 编写通用 SDK
1. 利用__get 获取没有定义的变量而后来通过__call 调用未知办法
2.abstract 的子类定义的变量 是能够笼罩 父类的定义的变量
3.abstract 外面放子类外面专用的代码
$shopify = PHPShopify\ShopifySDK::config($config);
$products = $shopify->Product->get(['fields'=>'id,images,title']);
public static $config = array(
);
public function __construct($config = array())
{if(!empty($config)) {ShopifySDK::config($config);
}
}
public function __get($resourceName)
{return $this->$resourceName();
}
public function __call($resourceName, $arguments)
{if (!in_array($resourceName, $this->resources)) {if (isset($this->childResources[$resourceName])) {$message = "$resourceName is a child resource of" . $this->childResources[$resourceName] . ". Cannot be accessed directly.";
} else {$message = "Invalid resource name $resourceName. Pls check the API Reference to get the appropriate resource name.";}
throw new SdkException($message);
}
$resourceClassName = __NAMESPACE__ . "\\$resourceName";
//If first argument is provided, it will be considered as the ID of the resource.
$resourceID = !empty($arguments) ? $arguments[0] : null;
//Initiate the resource object
$resource = new $resourceClassName($resourceID);
return $resource;
}
abstract class ShopifyResource{
/**
* @inheritDoc
*/
public $resourceKey;
/**
* @inheritDoc
*/
protected $childResource;
public function __construct($id = null, $parentResourceUrl = '')
{
$this->id = $id;
$config = ShopifySDK::$config;
}
}
class Product extends ShopifyResource
{
/**
* @inheritDoc
*/
public $resourceKey = 'product';
/**
* @inheritDoc
*/
protected $childResource = array(
'ProductImage' => 'Image',
'ProductVariant' => 'Variant',
'Metafield',
'Event'
);
}
<?php
/**
* 事件产生类
* Class EventGenerator
*/
abstract class EventGenerator
{private $ObServers = [];
// 减少观察者
public function add(ObServer $ObServer)
{$this->ObServers[] = $ObServer;
}
// 事件告诉
public function notify()
{foreach ($this->ObServers as $ObServer) {$ObServer->update();
}
}
}
/**
* 观察者接口类
* Interface ObServer
*/
interface ObServer
{public function update($event_info = null);
}
/**
* 观察者 1
*/
class ObServer1 implements ObServer
{public function update($event_info = null)
{echo "观察者 1 收到执行告诉 执行结束!\n";}
}
/**
* 观察者 1
*/
class ObServer2 implements ObServer
{public function update($event_info = null)
{echo "观察者 2 收到执行告诉 执行结束!\n";}
}
/**
* 事件
* Class Event
*/
class Event extends EventGenerator
{
/**
* 触发事件
*/
public function trigger()
{
// 告诉观察者
$this->notify();}
}
// 创立一个事件
$event = new Event();
// 为事件减少旁观者
$event->add(new ObServer1());
$event->add(new ObServer2());
// 执行事件 告诉旁观者
$event->trigger();
Yii 框架
多图上传
https://blog.csdn.net/zbc4962…值得学习博客:http://www.yiichina.com/exten…
中文文档 http://www.yii-china.com/doc/…
白狼寨GridView http://blog.csdn.net/myhuashe…
use common\widgets\ImgMultUpload;
<?= ImgMultUpload::widget(['label' => '产品图片', 'imgarr'=>['12321.jpg'],'imagedir' => '/uploads/temp/']); ?>
引入类办法:
①Yii::$classMap['类名']=>'@app/libs/ 文件名'; 映射类,在 controller 中调用
use 类名;可立刻应用; 此类中不须要写 namespace
②在 config 数组中退出 aliases=>['@test'=>@app/ 文件夹];test 代表前面的链接,别名引入类。use 别名 \ 类名;可立刻应用。此类中须要写 namespace
打印以后所执行的 sql
echo $query->createCommand()->getRawSql();die;
params 文件夹中配置写常常变动的内容:key =>value 模式展现
Yii::$app->param['key']获取参数 value 值。composer 装置 yii 框架 装置好之后进入 yii 框架中进行 composer install 装置 vendor 目录
controller 操作留神:
申请参数: $request=Yii:$app->request; $request->get(); $request->post();
$request->bodyParams(); 能够获取任何类型以及所有的参数
$request->getBodyParam('id')特定的获取某个参数
render renderPartial 不会渲染模板。注意事项:①模型类,需引入 use Yii;ActiveRecord 类用。Controller 申明须要留神 actionIndex 办法名必须是驼峰式的,action 来申明是能够跳转的办法
migrate 生成数据库
① 在根目录生成 migrations 目录生成对应的文件 yii migrate/create test
②批改 test 文件,两头引入 yii\db\Schema, 利用 Schema 来生成表的和构造
③最初应用 yii migrate 来生成对应的数据库。yii 框架中设置别名
在 web.php 外面 设置 Yii::setAlias('@bar','www.baidu.com');
取出 Yii::getAlias('@bar');
gii,debug 拜访不到,起因可能是继承 Controller, 默认拜访的是 r =index, 所以导致路由不到。丑化 url: 将 urlmanager 写到 components 数组中(此办法临时不能失常应用)'urlManager' => [
'enablePrettyUrl' => true, // 是否启用丑化 url pathinfo 模式
// 就必须增加扩展名
'showScriptName' => false, // 是否显示脚本名
'rules' => [],],
应用以上的办法 UrlManager 管制路由,导致 Url::to([]); 办法不能失常应用,解决办法:在入口文件平级目录创立.htaccess 文件,内容如下:Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
yii-debug
显示在页面中加 <?php $this->endBody;?>, 将显示 xdebug
原理:yii\web\View 中有 endBody 的触发事件,回去触发 bootstarp,注册插件,从而将大量的 debug 款式加载到页面 上,图标因而呈现。时区显示不正确,在 web.config 中增加 'timeZone' => 'Asia/Shanghai',
__DIR__ 当前目录 不蕴含文件名字 dirname(__DIR__) 当前目录的 dir
例如:E:\project\yii\controllers E:\project\yii
__FILE__ 以后文件门路 蕴含文件名字 dirname(__FILE__) 所蕴含以后文件的文件夹
例如:E:\project\yii\controllers\IndexController.php E:\project\yii\controllers
配置空页面的跳转办法 web.php 中配置的有。'errorHandler' => ['errorAction' => 'site/error',],
控制器中须要申明下 public function actions()
{
return [
'error' => ['class' => 'yii\web\ErrorAction',],
];
}
拜访的页面不在的话就 跳转到该视图,将此封装到根底控制器中缩小代码
设置办法返回格局
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
组件 component
在配置文件 component 中加 key => 类的命名空间, 注册后才用 Yii::$app-> key-> 类中办法。即可实现全局拜访的成果。多数据库链接(判断以后数据库)/**
* 设置模型获取数据库链接
* */
public static function getDb(){return Yii::$app->get('db_spkx');
}
google 插件
jsonview 滑词翻译 apizza octotree Infinity wappalyzer gitpod
Infinity 账号 2233850112@qq.com 14adb1
composer
composer config repo.packagist composer https://mirrors.aliyun.com/co… 阿里云源
composer config repo.packagist composer https://packagist.phpcomposer… composer 部分申明源
composer selfupdate 更新 phar.
https://github.com/zoujingli/… 通用后盾开发框架
https://github.com/geesondog/… 联合 tp5 微信开发
https://demo.fastadmin.net 联合 tp5 后盾疾速开发(插件化 免费)
https://tencent.github.io/wepy/ 开发小程序框架
composer 命令大全
https://getcomposer.org/doc/0…
罕用 composer 库
composer require nesbot/carbon 工夫距离
composer require guzzlehttp/guzzle curl 申请
composer require yansongda/pay 微信领取包 riverslei/payment
composer require katzgrau/klogger:dev-master 解决日志类
“phpoffice/phpword”: “v0.13.*” 生成 word 文件
composer require league/fractal 简单输入 ajax 和 restful
composer require phpmailer/phpmailer 邮件解决类
账号 15239851762@163.com 163 测试 发送明码填写 smtp 的受权明码 smallsha666 端口 465
composer require overtrue/easy-sms 短信解决类
https://segmentfault.com/a/11… 图片解决类
filp/whoops
catfan/medoo
twig/twig
sysfony
composer 操作
composer depends ak_smallsha/application -t
获取以后 composer 中的无关以后包的扩大
composer config –list 查看以后包的配置信息
composer search 包 查问 composer 中包
composer show aferrandini/* 查问以后我的项目中的包
composer clear-cache 下载包呈现问题首先执行该命令
composer init –require = ak_smallsha/application -n
创立一个新的 composer.json 包并且增加依赖
可能的少应用 comoser update -vvv 导致更新最新版本,我的项目不兼容。
每次引入类库后,将 composer.json 和 composer.lock 上传到 github 上。
composer dump-autoload -o 之后,composer
就会提前加载须要的类并提前返回。这样大大减少了 IO 和深层次的 loop。
composer clear-cache 革除缓存
composer install – 如有 composer.lock 文件,间接装置,否则从
composer.json 装置最新扩大包和依赖;
composer update – 从 composer.json 装置最新扩大包和依赖;
composer update vendor/package – 从 composer.json 或者对应包的配置,并更新到最新;
composer require new/package – 增加装置 new/package, 能够指定版本,如:composer require new/package ~2.5.
代码上传到 packlist https://www.cnblogs.com/zhang…
http://blog.csdn.net/hel12he/… 在 packlist 自动更新 github 上的包
公布本人的 composer 包
composer 是什么
Composer 不是一个包管理器。是的,它波及“packages”和“libraries”,但它在每个我的项目的根底上进行治理,在你我的项目的某个目录中(例如 vendor)进行装置。默认状况下它不会在全局装置任何货色。因而,这仅仅是一个依赖治理。Composer 受到了 node’s npm 和 ruby’s bundler 的强烈启发。而过后 PHP 下并没有相似的工具。composer 能够做什么
Composer 将这样为你解决问题:你有一个我的项目依赖于若干个库。其中一些库依赖于其余库。你申明你所依赖的货色。Composer 会找出哪个版本的包须要装置,并装置它们(将它们下载到你的我的项目中)。零碎学习 composer 的应用请移步 composer 中文学习
开发本人的 composer 组件
要点:了解 composer 如何实现主动加载第三方组件; 了解 psr- 0 和 psr- 4 的标准; 了解基于 psr-0,psr-4,classmap,files 如何实现主动加载。了解 Composer 和 Packagist
对于装置和应用 composer 请参考 composer 中文学习
创立目录名称
mkdir try-make-package
cd try-make-package
这个 try-make-package 文件夹就是你的包的根目录了,你只须要记住 composer.json 在包的哪个目录上面,个别那就是包的根目录了。当初咱们还没有 composer.json 文件,上面咱们来初始化
初始化扩大包
☁ composer init
Welcome to the Composer config generator
This command will guide you through creating your composer.json config.
Package name (<vendor>/<name>) [lingan/try-make-package]:
Description []: try make a package
Author [saboran <saboran@163.com>, n to skip]:
Minimum Stability []: dev
Package Type (e.g. library, project, metapackage, composer-plugin) []: library
License []: MIT
Define your dependencies.
Would you like to define your dependencies (require) interactively [yes]? n
Would you like to define your dev dependencies (require-dev) interactively [yes]? n
{
"name": "lingan/try-make-package",
"description": "try make a package",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "saboran",
"email": "saboran@163.com"
}
],
"minimum-stability": "dev",
"require": {}}
Do you confirm generation [yes]? yes
通过一番下面的挣扎在当前目录就生成了 composer.json 文件,上面咱们对这个文件进行一些批改
批改 composer.json 减少主动加载标准 (命名空间和目录映射关系) 和环境要求
{
"name": "lingan/try-make-package",
"description": "try make a package",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "saboran",
"email": "saboran@163.com"
}
],
"minimum-stability": "dev",
"require": {"php": ">=7.0"},
"autoload": {
"psr-4": {
"Flower\\Rose\\": "src/Flower/Rose",
"Flower\\Lily\\": "src/Flower/Lily"
}
}
}
创立类文件
依据下面的命名空间和目录的映射关系,创立对应目录和文件,如下图
对应文件内容
<?php
/**
* Created by PhpStorm.
* User: Lingan
* Date: 2017/11/6
* Time: 21:39
*/
namespace Flower\Rose;
class Rose
{public function desc()
{echo "this is rose flower";}
}
<?php
/**
* Created by PhpStorm.
* User: Lingan
* Date: 2017/11/6
* Time: 21:38
*/
namespace Flower\Lily;
class Lily
{public function desc()
{echo "this is lily flower";}
}
测试装置
以上代码都梳理结束后,须要 composer install 来测试咱们的包是否能够失常工作此时会在 vendor/composer/autoload_psr4.php 中生成命名空间和目录的映射关系,被包在一个数组中:<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array('Flower\\Rose\\' => array($baseDir . '/src/Flower/Rose'),
'Flower\\Lily\\' => array($baseDir . '/src/Flower/Lily'),
);
减少.gitignore 为 git 疏忽一些文件, 减少 readme.md 为我的项目减少形容
.idea
vendor/
composer.lock
提交代码到 github
当初本人的 Github 主页上创立一个新的仓库而后将我的项目提交到对应仓库,参考如下
git init
git add -A
git commit -am "init && dev package"
git remote add origin git@github.com:linganmin/try-make-package.git
git push -u origin master
登录本人的 packagist submit(本人注册)
将本人的我的项目地址粘贴
点击 check,而后点击 submit,至此,本人的 composer 包就提交胜利了,测试应用本人开发的包扩大[2017.11.07 更新]
创立测试目录
mkdir test-my-package
cd test-my-package
装置本人的扩大
composer require lingan/try-make-package dev-master
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing lingan/try-make-package (dev-master d7b9f94): Cloning d7b9f941b0 from cache
Writing lock file
Generating autoload files
装置实现的目录如下图
查看 autoload_psr4.php
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array('Flower\\Rose\\' => array($vendorDir . '/lingan/try-make-package/src/Flower/Rose'),
'Flower\\Lily\\' => array($vendorDir . '/lingan/try-make-package/src/Flower/Lily'),
);
新建首页入口文件 index.php,开始测试本人写的包
<?php
/**
* Created by PhpStorm.
* User: Lingan
* Date: 2017/11/7
* Time: 11:04
*/
require_once './vendor/autoload.php'; // 加载主动加载文件
use Flower\Rose\Rose;
use Flower\Lily\Lily;
$rose = new Rose();
$lily = new Lily();
echo $rose->desc();
echo "\n";
echo $lily->desc();
执行
php index.php
this is rose flower
this is lily flower%
* 至此阐明咱们本人开发的扩大包能够失常应用
设置 Packagist 上自动更新扩大包,即当咱们更新扩大包提交到 GitHub 时,Packagist 自动更新
在没有设置自动更新时,Packagist 上包详情页会有这样一个提醒
This package is not auto-updated. Please set up the GitHub Service Hook for Packagist so that it gets updated whenever you push!(这个软件包不是自动更新的。请为 Packagist 设置 GitHub 服务钩,以便在您推送时更新!)
具体设置自动更新软件包的文档地址
简化步骤如下:去集体核心页面拿到本人的 api 令牌
去以后包在 GitHub 的地址,点击设置,点击集成和服务,点击增加 Packagist 服务并配置你的 API 令牌,以及你的 Packagist 用户名和账号对应域名
抉择 active,点击 add service
设置自动更新完结,之后你更改了本人包扩大的代码提交到 GitHub 后,很短的时间差就会同步到 Packagist
laravel
http://laravel-admin.org/ laravel-admin
https://www.jianshu.com/p/18d…
数据库迁徙
http://laravelacademy.org/pos…
数据库操作
http://laravelacademy.org/pos…
http://blog.csdn.net/ks3ks/ar…
权限 RBAC
https://packagist.org/package…
分页
http://laravelacademy.org/pos…
我的项目
https://www.bandari.net/blog laravel 整合 workerman
队列
http://blog.csdn.net/chen5298…
外围一 Facade
不便开发者间接用静态方法调用,放慢开发速度,不须要依靠服务器容器。创立 facade 步骤 1 先写好本人的办法
步骤 2 编写 providers 能够应用 php artisan make:provider 生成服务提供者
public function register()
{
将写好的办法注册到 ajaxResponse;
$this->app->singleton('ajaxResponse', function () {return new \App\Services\ajaxResponse();
});
}
步骤 3 编写 facades
class AjaxResponseFacade extends Facade
{protected static function getFacadeAccessor()
{return 'ajaxResponse';}
}
步骤 4 进入 config/app.config
在 providers 数组中编写 将服务提供者 provides ::class 注册进去
步骤 5
在 aliases 中将编写好的门面 放入。不便调用。++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
外围二 服务器容器
服务容器 应用命名空间引入类,而后将名称注入到 __construct 或者是办法名中,申明变量,将注入的类指定到变量中,此办法雷同于 yii 框架的组件化。++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
外围三 contracts 契约 次要是缩小代码的冗余
①首先编写一个接口 contracts 接口类
②在编写本人的要实现性能 implement 继承接口类
③开始编写 provider , 实现 register 办法
public function register()
{
// 给这个接口一个别名
$this->app->bind('Hello','App\Contracts\Hello');
// 将 Contract 接口和它的实现类绑定
$this->app->bind
('App\Contracts\Hello','App\Services\helloWorld');
}
④而后将此 provider 放入到 config\app.php 中
⑤在类中调用应用服务容器的办法进行调用
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
laravel 文档
博客 http://www.cnblogs.com/itfenqing/category/1010078.html
小下博客 https://www.linganmin.com/show/59
韩天峰博客 http://rango.swoole.com/archives/519
laravle 中文手册:http://d.laravel-china.org/docs/5.4 速查:https://cs.laravel-china.org/
http://laravelacademy.org/post/7930.html smartApi 我的项目
https://github.com/JJJJJJJerk/laravel-passport-admin-stock-loan laravel5.5
=====================================================================
罕用 artisan 命令
php artisan make:controller PhotoController --resource --model=Photo
php artisan make:model User -m 生成模型并生成迁徙文件
=====================================================================
罕用 blade
{!! $name !!} 避免 xss 攻打
{{$name or $hello}} 三元运算符
=====================================================================
罕用组件
laravel-password oauth2 认证
https://www.jianshu.com/p/2988ba405b3b?from=timeline&isappinstalled=0
easywechat 网页受权
https://github.com/overtrue/laravel-wechat
https://github.com/overtrue
微信机器人 swoole
http://create.hanc.cc/vbot/docs/install.html
laravel-debugbar 监控 sql 和 route
http://laravelacademy.org/post/2774.html
默认会将 debugbar 增加到页面的 body 后,\Debugbar::disable(); 敞开
\Debugbar::enable(); 开启
config 外面 inject 设置 false 禁止渲染页面
==================================================================
常见问题
base 类中获取不到 session,起因
在 Laravel 以前的版本中,能够在控制器构造函数中获取 session 变量或者认证后的用户实例。在 Laravel 5.3 中,在控制器构造函数中不再可能间接获取到 session 变量或认证后的用户实例,因为中间件还未启动。依然有代替计划,那就是在控制器构造函数中应用 Closure 来间接定义中间件。请留神,在应用这个计划的时候,确保你所应用的 Laravel 版本高于 5.3.4:能够在构造方法中采纳以下办法获取:$this->middleware(function ($request, $next) {return $next($request);
});
base64 数据流图片解决办法
$base64_string= explode(',', $base64_string); // 截取 data:image/png;base64, 这个逗号后的字符
$data= base64_decode($base64_string[1]); // 对截取后的字符应用 base64_decode 进行解码
file_put_contents($url, $data); // 写入文件并保留
https://www.cnblogs.com/lyzg/p/6181055.html app()应用
https://www.onmpw.com/tm/xwzj/sjk_251.html mysql 查问判断
https://segmentfault.com/q/1010000009858793 422 ajax 解决
用户管理系统 php artisan make:auth -> php arisan migrate 呈现数据 unique 字节数过大,起因 laravel 采纳 utf8mb4 字符,mysql 默认是 utf-8. 解决办法在 app->provides->appprovide->boot 办法下退出 use Illuminate\Support\Facades\Schema; Schema::defaultStringLength(191);
php artisan vendor:publish --provider 命令蛊惑
swoole
swoole 博客 蕴含 mac 快捷软件
https://www.cnblogs.com/redir…
swoole 配置阐明
https://github.com/LinkedDest…
守护过程开启后,敞开采纳
http://blog.csdn.net/qq_33679…
swoole 成员博客
https://blog.csdn.net/u012979…
pecl 装置 swoole 呈现 sll
https://stackoverflow.com/que…
//nginx 设置第一发包和第二次发包 工夫期待
https://blog.csdn.net/jack___…
websocket 客户端断开状态码
https://www.javascriptcn.com/…
注意事项
查看 php.ini 地位 php -i|grep php.ini
查看是否含有 swoole.so cat /www/server/php/71/etc/php.ini| grep swoole.so
swoole_websocket_server php --ri swoole 查看 php 是否反对 swoole
服务器端绑定 ip 0.0.0.0 端口须要留神将阿里云的安全策略关上
客户端绑定 ip 39.106.59.83 端口号和服务器端绑定端口号统一
①代码中不要应用 sleep, 导致过程梗塞
②exit/die,导致 woker 过程退出
③register_shutdown_function 来捕捉致命谬误
④在回调函数中应用 try/catch, 否则程序异样,不反对 set_exception_handler
⑤连贯 redis,mysql 类型的连贯应该放到 OnWorkerStart 回调函数中
⑥引入文件 应用 include_once,require_once;
⑦worker 是隔离的,应用 swoole_table 将全局变量保存起来。⑧事件回调中所有的局部变量都会全副回收,全局变量须要本人 unset
⑨global,static,$_GET,$_POST,$GLOBALS 保留在 swoole_server 不会主动开释
⑩多过程的状况下,父过程应用 mt_rand, 子过程要应用 mt_srand。server 配置
dispatch_mode = 7 无论极其条件下工作都会及时处理