非科班的苦逼程序员,深感找工作的艰辛,而且还是PHP的技术栈,找工作更加痛苦。 现把自己积累的手写php笔记,搬到上吧
文章目录
1. PHP的数据类型2. 数据类型3. 注释4.自增自减5.可变变量6.预定义变量7.常量8.流程控制替代语法9.匿名函数10.遍历数组11.类-对象(1)魔术方法(2)类的自动加载(3)内置标准类(4)与类相关的系统函数(5)与对象相关的系统函数(6)与类有关的运算符(7)static、self(8)面向对象的三个特征
12.header(string,replace,http_response_code)13.性能优化14.PHP7新特性(1)引入类型说明:形参、返回值(2)use声明(3)匿名类(4)新操作符(5)统一变量语法(6)session_strat中可添加参数(7)unseriazlize(8)支持Unicode字符格式
15.性状16.生成器17.PHP常用参数(1)php.ini1、Zend OPcache2、文件上传参数3、缓存输出
(2)PHP-FPM.conf
1. PHP的数据类型
布尔型(Boolean)、整形(Int)、浮点型(Float)、字符串(String)、数组(Array)、对象(Object) 特殊类型:资源类型(Resource)、空类型(Null)
2. 数据类型
var_dump()is_*() is_bool():是否是整形 is_int()、is_float()、is_string()、is_array()、……is_a(object,classname):判断对象是否为某类的对象isset():判断变量是否存在/设置isset($a)?1:isset($b)?2:3;无论几层嵌套,都要看成前面归一类(isset($a)?1:isset($b))?2:3;empty():判断变量是否为空强制转换数据类型: (int)$name、(float)$name、(string)$name、(bool)$name、settype/gettype intval()、strval()
settype($name,'目标类型');
gettype($name);
进制转换: bin:2进制 oct:8进制 dec:10进制 hex:16进制
$dec = 123;
$oct = 0123;
$hex = 0x123;
decbin($num);
decoct($num);
dechex($num);
bindec($num);
octdec($num);
hexdec($num);
echo base_convert($hex,16,8);
浮点数
tip:浮点数不应该直接进行大小比较,因为所有的数字最终都是转换为二进制形式,不能完全表达准确,最终只能“以很高的精度接近理论值”,因此浮点数是不可靠的
$a = 0.1;
$b = 0.9;
$c = 1;
var_dump(($a+$b)==$c);
var_dump(($c-$b)==$a);
解决方法 1、尽量不用浮点数直接进行比较,进行round/ceil/floor等操作 2、用php的高精度运算函数
$a = 0.1;$b = 0.9;$c = 1;
var_dump(($c-$b)==$a);
var_dump(bcsub($c, $b, 1)==$a);
字符串
$str1 = '';
$str2 = "";
$str3 = <<<yyfs
heredoc
多行文本,默认双引号,也可以加上双引号,会转义变量及特殊字符
yyfs;
$str4 = <<<'yyfs'
nowdoc
多行文本,默认双引号,也可以加上双引号,不会转义变量及特殊字符
yyfs;
类型自动转换
$v1 = '1def'+'2abc';
$v2 = 'def1'+'abc2';
比较规律 布尔值: ture>false 字符串:可转为文字进行比较
"abc">true;
"abc">false;
"ab">"c";
"3abc">"12abc";
"abc">"ab123c";
1>"a";
"1">"a";
3. 注释
单行://或# 多行:/* */
4.自增自减
布尔值:自增自减无效 null值:自减无效,自增结果为1 字符串:只能自增,效果为下一个字符,只能针对字母或者数字进行自增
$s1 = 'a';
$s2 = 'abc';
$s3 = 'xyzz';
$s4 = 'zzz';
$s5 = 'abc9';
tips:循环时推荐使用++$i,因为用时比较少
5.可变变量
$s1 = 'abc';
$abc = 10;
echo $$s1;
6.预定义变量
$_GET、$_POST、$_REQUEST、$_SERVER、$_GLOBALS、$_COOKIE、$_FILES、$_SESSION、$_ENV
$_GET 、$_POST:获取GET或POST方法传参的数据$_REQUEST:获取GET和POST方法传参的数据$_SERVER:返回一些浏览器的信息$_GLOBALS:存储所有全局变量$_COOKIE、$_SESSION:存储COOKIE / SESSION的信息$_FILES:文件上传时,存储文件信息$_ENV:获取服务器端环境变量的数组
7.常量
define一般情况下:define(‘company’,‘4399’); 但define还可以设置表达式的常量,define(‘yesterday’,246060);判断变量是否存在:defined() 存在返回true,不存在返回falseconst:const 常量名=常量值预定义常量:M_PI:圆周率PHP_OS:php运行所在的操作系统HP_VERSION:php的版本号PHP_INT_MAX:php中最大的整数值PHP_EOL:php中的换行符魔术常量:_ _ LINE _ _ :返回文件中的当前行号_ _ FILE _ _ :返回文件的完整路径和文件名_ _ DIR _ _ :返回该文件所在的目录_ _ FUNCTION _ _ :返回该函数被定义时的名字_ _ CLASS _ _ :返回该类被定义时的名字_ _ METHOD _ _ :返回类中该方法被定义时的名字_ _ NAMESPACE _ _ :返回当前命名空间的名字
8.流程控制替代语法
if(…): ……else:……endif;while(……):……endwhile;switch(……):case xx:……case xx:……case xx:…… endswitch;
9.匿名函数
没有名字的函数
将匿名函数复制给变量
$f1 = function(){……
}
$f1();
将匿名函数作为实参使用
function func1($x,$y,$z){
$s1 = $x + $y;
$s2 = $x - $y;
$z($s1,$s2);
}
func1(3,4,function($m1.$m2){
echo "m1=$m1,m2=$m2";
});
10.遍历数组
for和foreach比较普遍,记录一个比较特殊的,可以用while+each+list
while(list($key,$value)=each($arr)){
echo $key,'===>',$value;
}
11.类-对象
(1)魔术方法
_ _constuct():在new一个对象的时候自动调用_ _destruct() :当一个对象被销毁时自动调用_ _call()和 _ _callStatic():当对一个对象的不存在的实例(静态)方法进行调用时自动调用_ get()和 _set():对对象中不存在的属性进行“取值“和”赋值”_ isset()和 _unset():对对象中不存在的属性进行isset()和unset()判断时自动调用_ sleep()和 _wakeup():对象的序列化serialize和反序列化unserialize时自动调用,只能序列化其属性数据,而方法被忽略,因为方法不是数据_ _toString():当直接echo对象时自动调用_ _invoke():直接把对象当成函数调用时自动调用_ _clone() :当 clone复制一个对象时,新创建的对象会自动调用类中的此函数_ _debugInfo() :直接var_dump对象时自动调用官网示范用例:魔术方法----重载----构造函数和析构函数----对象复制
(2)类的自动加载
_ _autoload():系统内部的自动加载函数spl_autoload_register(‘函数名’):注册更灵活的自动加载函数PHP实现路由器功能–未编写
spl_auto_register('autoload1');
function autoload1($class_name){
echo '<br>准备在autoload1中加载这个类:',$class_name;
$file = './class/'.$class_name.'.class.php';
if(file_exists($file)){
include_once $file;
}
}
(3)内置标准类
内置标准类里面什么都没用,class stdclass{}作用:1.用于存储一些临时的简单的数据 2.在类型转换时用于存储数据
$obj1 = new stdclass();
var_dump($obj1);
class A{}
$obj2 = new A();
var_dump($obj2);
对象的类型转换:$obj = (object)其他数据类型;说明:1.数组转换成对象,数组的键名当做属性名,值为对象对应的值 (数字下标的数据元素,转换为对象后的属性,无法通过对象语法获取,因此不推荐转换) 2.null转换为对象:空对象 3.其他标量数据转换为对象:属性名为固定的”scalar“,值为该变量的值
$arr = array('pp1' => 1, 5 => 12);
$obj = (object
)$arr;
var_dump($obj );
echo $obj ->pp1;
echo $obj2->5;
$v1 = 1;
$objv1 = (object
)$v1;
var_dump($objv1);
(4)与类相关的系统函数
class_exist(“类名”):判断一个类是否存在/是否定义过interface_exist(“接口名”):判断一个接口是否存在/是否定义过get_class($obj):获得某个对象$obj的所属类get_parent_class($obj):获得某个对象$obj的父类get_class_methods():获得一个类的所有方法名,返回结果是一个数组,存储的是方法的名称get_class_vars():获得一个类的所有属性名,返回结果是一个数组,存储的是属性的名称get_declared_classes()/get_declared_interfaces:返回一个数组包含当前脚本所有已声明的类/接口的名称
(5)与对象相关的系统函数
is_object($obj):判断某个变量是否是一个对象is_a(object,classname):判断对象是否为某类的对象get_object_vars($obj):获得一个对象的所有属性,结果一个数组存储属性的名称
(6)与类有关的运算符
new:新建一个对象clone:克隆一个对象instanceof:判断一个变量/对象/数据是否是某个类的实例
class A{} $a = new A();
class B{} $b = new B();
class C extends A{} $c = new C();
$v1 = $a instanceof A;
$v2 = $b instanceof A;
$v3 = $c instanceof C;
$v4 = $c instanceof A;
(7)static、self
self:代表这个单词本身所在位置的所在类 (写在哪个类里面, 实际调用的就是这个类)static:代表的是调用当前方法的类 (代表使用的这个类, 就是你在父类里写的static,然后被子类覆盖,使用的就是子类的方法或属性)
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
self
::who();
}
}
A
::test();
class B extends A {
public static function who() {
echo __CLASS__;
}
}
echo B
::test();
如果使用关键字self运行结果: A A
如果使用关键字
static运行结果:A B
(8)面向对象的三个特征
封装:尽可能将一个类私有化,只开放那些必不可少的对外的属性和方法 (能private就不要protected,能protected就不要public)继承:面向对象的基本思想和基本做法多态:1.不同对象使用相同的方法会表现出不同的结果 2.同一个对象使用相同的方法也可能会表现为不同的结果,称“方法重载现象”
12.header(string,replace,http_response_code)
向客户端发送原始的 HTTP 报头参数:string:规定要发送的报头字符串replace:指示该报头是否替换之前的报头,或添加第二个报头,默认是 true(替换)。false(允许相同类型的多个报头)http_response_code:可选。把 HTTP 响应代码强制为指定的值例子1:跳转页面
header('Location: https://blog.csdn.net/u010365335');
例子2:控制浏览器缓存gmdate():将一个时间戳,格式化成GMT时间,格林威治时间
$expire = gmdate('D,d M Y H:i:s',time()+3).' GMT';
header("Expires:".$expire);
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified:".$expire);
header("Cache-Control: no-cache");
header("Pragma: no-cache");
header("Expires: 0");
例子4:声明content-type,页面编码
header('content-type:text/html;charset=utf-8');
例子5:返回response状态码
header('HTTP/1.1 404 Not Found');
例子6:在某个时间后执行跳转
header('Refresh: 10; url=https://blog.csdn.net/u010365335');
例子7:控制文件下载 :PHP文件操作-上传,下载(断点续传),目录操作,文件操作
header("Content-type:application/pdf");
header("Content-Disposition:attachment;filename='downloaded.pdf'");
readfile("original.pdf");
13.性能优化
(1)使用isset()代替strlen
if(strlen($str)<5)){……
}
if(!isset($str[5])){……
}
(2)使用str_split分隔字符串比explode快(3)如果是单个字符替换,用strtr比str_replace快strtr($string, $from, $to)或strtr($string, $array)str_replace($find, $replace, $string[, $count])在替换之前可以先用strpos查找,判断是否需要替换
echo strtr('hello', 'e', '');
echo strtr('hello', ['e' => '']);
echo str_replace("red","pink","blue,red,green,yellow");
14.PHP7新特性
(1)引入类型说明:形参、返回值
默认情况下,形参类型声明不是被完全限制的,即程序期望得到一个整数型的参数,但我们可以传递一个浮点数,但可以做出一些限制,如declare(strict_type=1):强制类型保持一致,之后如果传递参数类型不一致,将会扔出Fatal错误
class Person{
public function age(int
$age):string
{}
public function age(int
$age):Address
{
return new Address();
}
}
(2)use声明
use Publish\Packet\{Book
,Ebook
,Video
,Presentation
};
use function Publish\
Packet\{getBook
,saveBook
};
use const Publish\
Packet\{COUNT,KEY};
use Publish\Packet\{Book
,Ebook
,Video
,Presentation
,
function getBook
,function saveBook
,
const COUNT,const KEY};
use Publish\Packet\{
Paper\
Book,
Electronic\
Ebook,
Media\
Video
};
(3)匿名类
不用设置类名的类,同样可以继承接口和类,也可以在一个类中嵌套使用匿名类
$name = new class(){
public function __construct(){ echo 'yyfs';}
}
interface Publishes{ public function getName(); }
class Packet { protected $name;}
$info = new class(...) extends Packet implements Publishes{...}
class Math{
public function multiplySum(){
return new class extends Math{
public funtion
multi(){}
}
}
}
$math = new Math();
echo $math->multiplySum()->multi(2);
(4)新操作符
<=>:太空飞船操作符,用于比较变量,当符号两边相等时返回0,右边大于符号左边,返回 -1 ,左边大于符号右边,返回 1,例 $int1 <=> $int2??:null合并运算操作符,原本是 $post = $_POST[‘title’] ? $_POST[‘title’] : null;现在可以$post = $_POST[‘title’] ?? null;intval(x, y):整除运算符, intval( 10, 3) = 3
(5)统一变量语法
解析代码的顺序默认从左到右
class Packet{
public $title = 'PHP7';
public function getTitle():string
{ return $this->title;}
}
$method = ['title' => 'getTitle'];
$object = new Packet();
echo 'Book:' . $object->$method['title']();
在PHP5.x中可以正常允许,但在PHP7中会首先尝试解析$object->$method,之后才会去尝试解析[‘title’]等,这并不符合预期,因此需要修改为echo ‘Book:’ . $object->{$method[‘title’]}();即可
(6)session_strat中可添加参数
设置信息将会覆盖php.ini中的session配置
session_start(['cookie_lifetime'=>3600,'read_and_close'=>true]);
(7)unseriazlize
PHP7之前,unseriazlize并不安全,可以反序列化任何类型的对象,PHP7之后添加了过滤器,可以防止非法数据进行代码注入,提供了更安全的反序列化数据
class MyClass1 {
public $obj1prop;
}
class MyClass2 {
public $obj2prop;
}
$obj1 = new MyClass1();
$obj1->obj1prop = 1;
$obj2 = new MyClass2();
$obj2->obj2prop = 2;
$serializedObj1 = serialize($obj1);
$serializedObj2 = serialize($obj2);
$data = unserialize($serializedObj1 , ["allowed_classes" => false]);
$data2 = unserialize($serializedObj2 , ["allowed_classes" => ["MyClass1", "MyClass2"]]);
print($data->obj1prop);
print($data2->obj2prop);
(8)支持Unicode字符格式
echo "\u{771f}\u{9999}";
PHP7环境下输出“真香”,早起版本原样输出
15.性状
类似于类/接口,PHP解释器在编译时会把性状复制粘贴到类的定义体中,但是不会处理这个操作引入的不兼容问题。如果性状假定类中有特定的属性或方法,即在性状中没有定义,要确保相应的类中有对应的属性和方法。 PHP性状——他人文章创建性状
trait MyTrait{
}
使用性状
class MyClass{
use MyTrait;
}
16.生成器
yield,类似于迭代器,可以不要求类实现Iterator接口,减轻类的负担
function makeRange($length)
{
$dataset = [];
for ($i = 0; $i < $length; $i++) {
$dataset[] = $i;
}
return $dataset;
}
$time1 = microtime(true);
$range = makeRange(1000000);
foreach ($range as $v) {
}
echo '<br>';
$time2 = microtime(true);
echo '耗时:' . round($time2 - $time1, 3) . '秒<br>';
echo '内存消耗: ' . memory_get_usage() / 1024 . 'KB<br>';
function makeRange($length)
{
for ($i = 0; $i < $length; $i++) {
yield $i;
}
}
$time1 = microtime(true);
$range = makeRange(1000000);
foreach ($range as $v) {
}
$time2 = microtime(true);
echo '耗时' . round($time2 - $time1, 3) . '秒<br>';
echo '内存消耗: ' . memory_get_usage() / 1024 . 'KB<br>';
17.PHP常用参数
(1)php.ini
1、Zend OPcache
设置PHP内置字节码缓存功能
opcache.memory_consumption = 64: 为操作码缓存分配的内存制,单位为MB,小型PHP引用可以设置16MB,大型可以设置64-256MBopcache.interned_strings_buffer = 16:用来存储驻留的字符串的内存量,默认值为4MBopcache.max_accelerated_files=5000:最大缓存的文件数目, 命中率不到 100% 的话, 可以试着提高这个值,值一定要比PHP引用的文件数量大opcache.validate_timestamps=1:设置为1时,经过一段时间后PHP会检查脚本内的内容是否有变化,检查的时间间隔由opcache.revalidate_freq设置指定。如果这个设置的值为0,则PHP不会检查脚本内容辩护,必须手动清除缓存的操作码,建议在开发环境设为1,在生产环境设为0opcache.revalidate_freq=240:设置PHP多久的时间周期回去检查仪器脚本的内容是否有变化,默认为 2, 单位为秒opcache.fast_shutdown=1: 是否快速关闭, 能让操作码使用更快的停机步骤,把对象析构和内存释放交给ZendEngine的内存管理器完成,打开后在PHP Request Shutdown的时候回收内存的速度会提高opcache.save_comments=0:不保存文件/函数的注释
2、文件上传参数
PHP文件操作-上传,下载(断点续传),目录操作,文件操作
3、缓存输出
output_buffering=4096:off为关闭输出缓存,on为打开无限大的输出缓存,数值则打卡单位为B的输出缓存implicit_flush=false:打开或关闭绝对刷送,on:每次输出(如echo,print)后自动调用flush()函数后,直接输出;off:与On相反,每次输出后不会调用flush(),需要等到server buffering满了才会输出,但是我们可以用flush()函数代替它,不开启也没关系,反而更加灵活realpath_cache_size=256K:获取真实路径缓冲区的大小,使用大量文件时,增大该值可以优化性能
(2)PHP-FPM.conf
user=www-data:拥有这个PHP-FPM进程中子进程的系统用户group=www-data:拥有这个PHP-FPM进程池中子进程的系统用户组listen=127.0.0.1:9000:可以使用任意大于1024的端口,PHP进程池监听的IP地址和端口listen.allowed_clients:127.0.0.1:可以向这个PHP-FPM进程池发送请求的IP地址,一个或多个pm.max_children=51:设置任何时间点PHP-FPM进程池中最多能有几个进程,每个PHP进程使用5-15MB内存,假设设备为PHP-FPM进程池分配了512MB可用内存,则设置512/10MB=51个进程pm.start_servers=3:PHP-FPM进程池中立即可用的进程池,一般设置为2-3个pm.min_spare_servers=2:PHP应用空闲时PHP-FPM进程池中可以存在的进程数量的最小值pm.max_spare_servers=4:PHP应用空闲时PHP-FPM进程池中可以存在的进程数量的最大值pm.max_requeset=1000:回收进程之前,PHP-FPM进程池中各个进程最多能处理的HTTP请求数量showlog=/path/to/showlog.log:为一个日志文件在文件系统中的最对路径,用于记录处理时间超过 n 秒的HTTP请求信息,以便找出PHP应用的瓶颈,进行调试,PHP-FPM进程池所属的用户和用户组必须有这个文件的写权限request_showlog_timeout=51:如果当前HTTP请求的处理时间超过指定值,就把请求的回溯信息写入slowlog设置的日志文件中
-----小Tips
unset():删除的只是元素的值,而所占有的空间还保留着性能分析工具,XHProf,ab赋值字符串的指定位置具体字符时,只会把第一个值赋上
$text = 'Jony';
$test[10] = 'YY-帆S';
echo $text;
echo strlen($text);