乱七八糟未分类
yield只能一维数组
杂项
十六进制( 以 0x 为前缀)或八进制(前缀为 0)。
PHP $_REQUEST 用于收集HTML表单提交的数据。
distinct机制 加mtime之后?
static关键字
当某个函数一旦完成时,它的所有的变量通常都会删除,然而,如果您希望有些局部变量不被删除,请使用static关键字
注:当您没有在函数外部定义时,该变量仍然是函数的局部变量。
<?php
function myTest()
{
static $x=0;
echo $x;
$x++;
}
myTest();
echo "<br />";
myTest();
echo "<br />";
echo $x;
?>
运行结果
0
1
PHP Notice: Undefined variable: x in /root/soft/playground/index.php on line 16
print_r()
print_r()会将把数组的指针移到最后边。使用 reset() 可让指针回到开始处。
foreach
foreach还可可用于对象和普通数组
如果对普通数组使用,请
foreach (array_expression as $value)
const define static global globals[]区别
前二者用于定义常量 区别可参考https://www.cnblogs.com/yszr/p/10549511.html
后三者用于定义变量 区别以后补
下载
当下载的时候,网络中是不会显示接口地址的,这时候在弹出的下载框里看地址
CSV
csv本质是逗号分隔的文本文件 且只会保留第一个sheet,所以更省资源
07版以后的Excel本质上是xml,是二进制文件
版本差异
PHP7.3.14会遇到preg_match太大的问题 而7.4似乎就没有这个问题了
解决方法 php数组名后面可以加空格 数组键名可以有空格
if (count($ret) > 2000 && count($ret) < 4000) {
$notIn['push_action.id'] = array_slice($ret, 0, 2000);
$notIn['push_action.id '] = array_slice($ret, 2000);
} elseif (count($ret) >= 4000 && count($ret) < 6000) {
$notIn['push_action.id'] = array_slice($ret, 0, 2000);
$notIn['push_action.id '] = array_slice($ret, 2000, 2000);
$notIn['push_action.id '] = array_slice($ret, 4000);
}
else {
$notIn['push_action.id'] = $ret;
}
排序 筛选 时间等各种方便的操作
看operation这个接口
数组索引
当进行某些删除操作时候如
unset($php[1]);
数组的key可能变成Array ( [0] => 0 [3] => 120 ) 此时可sort重建索引 或者和一个空数组array_merge
foreach结束后 itmm会保存最后一次的值
二维数组去重
$softs = array_unique($softs,SORT_REGULAR);
foreach 去除元素
我有一个简单的数组,其中包含所有国家/地区的名称以及每个国家/地区在我的网站上注册的用户总数.它是这样的:
Array (
[1] => Array ( [name] => Afghanistan [total] => 3 )
[2] => Array ( [name] => Albania [total] => 0 )
)
而且,我正在尝试删除拥有0个用户的数组元素(国家/地区).
我已尝试使用此代码,但它无法正常工作:
foreach($country as KaTeX parse error: Expected '}', got 'EOF' at end of input: row) { if (row[‘total’] == 0) {
unset($row);
}
}
这段代码有什么问题?
如果取消设置($row),则只删除局部变量.
而是获取密钥并删除它:
foreach ($country as $i => KaTeX parse error: Expected '}', got 'EOF' at end of input: row) { if (row[‘total’] == 0) {
unset(
c
o
u
n
t
r
y
[
country[
country[i]);
}
}
php数组的根基是关联数组
在理解一门语言之前 先确定其根基
比如php数组都是基于关联数组设计的,因而普通数组的 unique等操作,其key也是原来的。
空值的坑
array_column可能回返回
Array
(
[0] =>
[1] =>
)
这种数据 而empty判断会失效。处理办法array_filter
foreach之前记得empty判断
php一些奇淫异巧
$this->{$var}
$this->a = "hello";
$this->b = "hi";
$this->val = "howdy";
$val = "a";
echo $this->{$val}; // outputs "hello"
$val = "b";
echo $this->{$val}; // outputs "hi"
echo $this->val; // outputs "howdy"
echo $this->{"val"}; // also outputs "howdy"
相当于
$a = "hello";
$b = "hi";
$val = "a";
echo $$val; // outputs "hello"
$val = "b";
echo $$val; // outputs "hi"
还可动态调用函数
$this->{$fun_name}($plat_id, $v['id'], true)
json避免/转义
json_encode($params,JSON_UNESCAPED_SLASHES)
ip2long
如何将四个字段以点分开的IP网络址协议地址转换成整数呢?PHP里有这么一个函数ip2long
session
ini_set(‘session.gc_probability’,100); //否则不是百分之百 一般不改这个 特殊需求
ini_set(‘session.gc_divisor’,100);
设置后,会在返回值中多一个set-Cookie
微信小程序不能自动设置cookie,要先存到storge 然后在header中设置 Cookie
函数也可以引用
如 function &name(){
}
php值的传递
empty($this->a);这种形式的语法会始终判断为真 不知道是不是php的bug 而且在controller层调用正常 svc层又不正常
变量作用域
在所有函数外部定义的变量,拥有全局作用域。除了函数外,全局变量可以被脚本中的任何部分访问,但是要在一个函数中访问或修改一个全局变量,需要使用 global 关键字申明。
如 global $x,$y;
如果不声明,也可使用$GLOBALS['y']
得形式
在 PHP 函数内部声明的变量是局部变量,仅能在函数内部访问:
函数中也可使用static作用域
当一个函数完成时,它的所有变量通常都会被删除。然而,有时候您希望某个局部变量不要被删除。
要做到这一点,请在您第一次声明变量时使用 static 关键字:
<?php
function myTest()
{
static $x=0;
echo $x;
$x++;
echo PHP_EOL; // 换行符
}
myTest();
myTest();
myTest();
//然后,每次调用该函数时,该变量将会保留着函数前一次被调用时的值。
//注释:该变量仍然是函数的局部变量。
EOF
PHP 定界符 EOF 的作用就是按照原样,包括换行格式什么的,输出在其内部的东西;
$name="runoob";
$a= <<<EOF
"abc"$name
"123"
EOF;
// 结束需要独立一行且前后不能空格
echo $a;
三目运算符
1、传统的
(expr1) ? (expr2) : (expr3) 对 expr1 求值为 TRUE 时的值为 expr2,在 expr1 求值为 FALSE 时的值为 expr3。
2、PHP5.3新增
表达式 expr1 ?: expr3 在 expr1 求值为 TRUE 时返回 expr1,否则返回 expr3。
3、php7.3新增 null合并运算符
$site = $_GET[‘site’] ?? ‘菜鸟教程’;判断变量是否存在且值不为NULL,如果是,它就会返回自身的值,否则返回它的第二个操作数。
注:2和3得区别在于,当你想仅仅判断isset时候(不为布尔值、空数组等),二者是一致的。但是仅仅想判断isset的时候 用后面的不会出错。2的根据是true false 3的根据只有isset
命名空间的作用
1、用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
2、为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
//file1文件
namespace Foo\Bar\subnamespace;
function foo() {}
<?php
namespace Foo\Bar;
include 'file1.php';//需要include 命名空间仅仅是为了解决命名冲突的 不是真实的目录结构
function foo() {}
/* 非限定名称 */
foo(); // 解析为函数 Foo\Bar\foo
/* 限定名称 */
subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
/* 完全限定名称 */
\Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo
?>
//use用于为很长的命名空间起别名
use My\Full\Classname as Another;
// 下面的例子与 use My\Full\NSname as NSname 相同
use My\Full\NSname;
面向对象-见另一个博客 比较的
const、define、static区别
使用const使得代码简单易读,const本身就是一个语言结构,而define是一个函数。另外const在编译时要比define快很多。
1、const用于类成员变量的定义,一经定义,不可修改。Define不可以用于类成员变量的定义,可用于全局常量。
2、Const可在类中使用,define不能
3、Const不能再条件语句中定义常量
表单直接发送
<form action="welcome.php" method="post">
//welcome.php文件
欢迎<?php echo $_POST["fname"]; ?>!<br>
网络攻击
XSS又叫 CSS (Cross-Site Script) ,跨站脚本攻击。恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
others
文件可用超级全局变量file数组得到
坑
svc 用this->的写法可能找不到
array_search搜寻第一个的键名为0 会判断为false 一般还是用in_array把
如[{name: “搜狗浏览器”, soft_id: 10185},{ soft_id: 10185,name: “搜狗浏览器”}] array_unique(array,SORT_REGULAR)会失败
一些用法
$this->redisObj->sAdd('proSafeSvcUpdateActivityPhonesFailed',...$this->phones);
public function broadcast($message, array $phones)
list
list() 函数用于在一次操作中给一组变量赋值。可实现类似golang,python 多个返回值的情况
$my_array = array("Dog","Cat","Horse");
list($a, , $c) = $my_array;
echo "我在这里只用了 $a 和 $c 变量。";
gzip
gzdecode、gzdecode可以对数据进行压缩,节省空间。不光是文件,字符串也可以直接用!
场景:如存关联数组到redis
和zip区别 linux的gz后缀就是用gzip压缩的
GZIP与zip区别主要是适应系统不同,还有就是压缩率不一样;普遍使用的是zip压缩,Windows系统下就用zipgzip为高压,可以把文件压缩得更小,便于放网盘或者网上供人下载;gzip是Linux下面用的格式,一般在Linux下解压,如果用Windows下的程序解压有可能丢失其中某些文件或属性。
函数可添加类型
指定环境变量测试还是正式的方法
以下方法任选其一
一、但是好像不成功 算了 还是nginx吧
1.打开etc/profile文件:vim /etc/profile
新增一个环境变量export PHP_ENV=“DEV”,正式服务器设置为=“PRODUCTION”
这样通过系统环境变量来做一些不同的操作,或者存在不同的数据库账号密码
设置完后重新加载:source /etc/profile
2.修改PHP的php-fpm.conf文件,设置PHP环境变量
底部增加:env[PHP_ENV]=$PHP_ENV
重启PHP服务,service php-fpm restart
然后代码中用$_ENV[‘PHP_ENV’]获取即可
二、 nginx设置
location ~ .php($|/) {
try_files $uri =404;
fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME
d
o
c
u
m
e
n
t
r
o
o
t
document_root
documentrootfastcgi_script_name;
fastcgi_param PHP_ENV ‘DEV’; # PRODUCT DEV RETURN
}
设置完要重启nginx。
然后如果要修改nginx配置 可以先还原配置完 然后最后再加这句就行
然后代码用$_SERVER[‘PHP_ENV’]获取即可
json_decode 对路径无法生效
四斜杠
$j = '{"class":"app\\\\api"}';
dump(json_decode($j, true));//["class" => "app\api"]
三斜杠
$j = '{"class":"app\\\api"}';
dump(json_decode($j, true));//["class" => "app\api"]
双斜杠
$j = '{"class":"app\\api"}';
dump(json_decode($j, true))//null;
单斜杠
$j = '{"class":"app\api"}';
dump(json_decode($j, true));//null
解决方法
1、
// 把json中的\替换为/
$str = str_replace("\\", "/", $json);
//注意:第一个指要两个\\,如果一个的话会被转义掉!!
2、将有反下划线的单独拿出来,用urlencode函数处理后再放进去
定界符
为什么要使用定界符
比如你要打印代码 或者 一些gzip的数据 里面有单引号 然后就很麻烦 直接用引号包裹会报错
解决方案
heredoc和nowdoc
区别是后者不会解析$变量,使用差别是多了个引号
$gzip = <<<'EOF'
//EOF可为任意字符,然后下面的eof要顶格写 php7.3后对此做了优化 避免破坏格式
EOF
搜索技巧
你直接搜怎么单引号 加密数据啥的 很难搜到 可以换种思路
搜索 php定界方式
call
反斜杠类名
在new PHPExcel()时总报错,但在前面加个反斜杠就可以了,new \PHPExcel() ,这个斜杠表示,如果当前类中没有,就去全局搜索这个类
构造函数
新版的php 构造函数不再推荐与类名相同了,如果继续使用 会抛出异常
注解
比如throws 告诉使用的类要catch异常
@internal : 被此标签标记的内部类/方法,作用范围只能限于当前文件,外部文件不可调用.
@deprecated可以填写一个版本号,版本号的规则同@version
如果被标记的方法只是因为被其他新方法代替而被废弃,可以结合@see来表示被代替的方法
当定义了命名空间后,要用\Exception
不能exception 因为定义了命名空间,就要用类的全称了 不然会报错
方法1 use \Exception;
方法2 throw new \Exception;
var_dump与print_r
print_r输出的时候 字符型的"0"可能也输出0,造成json_encode 类型不对 而且不好排查。所以用var_dump.还有引用 var_dump
json_encode对数字的坑
json_encode($unique_soft, JSON_NUMERIC_CHECK);
因为查询mysql返回的数据,全部都是加了双引号的(都当成字符串)。我希望的是数字不要加双引号,而字符串就加上双引号。所以在进行json_encode() 时,加了参数 JSON_NUMERIC_CHECK(参考)
但是问题来了:加了这个参数后,它会把 decimal 类型的 价格 price 比如:20.00 ,后面的小数点去掉了,还有一个就是,比如说它也会把比如身份证号转换成了科学计数法了。
然后json_encode对浮点数,比如4.0会错误
//直接var_dump
array(9) {
["m2"]=>
array(2) {
["num"]=>
int(24)
["compare"]=>
float(20)
}
["base_board"]=>
array(2) {
["num"]=>
int(23)
["compare"]=>
float(0)
}
["cpu_name"]=>
array(2) {
["num"]=>
int(23)
["compare"]=>
float(-4.17)
}
["phys_memory"]=>
array(2) {
["num"]=>
int(46)
["compare"]=>
float(-8)
}
["disk_list"]=>
array(2) {
["num"]=>
int(26)
["compare"]=>
float(0)
}
["video_controller"]=>
array(2) {
["num"]=>
int(23)
["compare"]=>
float(0)
}
["physical_adapter"]=>
array(2) {
["num"]=>
int(26)
["compare"]=>
float(0)
}
["sound_device"]=>
array(2) {
["num"]=>
int(23)
["compare"]=>
float(0)
}
["desktop_monitor"]=>
array(2) {
["num"]=>
int(23)
["compare"]=>
float(0)
}
}
//json_encode后
{"m2":{"num":24,"compare":19.999999999999996},
"base_board":{"num":23,"compare":0},
"cpu_name":{"num":23,"compare":-4.1699999999999964},
"phys_memory":{"num":46,"compare":-7.9999999999999964},
"disk_list":{"num":26,"compare":0},
"video_controller":{"num":23,"compare":0},
"physical_adapter":{"num":26,"compare":0},
"sound_device":{"num":23,"compare":0},
"desktop_monitor":{"num":23,"compare":0}}
foreach 引用
比如foreach ($category_map as $k=>&$v)
如果引用 unset(k[xx])后面使用V的时候 是最新的v 而如果不是引用 那么就是原来的v(拷贝了一份)
数组元素为null 但是isset判断为false
定义一个PHP 数组 $arr = array('jjbao'=>null,'cnima'=>null); isset($arr['jjbao'])
居然返回的false
把 null 改为 0 就没有问题了
找了半个小时 蛋痛啊
解决方法: isset() 对于数组中为 NULL 的值不会返回 TRUE,而 array_key_exists() 会。
unset内存反而大?
备注 unset也生效了 用unset之前 是500k 用了300k 但是注释那种 只要200k
1、require和include以及once的区别
require() 语句的性能与 include() 相类似,都是包括并运行指定文件。不同之处在于:
1、对 include() 语句来说,在执行文件时每次都要进行读取和评估;而对于 require() 来说,文件只处理一次(实际上,文件内容替换 require() 语句,使它变成 PHP 脚本文件的一部分。)。这就意味着如果可能执行多次的代码,则使用 require() 效率比较高。另外一方面,如果每次执行代码时是读取不同的文件,或者有通过一组文件迭代的循环,就使用 include() 语句。
2、require一般放在最前面(类名前),而include可以在需要时,比如if循环时再引入,降低消耗。
3、PHP 系统在加载PHP程序时有一个伪编译过程,可使程序运行速度加快。但 incluce 的文档仍为解释执行。include 的文件中出错了,主程序继续往下执行,require 的文件出错了,主程序也停了,所以包含的文件出错对系统影响不大的话(如界面文件)就用 include,否则用 require。
4、include_once() 和 require_once() 语句也是在脚本执行期间包括运行指定文件。此行为和 include() 语句及 require() 类似,使用方法也一样。唯一区别是如果该文件中的代码已经被包括了,则不会再次包括。这两个语句应该用于在脚本执行期间,同一个文件有可能被包括超过一次的情况下,确保它只被包括一次,以避免函数重定义以及变量重新赋值等问题。
5、
总之:
1、当很多函数都使用,或者经常要被执行的时候,当被包含的文件出错不让他继续运行的时候,用require。
2、当出错不影响、而且不经常被使用到时,用include。
3、Require_once 虽然官方说php5.3之后的版本 性能和require差不多了 但是···实际测试好像还是差了很多 如php5.3.3 所以 能用require就不要require_once
2、empty()和isset()
单从字面意思理解,empty是判断一个变量是否为“空”,而isset 则是判断一个变量是否已经设置。
但是这里有一点绝对要注意起来:当一个变量值为0,empty 认为这个变量同等于空,返回的是true!
3、== 和 ===
1==2 判断是false (之所以写这个是为了防止二者自动转换为true 然后判定相等)
‘1’==1 是true
Php 10和5 如果是字符串类型 那么可能会错误的结果 判断出5>10???是么
$a = (bool)('1');
dump($a); //结果为true
4、浮点数(特别是涉及到钱的!)的运算必须用高精度运算函数
如 1/8 ==0.125可能判断错误 要用bcdiv
5、注意数据库加锁 lock(true)
为了防止读写冲突问题!!
lock(true)的实际就是在查询(select)语句最后加上 for update 指定使用悲观锁
详细可见https://blog.csdn.net/S_ZaiJiangHu/article/details/116720884
序列化和反序列化的作用
你想如果想把一个数组或者是对象存储到文件或数据库中,怎么办。不能像字符串那样的存储吧。所以在存储数组或对象之前先serialize,在取回内容时再unserialize…
一句话:serialize的作用是 产生一个可存储的值的表示.unserialize的作用是 对单一的已序列化的变量进行操作,
序列化可以将PHP中 对象、类、数组、变量、匿名函数等,转化为字符串,这样用户就方便储存和传输,对服务器或web中减轻一定的压力。
错误篇
字符串和数字判断相等返回true的问题
更多详细的 看https://www.cnblogs.com/beenupper/p/12635779.html
if('a'==0){
echo "字符串a尽然等于0";//输出了
}
php虽然是弱类型的语言,但它是有数据类型的。大概分为三种类型:字符串、数字、布尔型。上面的问题出现是由于字符串转换为了数字类型。
正常情况下不同类型的值是不能比较的,php 为了比较进行了数据类型转换。把不同类型的值转换为相同类型后再比较。
规则如下:
宽松比较(==)类型转换规则
(1)数字和字符串比较,将字符串转为数字,然后进行比较
(2)数字和布尔型比较,将数字转为布尔型,然后进行比较
(3)字符串和布尔型比较,将字符串转为布尔型,然后进行比较。
宽松比较的落脚点只有两个,一个是布尔型,一个是数字。只有当数字和字符串比较的时候,会把字符串转为数字
三、字符串转数字
- 字符串的开始部分决定了它的数字值。
- 如果该字符串以合法的数字值开始,则使用该数值。否则其值为 0(零)。
- 合法数字值可以是正负号,后面跟着一个或多个数字(可能有小数点),再跟着可选的指数部分。指数部分由 ‘e’ 或 ‘E’ 后面跟着一个或多个数字构成。
四、剖析 ‘a’==0
‘a’ 这是一个字符串类型。0 是数字类型。使用 == 宽松比较,此时发生类型转换。字符串和数字比较,是将字符串转换为数字然后进行比较的。
运算步骤一:根据字符串转数字的规则,字符串的开始部分决定了它的数字值。该字符串的开头不是数字,则它的数字值为0。
所以’a’ 转换为数字类型时,它其实为0了。不仅’a’等于0,‘abc’,‘aabbcc’ 它们转为数字也是0哦。
运算步骤二:最后比较0是否等于0,结果为真。
字符串的布尔值和布尔值的相等问题
需要注意 即使强制类型转换也 比如(bool)‘false’==false 输出的是false
还是用0 1把
json变对象
在一次工作中跟前端对接API中出现的问题,前端说接口返回值跟接口文档不一致。API文档写的是返回数组,但是实际返回的是一个JSON对象。最后补充这个知识盲点:PHP的数组在转JSON的时候,如果索引连续,则转成数组。如果索引不连续,则会转成对象!
PHP数组转json后,元素变为object的坑🙈
今天项目遇到一个bug,组件排序是用数组做的排序,所以遇到了排序后的数组转为json字符串后,前端解析后变为了对象,导致了出现bug,自己研究了一下发现了一个坑。
首先测试key有序且下标从0开始的一个索引数组,代码如下:
<?php
$a[0] = '1a';
$a[1] = '2a';
$a[2] = '3a';
$b['a'] = $a;
$jStr = json_encode($b);
echo $jStr;
//结果是这样的
{“a”:[“1a”,“2a”,“3a”]}
可以看到这时,josn里的元素是数组,符合预期。
接下来试一下下标0开始,但是key无序的索引数组
<?php
$a[0] = '1a';
$a[2] = '2a';
$a[1] = '3a';
$b['a'] = $a;
$jStr = json_encode($b);
echo $jStr;
//结果是这样的
{“a”:{“0”:“1a”,“2”:“2a”,“1”:“3a”}}
这个时候已经可以看到,其中的a数组已经被json转为了对象
这个时候突发奇想,试一下key有序但是下标不是从0开始的索引数组:
<?php
$a[1] = '1a';
$a[2] = '2a';
$a[3] = '3a';
$b['a'] = $a;
$jStr = json_encode($b);
echo $jStr;
//结果如下:
{“a”:{“1”:“1a”,“2”:“2a”,“3”:“3a”}}
可以看到即使索引数组下标连续,但是下标key不是从0开始的索引数组,依然是会被转换为对象。
结论
如果也遇到了类似的需求,需要某种排序要用到这一步,一定要注意一下这里,要转换为从0开始,下标连续不间断的新数组,json_encode后才会是一个数组的形式。
我后来是转换为从0开始下标的新数组,并且使用ksort之后,json才成功转换为了想要的数组格式。
解决方案
加一个 :
a
r
r
a
y
=
a
r
r
a
y
v
a
l
u
e
s
(
array = array_values(
array=arrayvalues(array);
技巧与使用篇
microtime()
字符串的两部分的单位都是秒(第一部分并不是微秒为单位),第一部分是精确到微秒的部分
比如0.25139300 ,有效数字是6位,正好符合1秒=1,000毫秒=1,000,000微秒
使用echo microtime(true);直接获得浮点值。
内外网判断
工作需要判断ip是否是内网ip,本来想着使用正则自己写一个呢,后来发现php自带的有现成的函数filter_var() 。
除了ip验证外还有许多都可以验证,如url、email等等
验证ip是否是内网ip,如果是的话返回false,否则返回ip;
直接的话 浏览器看不到 要 var_dump
代码如下:
filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)
内网ip
A类:10.0.0.0-10.255.255.255
B类:172.16.0.0-172.31.255.255
C类:192.168.0.0-192.168.255.255
本机地址:127.0.0.1
PHP FILTER_VALIDATE_IP 过滤器
定义和用法
FILTER_VALIDATE_IP 过滤器把值作为 IP 进行验证。
Name: “validate_ip”
ID-number: 275
可能的标志:
FILTER_FLAG_IPV4 - 要求值是合法的 IPv4 IP(比如 255.255.255.255)
FILTER_FLAG_IPV6 - 要求值是合法的 IPv6 IP(比如 2001:0db8:85a3:08d3:1319:8a2e:0370:7334)
FILTER_FLAG_NO_PRIV_RANGE - 要求值是 RFC 指定的私域 IP (比如 192.168.0.1)
FILTER_FLAG_NO_RES_RANGE - 要求值不在保留的 IP 范围内。该标志接受 IPV4 和 IPV6 值。
二维数组去重
这个函数默认只能一维,会报错 arr to string的错误 所以
array_unique中加:SORT_REGULAR参数
抑制错误@和TODO
curl和file_get_contents的区别
1.fopen /file_get_contents 每次请求都会重新做DNS查询,并不对 DNS信息进行缓存。但是CURL会自动对DNS信息进行缓存。对同一域名下的网页或者图片的请求只需要一次DNS查询。这大大减少了DNS查询的次数。所以CURL的性能比fopen /file_get_contents 好很多。
2.fopen /file_get_contents 在请求HTTP时,使用的是http_fopen_wrapper,不会keeplive。而curl却可以。这样在多次请求多个链接时,curl效率会好一些。
3.fopen / file_get_contents 函数会受到php.ini文件中allow_url_open选项配置的影响。如果该配置关闭了,则该函数也就失效了。而curl不受该配置的影响。
4.curl 可以模拟多种请求,例如:POST数据,表单提交等,用户可以按照自己的需求来定制请求。而fopen / file_get_contents只能使用get方式获取数据。
file_get_contents 获取远程文件时会把结果都存在一个字符串中 fiels函数则会储存成数组形式
由此可知curl在性能、速度、稳定性上都要优于file_get_contents,所以建议以后使用curl库进行网络请求。
<?php
$curl = curl_init();//初始化一个cURL对象
$url = "http://cart.jd.com/cart/cart.html?backurl=http://item.jd.com/176166.html&rid=0.9533184533 938766";
$header = array();
$header[] = 'User-Agent: 5.0 (iPhone; U; CPU iPhone OS 4_3 like Mac OS X; en-us)';
$header[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
$header[]= 'Accept-Encoding: gzip,deflate';
$header[]= '//可以根据需要增加header内容';
curl_setopt($culr,CURLOPT_URL, $url);//设置你需要抓去的URL地址
curl_setopt($curl,CURLOPT_HEADER,$header );//设置header
curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);//将结果返回输出到字符串
$str = curl_exec($curl);运行cURL,请求网页
curl_close($curl);//关闭url请求
return $str;//返回或者显示结果
php性能低的原因
作者:旗木五五开
链接:https://www.zhihu.com/question/422661037/answer/1602633070
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
php不管是哪个框架真的要到高性能的场景,都是撑不住的。原因?首先,没有连接池这个玩意,立马就拖垮了数据库的连接数,too many connection见过没?没见过的话等你见过了再来喷框架垃圾。其次,每次都要从入口文件加载一次全部代码,当然你可以用opcache减少编译。框架代码按照道理你应该只加载一次就够了,逻辑上应该从路由开始执行才对,这部分也是性能损失的原因。第三,php本身的io机制不是epoll的,理论上你php-fpm开了多少个进程,就能同时执行多少个请求,网上一堆教程教你要么保持和cpu核数一样,要么内存50m一个进程之类的方式。基于这个问题,php方面的性能优化只能靠叠服务器,不然你会经常碰到504 gateway timeout的问题。所以php的优化途径都是这样的:首先你随便用一个了框架。然后某天突然发现504 gateway timeout了,排除了你sql写的实在是烂的前提,你就会发现是php-fpm的进程不够用导致的,修改php-fpm.conf配置或者加机器。加完机器大概率会出现too many connection,原因是mysql的连接数不够用了,然后你就会想要么mysql主从分离,要么加缓存上redis,先查redis再查mysql。然后如果量继续加大,你就只能继续增加服务器,因为php-fpm进程数=1秒处理数导致的。接着你会发现服务器成本越来越贵,就差不多要换swoole或者go获取java了。当你换了go或者java或者swoole后,你就会发出服务器降了多少台,成本降了多少的感叹。所以选一个自己称手的框架上就行了,框架无非就是熟练它的各种类库罢了,那个熟练用哪个,非得有个高下立判就无趣了,真到性能瓶颈你都得换。说点Laravel的题外话,Laravel真的是除了性能不行,哪哪都行的框架。掌握好他的框架思想、设计模式、队列、调度等原理,真的大有裨益。
1、too many 的问题解决方案很多,如果使用的是云数据库,一般都有短链接优化功能,开启即可解决问题。如果是本地自建数据库,加一个数据库代理即可,但根据实践来看,往往引起数据库连接超量并不是因为没有连接池引起的,而是业务代码里出现了大量的循环创建mysql连接导致的,开启连接池只是避免了前端报错,避免服务crash,但问题本质还是存在
2、php-fpm并不是你们理解的那样,一个进程只能处理一个请求,fpm本质也是利用了linux的epool机制,可以同时轮询处理多个请求,但是要记住,业务代码里不能有阻塞代码,阻塞代码一定要放到后台进行,否则并发能力会大受影响,就真的变成一个进程一次只能处理一个请求了
3、用laravel这样的框架,正确的写代码,两台4G8核的服务器,可以支撑到日请求数300万,峰值每秒处理2000请求,一直到项目黄了也没有触摸到性能瓶颈,这一点是自己创业的经历,不多解释。
4、php十分适合低成本创业,php当前最大的问题是被语言创造者们抛弃了,得不到黑科技的注入了。