资讯专栏INFORMATION COLUMN

PHP Q&A

mikasa / 390人阅读

摘要:有哪些作用域函数作用域类作用域函数作用域是什么函数体是一个局部作用域函数体中无法直接访问外部全局变量,必须通过才能访问外部全局变量无法访问通知错误正确访问外部全局变量无法访问函数体中可以直接访问常量输出函数体中可以直接访问类静态属性静态方法

PHP 有哪些作用域?

函数作用域

类作用域

PHP 函数作用域是什么?

函数体是一个局部作用域

函数体中无法直接访问外部全局变量,必须通过global/$GLOBALS才能访问外部全局变量

$var = "aa";
function showVar(){
    echo $var; //无法访问
}
showVar(); //Notice通知错误

//正确访问外部全局变量
$var = "aa";
function showVar(){
    echo $GLOBALS["var"]; //无法访问
}
showVar();

函数体中可以直接访问常量

define("BBO","wutao");
function showVar(){
    echo BBO;
}
showVar();//输出‘wutao’

函数体中可以直接访问(静态属性、静态方法)和对象(属性、方法)

function showVar(){
    $person = new Person();
    $person->getName();
    Person::getAge();
}

class Person{
    private $name = "不懂撒的";
    public static $age = 200;
        
    public function getName(){
        echo $this->name;
    }
        
    public static function getAge(){
        echo self::$age;
    }
}
    
showVar();
类作用域是什么?有什么注意事项?

类其实就是一个完整且独立的个体,外部(变量与函数)可以直接使用它

//定义一个Person类
class Person{

};
外部变量直接访问类中静态方法/属性与实例化
$var = new Person();
$var1 = Person::test();
//函数内部也是直接访问类中静态方法/属性并使用
function demo(){
    $var1 = Person::test();
    $var = new Person();
}

在类中,方法可以直接调用外部函数或其他类,但不可以直接访问外部变量,外部常量(超全局常量)可以任何地方访问

在类中,属性可以直接访问外部常量(超全局常量),但外部函数、外部变量,其他类就无法访问

$var = "121";
function fn(){}
class Student{}
define("CONF","121");

class Person{
    public $one = new Student(); //不正确,无法访问
    public $two = fn(); //不正确,无法访问
    public $three = $var; //不正确,无法访问
    public $four = CONF; //正确,可以访问
}
PHP 常量有哪些?各自有什么特点?常量取值类型有哪几种?

超全局常量系统内置超全局变量/常量用法一样

//定义超全局常量,无论在函数,方法,还是外部定义,只要定义,此常量都是超全局常量,哪都可以直接使用
define("BOSS","wt"); 

function showVar(){    
    echo BOSS;
    $person = new Person();
    $person->getName();
    Person::getAge();
}

class Person{
    private $name = BOSS;   //wt
    public static $age = BOSS;   //wt
        
    public function getName(){
        echo BOSS;   //wt
        echo $this->name;  //wt
    }
        
    public static function getAge(){
        echo self::$age;  //wt
        echo BOSS;        //wt
    }
}
    
showVar();

类中常量

function showVar(){
    $person = new Person();
    $person->getName();
    Person::getAge();
    echo Person::BMM;   //外部调用类常量
}

class Person{
    const BMM = "xiaomi";
    private $name = self::BMM;  //输出xiaomi
    public static $age = self::BMM;  //输出xiaomi
        
    public function getName(){
        echo $this->name;  //输出xiaomi
    }
        
    public static function getAge(){
        echo self::BMM;  //内部调用类常量
        echo self::$age;  //输出xiaomi
    }
}
    
showVar();

常量类型
boolean/integer/float/string 四种类型之一,不能是其他类型

PHP 变量种类有哪些?各自有什么特点

外部全局变量 $var = "string"; 除4种基本类型,还可以数组/对象/null数据类型;
外部全局变量的特点:函数中要用过global/$GLOBALS才能访问到外部全局变量(一般不推荐这样使用),类中(方法和属性)都无法直接访问外部全局变量

静态变量 在函数中定义的一种变量; static $a = 0;
静态变量的特点:在一次请求响应中,无论函数调用多少次,静态变量的初始化只会执行一次

局部变量 在函数中定义的一种变量; $a = 0;
局部变量的特点:只在定义的函数中有效,函数执行完,局部变量就会释放,所以外部无法访问局部变量

纯净手工编译版PHP如何增加其他扩展类库?

由于PHP是手工编译最简化安装,所以只包含一些基本扩展,其他大部分扩展都没有,后期才按需添加

加入其他扩展,有2种方法

1、重新安装PHP (不推荐)
2、使用PHP官方提供的工具phpize来添加 (添加)

使用phpize来生成其他扩展.so文件

phpize工具所在位置:php安装目录/bin/phpize
所需依赖:autoconf工具 yum install autoconf
步骤:
1、cd /php源码目录/ext
2、找到所需安装扩展库,然后cd进入  //例如: cd curl
3、php安装目录/bin/phpize   //生成configure文件
4、./configure --with-php-config=/usr/local/php/bin/php-config  //生成Makefile
5、make && make install

## 最终.so安装位置在php/bin/php-config中已经指定

php.ini配置文件中加入extension=curl.so

注意:如果想按上面配置,必须在php.ini中配置extension_dir="/usr/local/php/ext"
PHP 如何使用函数更健壮呢?
function_exists("ini_set") && ini_set("memory_limit", "1024M");
PHP 如何定义常量更健壮呢?
defined("GREETING") || define("GREETING","Hello world!");
函数定义时,前面加&代表什么?加与不加&有什么区别?

前置知识

$a = 55;
$b = &$a; //引用变量 $b为55
$b = 100; //$b为100 $a为100

函数的返回方式有2种

1、引用返回方式(定义函数时,前面需加&,否则函数调用时只会普通返回
2、普通返回方式(在调用函数前不能使用&符号,否则会报错)

注意事项

1、如果定义函数时,前面加&的话,函数调用可以使用引用返回普通返回
2、如果定义函数时,前面不加&的话,函数调用可以只可使用普通返回
URL 如何变得更加优美?

原始URL ———— 查询字符串

http://www.test.com/index.php?key=val
参数可以使用 $_GET["key"] 获取,但这样的 URL 很不美观

初步优化 ———— 使用PATHINFO模式

http://www.test.com/index.php/key/val
使用 PATHINFO 模式的 URL ,参数的获取就不可以使用 $_GET["key"] 获取了。

必须使用 $_SERVER["PATH_INFO"] 获取

进一步优化 ———— 隐藏入口文件index.php

http://www.test.com/key/val
要使用到服务器Apache/Nginx的URL重写功能

最终优化 ———— 开发路由层(伪静态)

http://www.test.com/val.html
很多框架都有路由层,此路由优化后的 URL ,对 SEO 最为友好
如何使用 Xdebug 来调试 PHP 代码

在 php.ini 进入如下配置

xdebug.profiler_output_dir="H:installphpStudy	mpxdebug"
xdebug.trace_output_dir="H:installphpStudy	mpxdebug"
zend_extension="H:installphpStudyphpphp-5.6.27-ntsextphp_xdebug.dll"

xdebug.profiler_enable = 1
xdebug.auto_trace = 1
xdebug.show_exception_trace = 1
;这里必须设置为0,为了能使用浏览器插件 xdebug helper配合调试
xdebug.remote_autostart = 0
xdebug.remote_enable = 1
;这里是开启远程调试
xdebug.remote_handler = "dbgp"
;远程调试的host
xdebug.remote_host = "127.0.0.1"
;远程调试的端口号
xdebug.remote_port = 9000
;远程调试的对应 key
xdebug.idekey="PHPSTORM" 

浏览器要安装对应的调试插件

chrome => xdebug helper
火狐 => Xdebug Helper

远程调试

1、要检查防火墙是否已经关闭
2、如果你的项目所在环境是外网,就是IDE所在PC与项目部署环境不能通过IP直接访问,则远程断点方式不能使用。(必须使用域名)
面向对象中 static与self的区别

self非动态的,在哪个类中存在,self就代表哪个类

static是动态的,根据具体哪个类调用,static指向那个类

static与self的区别

PHP 自动加载机制是什么?
在做项目时,我们经常遇到要用到很多类(有些是自己写的,有些是第三方类库的),
使用前必须先加载(include/require),但如果全部自己手动加载,那么将很吃力不讨好:

1、代码量巨大,不好维护,浪费时间
2、无法做到按需加载,运行性能低下
3、还有可能造成重复加载统一类

所以,PHP5提出解决这一问题方法:自动加载机制

第一代自动加载机制 autoload

function __autoload($classname) {
    require_once ($classname . “class.php”);
}

$person = new Person(”Altair”, 6);
var_dump ($person);
看出autoload至少要做三件事情,
第一件事是根据类名确定类文件名
第二件事是确定类文件所在的磁盘路径(在我们的例子是最简单的情况,类与调用它们的PHP程序文件在同一个文件夹下)
第三件事是将类从磁盘文件中加载到系统中(第三步最简单,只需要使用include/require即可)
缺点就是:一般项目都是用到第三方类库,很多时候这种类名与与类文件所在的磁盘路径的映射规则与我们订的不同,如果全部写在一个__autoload()函数里会很臃肿,难维护,性能低等问题

第二代自动加载机制 SPL autoload

PHP5提供的一个SPL扩展,其中提供的自动加载机制用于取代上面第一代自动加载机制

spl_autoload是SPL实现的默认的自动加载函数,它的功能比较简单。我们不能扩展spl_autoload()函数,
怎样让spl_autoload自动起作用呢?在PHP脚本中第一次调用spl_autoload_register()函数,无需传入任何参数,一般不会使用SPL扩展预先定义好的spl_autoload()函数

## 1、注册函数
function my_autoloader($class) {
    include "classes/" . $class . ".class.php";
}
spl_autoload_register("my_autoloader");

## 2、自PHP 5.3.0起可以使用一个匿名函数
spl_autoload_register(function ($class) {
    include "classes/" . $class . ".class.php";
});

## 3、注册类静态方法 -- 自 PHP 5.3.0 起
namespace Foobar;
class Foo {
    static public function test($className) {
        $className = str_replace("", DIRECTORY_SEPARATOR, $className);
    }
}
spl_autoload_register(__NAMESPACE__ ."Foo::test");

## 4、在类方法中调用,注册类静态方法
namespace Foobar;
class Framework{
    public static function init() {
         require_once (__DIR__ . "/functions.php");
         // 自动加载设置
         spl_autoload_register("self::loadClass");
    }
    
    public static function loadClass($className) {
        $className = str_replace("", DIRECTORY_SEPARATOR, $className);
    }
}
如果 加载的类 是在某命名空间内的话,自动加载函数接受到的$class变量将是 thinklibPerson
必须带上命名空间

注意

如果同时定义__autoload()函数和spl_autoload_register()函数,那到底会怎样?
先spl_autoload_register()起效果,如果没有这个函数的话,那么再找__autoload()函数
同时注册多个autoload函数,该如何执行呢?
按顺序执行多个注册的autoload()函数,但只要执行了require/include之后,后面注册的函数就不会执行下去了

autoload()函数内返回return true/false都没有效果

PHP 自动加载机制

4种PHP回调函数风格是什么?
匿名函数回调
$server->on("Request", function ($req, $resp) {
    echo "hello world";
});
类静态方法回调
class A
{
    static function test($req, $resp)
    {
        echo "hello world";
    }
}
$server->on("Request", "A::Test");
$server->on("Request", array("A", "Test"));
函数回调
function my_onRequest($req, $resp)
{
    echo "hello world";
}
$server->on("Request", "my_onRequest");
对象方法
class A
{
    function test($req, $resp)
    {
        echo "hello world";
    }
}

$object = new A();
$server->on("Request", array($object, "test"));

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/23283.html

相关文章

  • python3 queue多线程通信

      小编写这篇文章的主要目的,主要是给大家介绍关于python3 queue多线程通信,这里面有很多的技术性的难点,那么,该怎么去进行处理呢,下面小编给大家进行详细的解答一下。  queue分类  python3 queue分三类:  先进先出队列  后进先出的栈  优先级队列  他们的导入方式分别是: fromqueueimportQueue   fromqueueimportLifoQueue...

    89542767 评论0 收藏0
  • JavaScript树结构深度优先算法

      什么是树  现实中树随处可见;在计算机世界,树就是一种分层结构的抽象模型。  如下图所示:  树结构的可以用在很多情景,就如下图公司的组织架构,用树就可以表达出来,如下图:  组织架构只是其中之一,比如族谱、省市等用树的结构形式展现是完全可以。  树的术语  树有很多的术语,如下图:  树:n(n≥0)个节点所构成的有限集合,当n=0时,称为空树;  节点的度:节点的子树个数,例如B节点的度就...

    3403771864 评论0 收藏0
  • redis Q&A

    摘要:是什么基于内存有客户端和服务器端非关系型数据库应用场景是什么缓存队列数据持久存储如何安装如何启动如何关闭客户端如何启动下载解压编译安装服务启动注意这种方式启动使用的是默认配置通过启动参数告诉使用指定配置文件使用下面命令启动服务关 redis 是什么? 基于内存 有客户端和服务器端 NoSQL非关系型数据库 redis 应用场景是什么? 缓存 队列 数据持久存储 redis 如何...

    saucxs 评论0 收藏0
  • Python必考五大面试题是什么?下文给大家解答

      小编写这篇文章的一个主要目的,主要是来给大家做个介绍,介绍的内容主要是涉及到Python一些试题的讲解,小编给大家总结出来了五道必考的题目,大家可要仔细阅读哦,下面就给大家详细解答。  1、使用while循环实现输出2-3+4-5+6...+100的和  #方法一   #从2开始计算   i=2   #定义一个变量用于保存结果   sum=0   whilei<=100:   i...

    89542767 评论0 收藏0
  • WebServer Q&A

    摘要:进程的工作就是管理子进程,而子进程的工作就是处理用户请求。当新的请求过来的时候,管理线程会把请求交给其他的空闲线程处理。 当前主流的web服务器有哪些? Apache Nginx iis Apache的工作模式有哪些?各自的特点和优缺点是什么?适用场景是什么? apache主要工作模式有3种,分别如下: prefork工作模式 特点 prefork模式是一种非线程的多进程模型,we...

    MkkHou 评论0 收藏0

发表评论

0条评论

mikasa

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<