首页
关于
归档
朋友
壁纸
留言
API平台
告白墙
更多
休闲游戏
留言板
练字贴
Layui手册
Search
1
【PHP】PHPoffice/PHPSpreadsheet读取和写入Excel
1,339 阅读
2
【Git】No tracked branch configured for branch master or the branch doesn't exist.
1,039 阅读
3
【Layui】控制页面元素展示隐藏
860 阅读
4
【composer】composer常用命令
787 阅读
5
【PHP】PHP实现JWT生成和验证
769 阅读
默认分类
PHP
ThinkPHP
Laravel
面向对象
设计模式
算法
基础
网络安全
Web
HTML
CSS
JavaScript
jQuery
Layui
VUE
uni-app
Database
MySQL
Redis
RabbitMQ
Nginx
Git
Linux
Soft Ware
Windows
网赚
Go
登录
Search
标签搜索
PHP
函数
方法
类
MySQL
ThinkPHP
OOP
JavaScript
Layui
Web
Linux
Array
设计模式
Git
PHPSpreadsheet
PHPoffice
排序算法
基础
面试题
Windows
小破孩
累计撰写
223
篇文章
累计收到
33
条评论
首页
栏目
默认分类
PHP
ThinkPHP
Laravel
面向对象
设计模式
算法
基础
网络安全
Web
HTML
CSS
JavaScript
jQuery
Layui
VUE
uni-app
Database
MySQL
Redis
RabbitMQ
Nginx
Git
Linux
Soft Ware
Windows
网赚
Go
页面
关于
归档
朋友
壁纸
留言
API平台
告白墙
休闲游戏
留言板
练字贴
Layui手册
搜索到
219
篇与
的结果
2022-06-19
【PHP】基于RBAC模式解决权限管理
本文以最简单逻辑解释什么是rbac模式本文全是个人理解,如有不恰当的地方,请指出,互相学习RBAC(Role-Based Access Control)权限模型的概念,即:基于角色的权限控制。通过角色关联用户,角色关联权限的方式间接赋予用户权限。1.创建最基本的三个表,即 人员表(admin),角色表(role),功能表(func),和一个扩展人员权限表(admin_func)人员表:必有得字段(role_id)角色表:必有的字段(func_ids)人员扩展权限表:必有得字段(admin_id,func_ids)2.整体思路用户登录,查人员表数据,获取到角色唯一标志(这里是id)通过角色唯一标记,获取权限(这里角色里面的func_ids里面的数据通常是逗号隔开的字符串,我们在业务逻辑上处理时,转换成数组比较好处理)用户操作任意一个功能,获取到该功能的 控制器 和 方法 去功能表里查获取到id获取到的id判断是不是在上一步查的角色所对应的func_ids里面3.特殊情况如果在一个公司内,举个例子,在同一个公司有两个销售部(a部门,b部门),两个销售部的领导都是有一样的权限的(角色是一样的),这个时候,公司高层决定,a部门的领导为总领导,可以查看b部门的数据,这个时候,都知道,a和b的部门领导角色不能修改,一种笨方法,在开一个账号,分配角色和权限,可以查看b部门的数据,这样不符合工作逻辑,对领导不友好,下面就有了扩展人员权限在扩展人员表里绑定人员id和对应的功能表的id这样在我们操作的时候就多了一个步骤,多查一个表(admin_func),获取到的数据在和角色里面的权限进行合并,在做后面业务逻辑操作4.在什么位置实现权限在你看来怎么方便怎么实现,最好的就在中间件里实现权限验证,可以有效的降低无效访问中间件的主要应用场景可以包括对HTTP请求的数据过滤、权限检测、请求拦截等行为,使用中间件能够让控制器的定义更加简单,很多额外的非核心业务流程的处理都可以交给中间件执行。补充: 在实际的代码逻辑中应该避免用if else 判断不同角色查看同一接口返回不同的数据,不同的角色应该在权限理固定好访问接口。这里面需要更多的绑定关系。
2022年06月19日
160 阅读
0 评论
0 点赞
2022-06-19
【Laravel】Laravel为什么会成为最优雅的PHP框架
Laravel最初的设计是为了面向MVC架构的,它可以满足如事件处理、用户身份验证等各种需求。另外它还有一个由管理数据库强力支持,用于管理模块化和可扩展性代码的软件包管理器。Laravel以其简洁、优雅的特性赢得了大家的广泛关注,无论是专家还是新手,在开发PHP项目的时候,都会第一时间的想到Laravel。本文我们将讨论为什么Laravel会成为最成功的PHP框架。模块化和可扩展性Laravel注重代码的模块化和可扩展性。你可以在包含超过5500个程序包的Packalyst目录中找到你想要添加的任何文件。Laravel的目标是让你能够找到任何想要的文件。微服务和程序接口Lumen是一个由laravel衍生的专注于精简的微框架。它高性能的程序接口可让你更加简单快速的开发微型项目。Lumen使用最小的配置集成了所有laravel的重要特性,你可以通过将代码复制到laravel项目的方式将完整的框架迁移过来。 get('/', function() { return view('lumen'); }); $app>post('framework/{id}', function($framework) { $this>dispatch(new Energy($framework)); }); HTTP路径Laravel拥有类似于Ruby on Rails的,快速、高效的路由系统。它可以让用户通过在浏览器上输入路径的方式让应用程序的各部分相关联。 Route::get('/', function () { return 'Hello World'; });HTTP中间件应用程序可受到中间件的保护——中间件会处理分析和过滤服务器上的HTTP请求。你可以安装中间件,用于验证注册用户,并避免如跨站脚本(XSS)或其它的安全状况的问题。 input('age') <= 200) { return redirect('home'); } return $next($request); }缓存你的应用程序可得到一个健壮的缓存系统,通过对其进行调整,可以让应用程序的加载更加快速,这可以给你的用户提供最好的使用体验。 Cache::extend('mongo', function($app) { return Cache::repository(new MongoStore); });身份验证安全是至关重要的。Laravel自带对本地用户的身份验证,并可以使用“remember” 选项来记住用户。它还可以让你例如一些额外参数,例如显示是否为活跃的用户。 if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1 ], $remember)) { // The user is being remembered... } 种类集成Laravel Cashier可以满足你要开发支付系统所需要的一切需求。除此之外,它还同步并集成了用户身份验证系统。所以,你不再需要担心如何将计费系统集成到开发当中了。 $user = User::find(1); $user>subscription('monthly')>create($creditCardToken);任务自动化Elixir是一个可让我们使用Gulp定义任务的Laravel程序接口,我们可以使用Elixir定义可精简CSS 和JavaScript的预处理器。 elixir(function(mix) { mix.browserify('main.js'); });加密一个安全的应用程序应该做到可把数据进行加密。使用Laravel,可以启用OpenSSL安全加密算法AES256CBC来满足你所有的需求。另外,所有的加密值都是由检测加密信息是否被改变的验证码所签署的。 use Illuminate\Contracts\Encryption\DecryptException; try { $decrypted = Crypt::decrypt($encryptedValue); } catch (DecryptException $e) { // }事件处理应用程序中事件的定义、记录和聆听都非常迅速。EventServiceProvider事件中的listen包含记录在你应用程序上所有事件的列表。 protected $listen = [ 'App\Events\PodcastWasPurchased' => [ 'App\Listeners\EmailPurchaseConfirmation', ], ];分页在Laravel中分页是非常容易的因为它能够根据用户的浏览器当前页面生成一系列链接。 paginate(15); return view('user.index', ['users' => $users]); } }对象关系图(ORM)Laravel包含一个处理数据库的层,它的对象关系图被称为Eloquent。另外这个对象关系图也适用于PostgreSQL。 $users = User::where('votes', '>', 100)>take(10)>get(); foreach ($users as $user) { var_dump($user>name); }单元测试单元测试的开发是一个耗费大量时间的任务,但是它却是保证我们的应用程序保持正常工作的关键。Laravel中可使用PHPUnit执行单元测试。 visit('/') >see('Laravel 5') >dontSee('Rails'); } }待办事项清单Laravel提供在后台使用待办事项清单(to do list)处理复杂、漫长流程的选择。它可以让我们异步处理某些流程而不需要用户的持续导航。 `Queue :: push ( new SendEmail ( $ message ));` 转载:https://mp.weixin.qq.com/s/r10CZJF4AyZo-T1LRDFMeg;
2022年06月19日
255 阅读
0 评论
0 点赞
2022-06-19
【网络安全】常见的网络攻击
CSRF攻击跨站点请求伪造。攻击者盗用用户身份发送恶意请求,执行攻击性代码进行攻击。预防方法:验证HTTP中的referer字段: HTTP中的referer字段中记录了该http的请求来源地址,黑客进行CSRF攻击时,必须在其带有攻击性代码的网站中进行请求伪造,当该请求发送至目标网站中时,referer字段中记录的请求来源地址实际上是黑客的网站地址。在请求地址中添加token验证 CSRF攻击是利用存在cookie中的用户信息进行请求伪造和通过安全验证,在http请求中以参数的形式添加一个随机的token,并在服务器建立一个拦截器进行验证,如果请求中没有token或者token内容不正确,则可以认为是CSRF攻击。在HTTP头中自定义属性并验证。SQL注入SQL注入是一种将SQL代码添加到输入参数中,传递到服务器解析并执行的一种攻击手法。SQL注入攻击是输入参数未经过滤,然后直接拼接到SQL语句当中解析,执行达到预想之外的一种行为,称之为SQL注入攻击。数字注入:OR 1 =1字符串注入(‘#’、’.... ‘):'-- ' (--后面有个空格):'--'后面的字符串都会被当成注释来处理;'#'后所有的字符串都会被当成注释来处理SQL注入是怎么产生的?1)WEB开发人员无法保证所有的输入都已经过滤2)攻击者利用发送给SQL服务器的输入参数构造可执行的SQL代码(可加入到get请求、post请求、http头信息、cookie中)3)数据库未做相应的安全配置如何预防SQL注入?1)严格检查输入变量的类型和格式2)过滤和转义特殊字符3)使用正则表达式过滤传入的参数XSS攻击跨站脚本攻击。通过对网页注入可执行代码且成功地被浏览器 执行,达到攻击的目的。预防方法:mysql_real_escape_string 函数转义 SQL 语句中使用的字符串中的特殊字符。 htmlspecialchars 函数把预定义的字符转换为 HTML 实体。 strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签。Cookie攻击Cookie窃取攻击,最基本的XSS跨站攻击方法就是窃取受害者Cookie信息。Cookie窃取攻击的步骤1、判断网站是否存在反射型XSS/存储型XSS漏洞 2、注入Cookie信息窃取的恶意代码3、 冒充被害人身份登陆网站其他攻击手段攻击手段永远都比防御方法多得多。因此平时的业务中需要及时的添加各种攻击防御策略。
2022年06月19日
129 阅读
0 评论
0 点赞
2022-06-19
【PHP】PHP易混淆函数区别(面试题常见)
1、echo、print、print_r/var_dump的区别 echo():可以一次输出多个值,多个值用逗号隔开,echo是语言结构,而并不是真正的函数,因此不 能作为表达式的一部分使用。 print():打印一个值(它的参数),如果字符串成功显示则返回true,否则返回false print_r():可以把字符串和数字简单地打印出来,而数组则以括起来的键和值得列表形式显示,并以Array开头 var_dump():判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型。此函数显示关于一 个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。2、include、include_once、require、require_once的区别 include():使用include应用外部文件时,只有代码执行到include语句时,外部文件才会被引入并读取,当所引用的外部文件 发生错误时,系统只给出一个警告,而整个php文件则继续向下执行。 include_once():使用include_once语句会在导入文件前先检测该文件是否在该页面的其他部分被应用过,如果有,则不会重复 引用该文件,程序只能引用一次。 require():使用require语句来调用文件时,如果调用的文件没找到,require语句会输出错误信息,并且立即终止脚本处理 require_once():使用require_once语句时,会先检查要引用的文件是不是已经在该程序中的其他地方被引用过,如果有,则不 会在重复调用该文件,在同一个页面中引用了两个相同的文件,那么在输出时,只有第一个文件被执行,第二次引用的文件 则不会被执行。3、empty、isset、is_null的区别 empty:如果 var 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE isset: 检测变量是否设置;如果 var 存在则返回 TRUE,否则返回 FALSE。如果已经使用 unset() 释放了一个变量之后,它 将不再是 isset()。若使用 isset() 测试一个被设置成 NULL 的变量,将返回 FALSE。 is_null:当参数满足下面三种情况时,将返回TRUE,其它的情况就是FALSE。 * 它被赋值为NULL * 它还没有赋值 * 它未定义,相当于 unset(),将一个变量 unset()后,不就是没有定义吗 $myvar = NULL; var_dump(is_null($myvar)); // TRUE $myvar1; var_dump(is_null($myvar1)); // TRUE Notice: Undefined variable $num = 520; unset($num); var_dump(is_null($num)); //TRUE Notice: Undefined variable var_dump(is_null($some_undefined_var)); //TRUE Notice: Undefined variable $myvar = 0; is_null($myvar); // FALSE $myvar = FALSE; is_null($myvar); // FALSE $myvar = ''; is_null($myvar); // FALSE4、双引号和单引号的区别一般情况下两者是通用的.但双引号内部变量会解析,单引号则不解析.双引号中的变量和特殊字符 (\r\n) 会被转义,单引号中的内容不会被转义5、session和cookie的区别(1)cookie数据存放在客户的浏览器上,session数据放在服务器上。 (2)cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。 (3)单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。 (4)session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能 考虑到减轻服务器性能方面,应当使用COOKIE6、get和post的区别(1)GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接; (2)POST请求:POST请求会把请求的数据放置在HTTP请求包的包体中。 (3)GET请求在URL中传送的参数是有长度限制的,而POST没有。 (4)POST相对于GET更加安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。7、传值与传引用的区别传值:把实参的值赋值给形参,对形参的修改不会影响到实参的值 传引用:真正的以地址的方式传递参数,传递以后,行参和实参都是同一个对象,对行参的修改将影响实参的值 8、==和===的区别、“!==”与“!=”的区别===比较两个变量的值和类型;==比较两个变量的值,不比较数据类型。9、->和=>的区别->用来引用对象的成员(属性与方法) =>只用来数组赋值10、?? 与 ?:区别?? :用于判断并赋值,先判断当前变量是否为null,如果是就可以赋一个新值 ?:常用于三元运算符,问号的作用是选择条件作为程序继续执行的分支11、跳出循环:exit、return、break、continue之间的区别 exit:用来结束程序执行的。可以用在任何地方,本身没有跳出循环的含义。 return: (1)从当前的方法中退出,返回到该调用的方法的语句处,继续执行。 (2)返回一个值给调用该方法的语句,返回值的数据类型必须与方法的声明中的返回值的类型一致。 (3)return 后面也可以不带参数,不带参数就是返回空,其实主要目的就是用于想中断函数执行,返回调用函数处。 break: (1)当它在循环体内,强行结束循环的执行,也就是结束整个循环过程,不在判断执行循环的条件是否成立,直接转 向循环语句下面的语句。 (2)当它出现在循环体中的switch语句体内时,其作用只是跳出该switch语句体。 continue:终止本次循环的执行,即跳过当前这次循环中continue语句后尚未执行的语句,接着进行下一次循环条件的判断。12、function_exists、method_exists、class_exists、property_exists、is_subclass_of 的区别 function_exists( string $function_name ) : 函数用于检测函数是否被定义,检测的函数可以是 PHP 的内置函数,也可以 是用户的自定义函数。如果被检测的函数存在则返回 TRUE ,否则返回 FALSE 。 method_exists ( mixed $object , string $method_name ) :检查类的方法是否存在于指定的 object中。如果检测的方法存 在与指定的对象中,则返回true,否则返回false。 class_exists ( string $class_name [, bool $autoload = TRUE ] ) :检查类是否被定义。第一个参数为检测的类名(如果 使用了命名空间后,需要使用完整的带命名空间的类名,如:app\admin\service\UserService ); class_exists()会默认将 会尝试调用 _autoload,如果不想让 class_exists() 调用_autoload,可以将 autoload 参数设为 FALSE。 property_exists([mixed] $class,string $property):判断类或对象中的属性是否存在(可无视属性权限),存在返回true, 否则返回false,$class 可以是类名(字符串)或类对象,$property为属性的名字 is_subclass_of ( object $object , string $class_name ):判断一个对象是否为一个类的子类,返回bool值13、PHP四种网页重定向方式 header('location:http://www.baidu.com'); echo '<meta http-equiv="refresh" content="1;http://www.baidu.com">'; echo '<script>window.location.href="http://www.baidu.com"</script>'; echo file_get_contents('http://www.baidu.com');14、php三种合并数组的方式 array_merge($arr, $arr_1); // 合并数组,如果健名为整数,键名会从 0 开始进行重新索引。 array_merge_recursive($arr, $arr_1); // 递归合并数组,不会进行键名覆盖,而是将多个相同键名的值递归组成一个数组 $arr + $arr_1 // 保留键名,追加数组转载:https://www.kancloud.cn/chunyu/php_basic_knowledge/767174
2022年06月19日
164 阅读
0 评论
0 点赞
2022-06-19
【MySQL】优化MySQL数据库的方法
1、开启慢查询日志,使用mysql慢查询日志对有效率问题的sql语句进行监控,定位执行较慢的查询语句,从而决定优化方案2、sql查询优化,如使用连接(JOIN)来代替子查询、优化group by查询等3、建立合适的索引4、适用外键,保证数据的关联性5、使用事务,事务的另一个重要作用是当多个用户同时使用相同的数据源时,它可以利用锁定数据库的方法来为用户提供一种安全的访问方式,这样可以保证用户的操作不被其它的用户所干扰。6、数据库表结构优化表的垂直拆分:把有很多列的表拆分成多个表,解决表的宽度问题。通常是按照功能进行拆分,可以按以下原则:不常用的字段单独存放一个表中,大字段独立存放在一张附表中。业务模块不明晰,耦合(表关联)度比较高的系统不适合这种拆分方式。表的水平拆分:当表的数据比较多的时候,可以选择将表进行水平拆分,水平拆分的本质并没有改变表的结构仅是将原本存放在同一个表中的数据放到了多个结构一样的表中。
2022年06月19日
228 阅读
0 评论
0 点赞
2022-06-19
【PHP】面向对象 - 魔术方法(集合)
构造函数和析构函数构造函数:PHP5可以在类中使用__construct()定义一个构造函数,具有构造函数的类,会在每次对象创建的时候调用该函数,因此常用来在对象创建的时候进行一些初始化工作。构造函数可以接受参数,能够在创建对象时赋值给对象属性构造函数可以调用类方法或其他函数构造函数可以调用其他类的构造函数PHP中的子类的构造函数不会主动调用父类的构造函数,要显示的使用parent::__construct()调用:也可以使用类名直接调用构造函数 private $name; public function __construct($name){ $this->setName($name); parent::__construct($name);//调用父类构造函数 Animal::__construct($name); // 调用Animal构造函数 }析构函数析构函数指的是当某个对象的所有引用被删除,或者对象被显式的销毁时会执行的函数。析构函数是在销毁对象时自动调用,不能显示的调用析构函数不能带参数要执行父类的析构函数,必须在子类的析构函数中显示调用parent::__destruct()以下几种情况可能会调用析构函数:页面加载完毕、unset()、变量引用指向别的对象或值时 <?php class test{ function __destruct(){ echo "当对象销毁时会调用!!!"; } } $a = $b = $c = new test(); unset($b); ?>私有属性的设置获取实际应用中,经常会把类的属性设置为私有(private),那么需要对属性进行访问时,就会变得麻烦。虽然可以将对属性的访问写成一个方法来实现,但 PHP 提供了一些特殊方法来方便此类操作。_set() 方法用于设置私有属性值;在类里面使用了 __set() 方法后,当使用 $p1->name = "张三"; 这样的方式去设置对象私有属性的值时,就会自动调用 __set() 方法来设置私有属性的值。function __set($property_name, $value){ $this->$property_name = $value; }_get() 方法用于获取私有属性值function __get($property_name, $value){ return isset($this->$property_name) ? $this->$property_name : null; }_isset() 方法用于检测私有属性是否被设置;如果对象里面成员是公有的,可以直接使用 isset() 函数。如果是私有的成员属性,那就需要在类里面加上一个 __isset() 方法: private function __isset($property_name){ return isset($this->$property_name); }_unset() 方法用于删除私有属性;同 isset() 函数一样,unset() 函数只能删除对象的公有成员属性,当要删除对象内部的私有成员属性时,需要使用__unset() 方法: private function __unset($property_name){ unset($this->$property_name); }__toString()方法__toString() 是快速获取对象的字符串信息的魔术方法,它在直接输出对象引用时自动调用。__toString() 的作用:当我们调试程序时,需要知道是否得出正确的数据,比如打印一个对象时,看看这个对象都有哪些属性,其值是什么。如果定义了toString方法,在打印对象体时,就会自动调用该方法,格式化输出这个对象所包含的数据。 <?php class Person{ private $name = ""; function __construct($name = ""){ // 定义构造函数 $this->name = $name; } public function say(){ // 定义公共方法 echo "hello,".$this->name."!"; } function __toString(){ // 定义获取字符串的魔术方法 return "__toString:".$this->name.'!'; } } $blog = new Person('blog'); $blog->say(); // 输出:hello,blog! echo $blog; // 输出:__toString:blog! ?>如果没有定义__toString() 方法,则执行echo语句时,会报错。Catchable fatal error: Object of class Person could not be converted to string in /usercode/file.php on line 16__clone()方法clone关键字用于克隆一个完全一样的对象,克隆之后两个对象互不干扰。适用场景:在编码过程中,有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。 // 使用clone关键字之前的复制效果实例 // // 定义一个类,类中定义一个公共成员变量 class TestClass{ public $value; } $obj = new TestClass(); // 实例化TestClass类的对象 $obj->value = 'qq'; // 给成员变量赋值 var_dump($obj); // object(TestClass)#228 (1) { ["value"]=> string(2) "qq" } $obj2 = $obj; // 将$obj赋值给$obj2变量,等同于复制一个$obj $obj2->value = 'zz'; // 更改$value的值 var_dump($obj); // object(TestClass)#228 (1) { ["value"]=> string(2) "zz" } var_dump($obj2); // object(TestClass)#228 (1) { ["value"]=> string(2) "zz" }从以上的例子可以看出来当实例化对象赋值给其他变量时,改变实例化对象和改变赋值对象,另一方都会随之改变。这是因为普象的赋值,仅仅是把新对象指向对象存储的地址(即 $obj给了$obj2它的地址,就和引用一样,$obj2指向了$obj,所以导致两者所执行的操作将会收到影响)。 // 使用clone关键字之后的复制效果实例 // // 定义一个类,类中定义一个公共成员变量 class TestClass { public $value; } $obj = new TestClass(); // 实例化TestClass类的对象 $obj->value = 'qq'; // 给成员变量赋值 var_dump($obj); // object(TestClass)#228 (1) { ["value"]=> string(2) "qq" } $obj2 = clone $obj; // 使用clone关键字克隆$obj $obj2->value = 'zz'; // 更改$value的值 var_dump($obj); // object(TestClass)#228 (1) { ["value"]=> string(2) "qq" } var_dump($obj2); // object(TestClass)#228 (1) { ["value"]=> string(2) "zz" }可以看出,使用clone关键字之后,更改$obj2的成员变量值并不会对$obj的成员变量产生影响,克隆之后的两个对象$obj和$obj2是互不影响,互相独立的。__clone方法用于重写原本的属性和方法;__clone() 方法只会在对象被克隆的时候自动调用。__clone()方法对一个对象实例进行的浅复制,对象内的基本数值类型进行的是传值复制,而对象内的对象型成员变量,如果不重写__clone方法,显式的clone这个对象成员变量的话,这个成员变量就是传引用复制,而不是生成一个新的对象。 // 定义age类 class Age{ public $balance; public function __construct($balance){ $this->balance = $balance; } } // // 定义第二个类,类中包括两个公共成员以及构造函数、克隆方法 class IndexService{ public $age; // 对象属性成员变量 public $name; // 非对象属性成员变量 public function __construct($name, Age $age){ $this->name = $name; $this->age = $age; } // 使用clone的时候触发 public function __clone() { $this->name = 'name:'.$this->name; $this->age = clone $this->age; // 这个对象会被强制复制,这样就不会指向原来的对象。 } } // 运行 $obj = new IndexService('peter',new Age(20)); $obj2 = clone $obj; $obj2->age->balance = 10; var_dump($obj); var_dump($obj2); // age对象中的balance值更改为10,name值也被更改。注意: __clone()方法中的clone操作只能用于对象,如果用于非对象属性,将会报错:# 致命错误: __clone method called on non-object。例子中的age就是一个对象。以上例子中,$age对象被强制复制,不会指向原来的对象,所以修改其中的值之后,并不会对原来对象有影响;如果不加上$this->age = clone $this->age;这行代码,运行结果则变成这样:两个对象的age对象的balance值都改成了10。__call()方法__call() 方法用于监视错误的方法调用。该方法在调用的方法不存在时会自动调用,程序会继续执行下去。该方法有两个参数,第一个参数会自动接收不存在的方法名,第二个参数则以数组的方式接收不存在方法的多个参数。 <?php class Test { function __call($function_name, $args) { echo "你所调用的函数:$function_name(参数:<br />"; var_dump($args); echo ")不存在!"; } } // 调用不存在的方法 $p1=new Test(); $p1->test(2,"test"); //你所调用的函数:test(参数:array(2) {[0]=> int(2) [1]=>string(4) "test"})不存在! 类的自动加载php实现类文件自动载入有两种办法:魔术方法:__autoload();SPL标准库提供的spl_autoload_register();__autoload()__autoload()是php中的一个魔术方法,在代码中当调用不存在的类的时候会自动调用。在开发过程中可以使用include或者require函数来引入需要调用的类文件,但是如果需要调用的类很多的时候,对应的include或者require也会很多,会造成代码冗余,而且每次执行都要加载这些文件,会白白占用内存,其次当删除了某个类文件时,也要对应的修改include或者require语句。使用__autoload()魔术方法来代替include或者require语句,则可以避免大量的代码冗余,也可以提高执行效率。在 Test.php文件中我们调用 类Test1 和 类Test2,由于我们没有显式的引用类文件,那么系统就会自动调用 __autoload() 方法。 //Test.php文件 function __autoload($class){ if(file_exists($class.".php")){ require_once($class.".php"); }else{ die("文件不存在!"); } } Test1::test(); Test2::test();__autoload()的缺点:一个文件中只允许有一个__autoload(),当引入的项目中有其他__autoload()时,则会发生冲突。当项目中的类根据不同的用处放在不同的文件夹中,此时要分别调用对应的类,会十分困难。spl_autoload_register()该函数可以注册任意数量的自动加载器,当使用未被定义的类和接口时自动去加载。code here... //Test.php文件 function my_autoload1($class){ if(file_exists("classes/".$class.".php")){ require_once("classes/".$class.".php"); }else{ die("文件不存在!"); } } function my_autoload2($class){ if(file_exists("core/".$class.".php")){ require_once("core/".$class.".php"); }else{ die("文件不存在!"); } } //将加载函数注册到PHP中 spl_autoload_register("my_autoload1"); spl_autoload_register("my_autoload2"); Test1::test(); Test2::test();鸣谢:看云chunyu
2022年06月19日
258 阅读
0 评论
0 点赞
2022-06-19
【PHP】面向对象 - instanceof关键字
instanceof是PHP5引入的新关键字。使用这个关键字可以判断一个对象是类的实例、类的子类,还是实现了某个特定接口。用法一: // 判断对象是否是某个类的实例 <?php $obj = new Demo(); if ($obj instanceof Demo) { echo '$obj 是Demo类的一个实例。'; } 用法二: // 判断一个对象是否实现了某个接口 <?php interface ExampleInterface{ public function interfaceMethod(); } class ExampleClass implements ExampleInterface{ public function interfaceMethod(){ return 'Hello World!'; } } $exampleInstance = new ExampleClass(); if($exampleInstance instanceof ExampleInterface){ echo '$exampleInstance 对象实现了ExampleInterface接口'; }用法三: // 判断子类是否继承自某个基类 <?php class Demo{} class DemoSub extends Demo{} $obj = new DemoSub(); if($obj instanceof Demo){ echo 'DemoSub类继承自Demo类'; }
2022年06月19日
185 阅读
0 评论
0 点赞
2022-06-19
【PHP】面向对象 - trait关键字
PHP是单继承语言,因此一个类不能同时继承多个类。 Trait的出现主要是为了解决单继承语言的局限性问题,是PHP多重继承的一种解决方法。trait不是类,所以不能有静态成员、类常量,当然也不可能被实例化。创建新文件来声明Trait: trait first_trait { function first_method() { /* Code Here */ } }在类中使用 use + trait名进行引用即可,引用之后就可以使用trait中声明的方法。 class test { use first_trait; private $method; public function __construct() { $this->method = $this->first_method(); } }
2022年06月19日
246 阅读
0 评论
0 点赞
2022-06-19
【PHP】面向对象 - 接口(interface)
PHP是单继承语言,因此一个类不能同时继承多个类。当一个类需要多个类的功能时,除了使用trait关键字,还可以使用接口技术。如果一个抽象类里面的所有方法都是抽象方法,且没有声明变量,而且接口里面所有成员都是public权限的,那么这种特殊的抽象类就是接口。应用场景:保持规范、统一性多个类需要实现同样的方法,只是实现方式不一样接口使用规范:接口不能实例化接口属性必须是常量接口方法必须是public,且不能有函数体类必须实现接口的所有方法一个类可以同时实现多个接口,用逗号隔开接口可以继承接口,使用extends关键字。接口使用关键字interface来定义,使用implements关键字来实现类要实现接口,必须使用和接口中所定义的方法完全一致的方式。否则会导致致命错误.实现多个接口时,接口中的方法不能有重名。 <?php //定义接口 interface User{ function getDiscount(); function getUserType(); } //VIP用户 接口实现 class VipUser implements User{ // VIP 用户折扣系数 private $discount = 0.8; function getDiscount() { return $this->discount; } function getUserType() { return "VIP用户"; } } class Goods{ var $price = 100; var $vc; //定义 User 接口类型参数,这时并不知道是什么用户 function run(User $vc){ $this->vc = $vc; $discount = $this->vc->getDiscount(); $usertype = $this->vc->getUserType(); echo $usertype."商品价格:".$this->price*$discount; } } $display = new Goods(); $display ->run(new VipUser); // VIP用户商品价格:80 元 ?>
2022年06月19日
188 阅读
0 评论
0 点赞
2022-06-19
【PHP】面向对象 - self、$this、parent::关键字
$this$this是指向对象实例的一个指针(在实例化的时候来确定指向),不指向任何其他对象或类使用形式:$this->实例属性或实例方法()selfself是指向类本身,也就是self是不指向任何已经实例化的对象,一般self使用来指向类中的静态变量。假如我们使用类里面静态(一般用关键字static)的成员,我们也必须使用self来调用。self调用静态变量必须使用:: (域运算符号),使用形式:self :: 静态属性或静态方法();parent::parent是指向父类的指针parent::可以用于调用父类中定义的方法。 class Count{ //建立了一个名为count的基类 private $lastCount; //定义属性,私有 private static $firstCount = 0; //定义构造函数,用于初始化赋值 function __construct( ) { parent::__construct(); //调用父类构造函数 $this->lastCount=$lastCount; //这里已经使用了this指针 $this->lastCount=++self::$firstCount; //使用self来调用静态变量 } }
2022年06月19日
163 阅读
0 评论
0 点赞
2022-06-19
【PHP】面向对象 - abstract关键字
abstract用于定义抽象方法和抽象类。抽象方法:抽象方法指没有方法体的方法,在方法声明事没有{}括弧以及其中的内容,而是直接在声明了方法后加上分号结束。abstract function function_name();抽象类:只要一个类中有一个方法是抽象方法,那么这个类就要定义为抽象类,抽象类同样用abstract关键字来定义。抽象类不能产生实例对象,通常是将抽象方法作为子类方法重载的模板使用,且要把继承的抽象类里的方法都实现。抽象类是方便继承而引入的。 <? abstract class Demo{ var $test; abstract function fun1(); abstract function fun2(); function fun3() { ... } } $demo=new Demo(); //抽象类不能产生实例对象,所以这样做是错的,实例化对象交给子类 class Test extends Demo{ function fun1() { ... } function fun2() { ... } } $test = new Test(); //子类可以实例化对象,因为实现了父类中所有抽象方法 ?>
2022年06月19日
174 阅读
0 评论
0 点赞
2022-06-17
【PHP】面向对象 - final关键字
final关键字final关键字用于修饰类和方法。如果父类中的方法声明了final,则子类无法对其覆盖;如果父类声明了final,则不能被继承。 //父类: final class BaseClass { public function test() { echo "use test\n"; } final public function moreTesting() { echo "use moreTesting\n"; } } //子类继承父类: class ChildClass extends BaseClass { public function moreTesting() { echo "use moreTesting1111111\n"; } } //运行结果报错 PHP Fatal error: Cannot override final method BaseClass::moreTesting()
2022年06月17日
154 阅读
0 评论
0 点赞
2022-06-17
【PHP】面向对象 - const关键字
constconst是一个定义常量的关键字用“const”修饰的成员属性的访问方式和“static”修饰的成员访问的方式差不多,也是使用“类名”,在方法里面使用“self”关键字。但是不用使用“$”符号,也不能使用对象来访问。 <?php class MyClass{ //定义一个常量CONSTANT const CONSTANT = 'constant value'; function showConstant() { echo self::CONSTANT ; // 使用self访问,不要加“$” } } echo MyClass::constant ; //使用类名来访问,也不加“$” $class = new MyClass(); $class->showConstant(); // echo $class::constant; 是不允许的 ?>
2022年06月17日
176 阅读
0 评论
0 点赞
2022-06-17
【PHP】面向对象 - 静态方法与普通方法
静态方法:静态和公共、受保护、私有这3种属性格式没有关系, 他们并不是并列的静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用在同一个类中可通过self::关键字来调用静态方法;不同类中,可以通过类的实例化对象来调用静态方法或者通过 类名::静态方法名的方式调用。类里面的静态方法只能访问类的静态属性,不能访问类的非静态成员。从程序运行开始就实例生成内存 ,会高很多,但静态内存是有限制的,实例太多会占用大量内存,且.静态内存会常驻适用于多次频繁调用普通方法:实例方法开始生成内存,执行效率相对于静态方法会慢很多普通方法不会常驻内存可以通过$this,self关键字来调用,即普通方法需要对象去调用,而静态方法不需要
2022年06月17日
186 阅读
0 评论
0 点赞
2022-06-17
【PHP】面向对象 - 静态变量与普通变量
在变量的前面加上static 就构成了静态变量(static 变量)。静态变量:静态变量属于静态存储方式,其存储空间为内存中的静态数据区(在静态存储区内分配存储单元),该区域中的数据在整个程序的运行期间一直占用这些存储空间(在程序整个运行期间都不释放),也可以认为是其内存地址不变,直到整个程序运行结束。(在函数执行完后不会被销毁,保留上次值)静态变量虽在程序的整个执行过程中始终存在,但是在它作 用域之外不能使用。属于静态存储方式的变量不一定就是静态变量。 例如:外部变量(在PHP中指全局变量)虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。静态局部变量:static类型的内部变量是一种只能在某个特定函数中使用,只会被初始化一次。当在某函数里定义一个静态变量后,这个变量不会即使函数退出了,在下次调用这个函数时,它会使用前次被调用后留下的值。作用域为该函数内部,外部函数不能使用。局部静态变量定义时没有赋初值,系统会自动赋初值0(对数值型变量)或空字符(对字符变量)。局部静态变量占用内存时间较长,并且可读性差全局局部变量:全局变量(外部变量)的声明之前加上static 就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。普通变量:非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。动态变量,属于动态存储类别,占动态存储空间,函数调用结束后即释放,不会保留上次函数运行的值。 // 静态局部变量:函数每次执行都会保留上次值 function static_test() { static $test = 0; $test++; echo $test; } static_test();// 第一次执行 输出 1 static_test();// 第二次执行 输出 2 // 普通局部变量:函数每次执行完都释放 function test() { $test = 0; $test++; echo $test; } test();// 第一次执行 输出 1 test();// 第二次执行 输出 1把局部变量改变为静态变量后是改变了它的存储方式,即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
2022年06月17日
184 阅读
0 评论
0 点赞
2022-06-17
【PHP】面向对象 - static关键字
staticstatic关键字是在类中描述成员属性和方法是静态的。static成员能够限制外部的访问,因为static成员是属于类的,不属于任何对象实例,是在类第一次被加载的时候分配的空间,其他类无法访问,只能对垒的实例共享,能对类的成员形成保护静态成员是在类第一次加载的时候就创建的,所以在类的外部不需要对象而使用类名就可以访问的到静态的成员。类里面的静态方法只能访问类的静态属性,不能访问类的非静态成员。在静态方法中可以通过使用 self::成员属性的方法进行访问。静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。 <? class Person{ //下面是人的静态成员属性 public static $myCountry = "中国"; //这是人的静态成员方法 public static function say() { echo "我是中国人"; } } //输出静态属性 echo Person::$myCountry; //访问静态方法 Person::say(); (new Person())->say(); //重新给静态属性赋值 Person::$myCountry = "美国"; echo Person::$myCountry; ?>
2022年06月17日
196 阅读
0 评论
0 点赞
2022-06-17
【PHP】面向对象 - 访问权限
public: 公有类型 在子类中可以通过self::var调用public方法或属性,parent::method调用父类方法在实例中可以能过$obj->var 来调用 public类型的方法或属性protected: 受保护类型在子类中可以通过self::var调用protected方法或属性,parent::method调用父类方法在实例中不能通过$obj->var 来调用 protected类型的方法或属性private: 私有类型该类型的属性或方法只能在该类中使用在该类的实例、子类中、子类的实例中都不能调用私有类型的属性和方法 <?php //父类 class father{ public function a(){ echo "public function a".PHP_EOL; } private function b(){ echo "private function b".PHP_EOL; } protected function c(){ echo "protected function c".PHP_EOL; } } //子类 class child extends father{ function d(){ parent::a();//调用父类的a方法 } function e(){ parent::c(); //调用父类的c方法 } function f(){ parent::b(); //调用父类的b方法 } } $father=new father(); $father->a(); //输出 public function a $father->b(); //显示错误 外部无法调用私有的方法 $father->c(); //显示错误 外部无法调用受保护的方法 $chlid=new child(); $chlid->d();//输出 public function a $chlid->e(); ////输出 protected function c $chlid->f();//显示错误 无法调用父类private的方法 Uncaught Error: Call to private method father::b() from context 'child'
2022年06月17日
153 阅读
0 评论
0 点赞
2022-06-17
【PHP】面向对象 - 三大基本特征和五大基本原则
面向对象基本特征:封装隔离性:被封装后的对象,其外部对象是无法直接访问对象的内部实现细节,内部实现细节的的改动不会影响到外部对象的访问原则(即:对象内部修改后,在公开暴露指定的访问路径不变的情况下,外部访问它的对象是无需修改的),这是隔离性的体现,同时也是实现高内聚,低耦合的最根本的思想之一;可复用性:被封装后的对象可以被外部多个对象访问,而无需为每个外部对象去指定不同的服务对象;减少代码的冗余。可读性:合理设置被封装的对象名称,可增强代码的可读性,通过方法名或者类名即可了解其作用。继承PHP中主要通过extends关键字来实现继承: class Student extends Person{}PHP只能单继承,不支持一个类继承多个类。但是一个类可以进行多层继承(即A继承于B,而C又继承于A,C通过A间接继承了B)子类继承父类非私有的属性和方法,可以通过$this关键字进行访问覆盖:子类中声明与父类相同名称的属性和方法,则该属性和方法会覆盖父类中的属性和方法,属性被覆盖后,无法访问父类中的属性,方法被覆盖后,可以通过parent::方法名()进行访问多态同一方法作用于不同对象时,产生不同的执行结果多态存在的三个必要条件:继承、重写(子类继承父类后对父类方法进行重新定义)、父类引用指向子类对象示例如下: abstract class Person{ // 父类使用abstract关键字修饰 abstract function say(); } class Chinese extends Person{ // 子类重写父类方法 function say(){ echo "我是中国人<br>"; } } class English extends Person{ // 子类重写父类方法 function say(){ echo "我是英国人"; } } $zhangsan = new Chinese(); $zhangsan->say(); $z = new English(); $z->say(); Person $p = new Chinese(); // 父类引用指向子类对象上述代码中,两个子类都是继承自同一父类,但因为都重写了父类的方法,表现出了不同的形态 基本原则:1、单一职责原则(SRP)单一职责有两个含义:一个是避免相同的职责分散到不同的类中,另一个是避免一个类承担太多职责2、开放封闭原则(OCP)一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的3、里氏替换原则(LSP)子类型必须能够替换掉它们的父类型,并出现在父类能够出现的任何地方。4、依赖倒置原则(DIP)依赖倒置简单地讲就是将依赖关系倒置为依赖接口,具体概念如下:上层模块不应该依赖于下层模块,它们共同依赖于一个抽象(父类不能依赖子类,它们都要依赖抽象类)。抽象不能依赖于具体,具体应该依赖于抽象。5、接口隔离原则(ISP)不同的模块要通过抽象接口隔离开,而不是通过具体的类强耦合。
2022年06月17日
217 阅读
0 评论
0 点赞
2022-06-17
【PHP】PHP函数大全
PHP函数大全有道云地址:http://note.youdao.com/noteshare?id=f1271100f4366b0338e9a45b8bbd4db7&sub=0DA577EC658B4923A67FA4EB862D2FDA
2022年06月17日
141 阅读
0 评论
0 点赞
2022-06-17
【Nginx】Nginx Log日志统计分析常用命令
IP相关统计统计IP访问量(独立ip访问数量) awk '{print $1}' access.log | sort -n | uniq | wc -l 查看某一时间段的IP访问量(4-5点) grep "07/Apr/2017:0[4-5]" access.log | awk '{print $1}' | sort | uniq -c| sort -nr | wc -l 查看访问最频繁的前100个IP awk '{print $1}' access.log | sort -n |uniq -c | sort -rn | head -n 100 查看访问100次以上的IP awk '{print $1}' access.log | sort -n |uniq -c |awk '{if($1 >100) print $0}'|sort -rn 查询某个IP的详细访问情况,按访问频率排序 grep '127.0.01' access.log |awk '{print $7}'|sort |uniq -c |sort -rn |head -n 100 页面访问统计查看访问最频的页面(TOP100) awk '{print $7}' access.log | sort |uniq -c | sort -rn | head -n 100 查看访问最频的页面([排除php页面】(TOP100) grep -v ".php" access.log | awk '{print $7}' | sort |uniq -c | sort -rn | head -n 100 查看页面访问次数超过100次的页面 cat access.log | cut -d ' ' -f 7 | sort |uniq -c | awk '{if ($1 > 100) print $0}' | less 查看最近1000条记录,访问量最高的页面 tail -1000 access.log |awk '{print $7}'|sort|uniq -c|sort -nr|less每秒请求量统计统计每秒的请求数,top100的时间点(精确到秒) awk '{print $4}' access.log |cut -c 14-21|sort|uniq -c|sort -nr|head -n 100每分钟请求量统计统计每分钟的请求数,top100的时间点(精确到分钟) awk '{print $4}' access.log |cut -c 14-18|sort|uniq -c|sort -nr|head -n 100每小时请求量统计统计每小时的请求数,top100的时间点(精确到小时) awk '{print $4}' access.log |cut -c 14-15|sort|uniq -c|sort -nr|head -n 100性能分析在nginx log中最后一个字段加入$request_time 列出传输时间超过 3 秒的页面,显示前20条 cat access.log|awk '($NF > 3){print $7}'|sort -n|uniq -c|sort -nr|head -20 列出php页面请求时间超过3秒的页面,并统计其出现的次数,显示前100条 cat access.log|awk '($NF > 1 && $7~/\.php/){print $7}'|sort -n|uniq -c|sort -nr|head -100蜘蛛抓取统计统计蜘蛛抓取次数 grep 'Baiduspider' access.log |wc -l 统计蜘蛛抓取404的次数 grep 'Baiduspider' access.log |grep '404' | wc -lTCP连接统计查看当前TCP连接数 netstat -tan | grep "ESTABLISHED" | grep ":80" | wc -l 用tcpdump嗅探80端口的访问看看谁最高 tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr
2022年06月17日
129 阅读
0 评论
0 点赞
1
...
9
10
11