美文网首页代码审计
php代码基础入门

php代码基础入门

作者: book4yi | 来源:发表于2020-10-22 03:20 被阅读0次

    前言:


    后面一段时间打算学习代码审计,我之前玩ctf的时候,也会遇到一些代码审计的题目,所以对php代码略略了解一些,本文对php作一个小小的归纳小结。

    基础学习:


    PHP 是一门弱类型语言:PHP 会根据变量的值,自动把变量转换为正确的数据类型。

    在所有函数外部定义的变量,拥有全局作用域。要在一个函数中访问一个全局变量,需要使用 global 关键字。

    Static 作用域:
    当一个函数完成时,它的所有变量通常都会被删除。如果希望某个局部变量不要被删除,在第一次声明变量时使用 static 关键字

    类型比较:
    松散比较:使用两个等号 == 比较,只比较值,不比较类型
    严格比较:使用三个等号 === 比较,除了比较值,也比较类型

    常量:
    该值在脚本中不能改变,在整个脚本中都可以使用,常量名不需要加 $ 修饰符
    常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用。
    函数语法格式:
    define ( string $name , mixed $value [, bool $case_insensitive = false ] )

    name:必选参数,常量名称,即标志符。
    value:必选参数,常量的值。
    case_insensitive :可选参数,如果设置为 TRUE,该常量则大小写不敏感。默认是大小写敏感的。

    三元运算符:
    语法格式:
    (expr1) ? (expr2) : (expr3)
    对 expr1 求值为 TRUE 时的值为 expr2,在 expr1 求值为 FALSE 时的值为 expr3。
    注意:自 PHP 5.3 起,可以省略三元运算符中间那部分。表达式 expr1 ?: expr3 在 expr1 求值为 TRUE 时返回 expr1,否则返回 expr3。

    组合比较符(PHP7+):
    不仅限于数值类数据的比较
    语法格式:
    $c = $a <=> $b;

    如果 $a > $b, 则 $c 的值为 1。
    如果 $a == $b, 则 $c 的值为 0。
    如果 $a < $b, 则 $c 的值为 -1。

    数组:
    在 PHP 中,array() 函数用于创建数组:
    在 PHP 中,有三种类型的数组:

    • 数值数组 - 带有数字 ID 键的数组
    • 关联数组 - 带有指定的键的数组,每个键关联一个值
    • 多维数组 - 包含一个或多个数组的数组
    • 数值数组:
    $cars=array("Volvo","BMW","Toyota");
    
    $cars[0]="Volvo";
    $cars[1]="BMW";
    $cars[2]="Toyota";
    

    获取数组长度:

    echo count($cars);  # 获取数组长度
    

    遍历数值数组:

    <?php
    $cars=array("Volvo","BMW","Toyota");
    $arrlength=count($cars);
     
    for($x=0;$x<$arrlength;$x++)
    {
        echo $cars[$x];
        echo "<br>";
    }
    ?>
    
    • 关联数组:

    使用分配给数组的指定的键的数组

    $age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
    # 或者
    $age['Peter']="35";
    $age['Ben']="37";
    $age['Joe']="43";
    

    遍历关联数组:

    <?php
    $age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
    foreach($age as $x=>$x_value)
    {
        echo "Key=" . $x . ", Value=" . $x_value;
        echo "<br>";
    }
    ?>
    

    超级全局变量:
    PHP 超级全局变量列表:

    $GLOBALS  
    $_SERVER
    $_REQUEST
    $_POST
    $_GET
    $_FILES
    $_ENV
    $_COOKIE
    $_SESSION
    
    • $GLOBALS

    包含了全部变量的全局组合数组。变量的名字就是数组的键

    • $_SERVER

    包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组
    所有 $_SERVER 变量中的重要元素:

    元素/代码 描述
    $_SERVER['PHP_SELF'] 当前执行脚本的文件名,与 document root 有关
    $_SERVER['GATEWAY_INTERFACE'] 服务器使用的 CGI 规范的版本;例如,"CGI/1.1"
    $_SERVER['REMOTE_ADDR'] 浏览当前页面的用户的 IP 地址
    $_SERVER['DOCUMENT_ROOT'] 当前运行脚本所在的文档根目录。在服务器配置文件中定义。
    $_SERVER['REMOTE_HOST'] 浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。
    $_SERVER['REMOTE_PORT'] 用户机器上连接到 Web 服务器所使用的端口号。
    $_SERVER['SERVER_ADDR'] 当前运行脚本所在的服务器的 IP 地址。
    $_SERVER['SERVER_NAME'] 当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定。(如: www.runoob.com)
    $_SERVER['SERVER_SOFTWARE'] 服务器标识字符串,在响应请求时的头信息中给出。 (如:Apache/2.2.24)
    $_SERVER['SERVER_PROTOCOL'] 请求页面时通信协议的名称和版本。例如,"HTTP/1.0"。
    $_SERVER['REQUEST_METHOD'] 访问页面使用的请求方法;例如,"GET", "HEAD","POST","PUT"。
    $_SERVER['REQUEST_TIME'] 请求开始时的时间戳。从 PHP 5.1.0 起可用。 (如:1377687496)
    $_SERVER['QUERY_STRING'] query string(查询字符串),如果有的话,通过它进行页面访问。
    $_SERVER['HTTP_ACCEPT'] 当前请求头中 Accept: 项的内容,如果存在的话。
    $_SERVER['HTTP_ACCEPT_CHARSET'] 当前请求头中 Accept-Charset: 项的内容,如果存在的话。例如:"iso-8859-1,*,utf-8"。
    $_SERVER['HTTP_HOST'] 当前请求头中 Host: 项的内容,如果存在的话。
    $_SERVER['HTTP_REFERER'] 引导用户代理到当前页的前一页的地址(如果存在)。由 user agent 设置决定。并不是所有的用户代理都会设置该项,有的还提供了修改 HTTP_REFERER 的功能。简言之,该值并不可信。)
    $_SERVER['HTTPS'] 如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。
    $_SERVER['SCRIPT_FILENAME'] 当前执行脚本的绝对路径。
    $_SERVER['SERVER_ADMIN'] 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。(如:someone@runoob.com)
    $_SERVER['SERVER_PORT'] Web 服务器使用的端口。默认值为 "80"。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。
    $_SERVER['SERVER_SIGNATURE'] 包含了服务器版本和虚拟主机名的字符串。
    $_SERVER['PATH_TRANSLATED'] 当前脚本所在文件系统(非文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。
    $_SERVER['SCRIPT_NAME'] 包含当前脚本的路径。这在页面需要指向自己时非常有用。FILE 常量包含当前脚本(例如包含文件)的完整路径和文件名。
    $_SERVER['SCRIPT_URI'] URI 用来指定要访问的页面。例如 "/index.html"。
    • $_REQUEST

    默认情况下包含了 $_GET$_POST$_COOKIE 的数组。

    魔术常量:

    • __LINE__:文件中的当前行号
    • __FILE__:文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名
    • __DIR__:文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录
    • __FUNCTION__:自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)
    • __CLASS__:自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)
    • __TRAIT__:自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 traits
    • __METHOD__:返回该方法被定义时的名字(区分大小写)
    • __NAMESPACE__:当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)

    命名空间:
    PHP 命名空间可以解决以下两类问题:

    1、用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
    2、为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

    命名空间通过关键字namespace 来声明。如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间

    类:
    类定义形如:

    <?php
    class phpClass {
      var $var1;
      var $var2 = "constant string";
      
      function myfunc ($arg1, $arg2) {
         [..]
      }
      [..]
    }
    ?>
    

    注解:

    类使用 class 关键字后加上类名定义。
    类名后的一对大括号({})内可以定义变量和方法。
    类的变量使用 var 来声明, 变量也可以初始化值。
    函数定义类似 PHP 函数的定义,但函数只能通过该类及其实例化的对象访问。

    实例:

    <?php
    class Site {
      /* 成员变量 */
      var $url;
      var $title;
      
      /* 成员函数 */
      function setUrl($par){
         $this->url = $par;
      }
      
      function getUrl(){
         echo $this->url . PHP_EOL;
      }
      
      function setTitle($par){
         $this->title = $par;
      }
      
      function getTitle(){
         echo $this->title . PHP_EOL;
      }
    }
    ?>
    

    变量 $this 代表自身的对象。
    PHP_EOL 为换行符。

    创建对象:

    $taobao = new Site;
    

    调用成员方法:

    // 调用成员函数,设置标题和URL
    $taobao->setTitle( "淘宝" );
    $taobao->setUrl( 'www.taobao.com' );
    
    // 调用成员函数,获取标题和URL
    $taobao->getTitle();
    $taobao->getUrl();
    

    构造函数:
    构造函数是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,在创建对象的语句中与new运算符一起使用。
    语法格式:

    void __construct ([ mixed $args [, $... ]] )
    

    添加构造函数之后的完整代码:

    <?php
    class Site {
      /* 成员变量 */
      var $url;
      var $title;
      
      function __construct( $par1, $par2 ) {
       $this->url = $par1;
       $this->title = $par2;
    }
      
      function getUrl(){
         echo $this->url . PHP_EOL;
      }
      
      function getTitle(){
         echo $this->title . PHP_EOL;
      }
    }
    $taobao = new Site('www.taobao.com', '淘宝');
    
    // 调用成员函数,获取标题和URL
    $taobao->getTitle();
    $taobao->getUrl();
    ?>
    

    析构函数:
    析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。
    一个实例:

    <?php
    class MyDestructableClass {
       function __construct() {
           print "构造函数\n";
           $this->name = "MyDestructableClass";
       }
    
       function __destruct() {
           print "销毁 " . $this->name . "\n";
       }
    }
    
    $obj = new MyDestructableClass();
    ?>
    

    输出结果如下:

    构造函数
    销毁 MyDestructableClass
    

    继承:
    PHP 使用关键字 extends 来继承一个类,PHP 不支持多继承
    实例中 Child_Site 类继承了 Site 类,并扩展了功能:

    <?php 
    // 子类扩展站点类别
    class Child_Site extends Site {
       var $category;
    
        function setCate($par){
            $this->category = $par;
        }
      
        function getCate(){
            echo $this->category . PHP_EOL;
        }
    }
    

    方法重写:
    如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写

    function getUrl() {
       echo $this->url . PHP_EOL;
       return $this->url;
    }
       
    function getTitle(){
       echo $this->title . PHP_EOL;
       return $this->title;
    }
    

    访问控制:
    PHP 对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的。

    • public(公有):公有的类成员可以在任何地方被访问。
    • protected(受保护):受保护的类成员则可以被其自身以及其子类和父类访问。
    • private(私有):私有的类成员则只能被其定义所在的类访问。
    • 属性的访问控制:

    类属性必须定义为公有,受保护,私有之一。如果用 var 定义,则被视为公有。

    • 方法的访问控制:

    类中的方法可以被定义为公有,私有或受保护。如果没有设置这些关键字,则该方法默认为公有。

    接口:
    1、使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。
    2、接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的
    3、接口中定义的所有方法都必须是公有,这是接口的特性。
    4、要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。

    一个实例:

    <?php
    
    // 声明一个'iTemplate'接口
    interface iTemplate
    {
        public function setVariable($name, $var);
        public function getHtml($template);
    }
    
    
    // 实现接口
    class Template implements iTemplate
    {
        private $vars = array();
      
        public function setVariable($name, $var)
        {
            $this->vars[$name] = $var;
        }
      
        public function getHtml($template)
        {
            foreach($this->vars as $name => $value) {
                $template = str_replace('{' . $name . '}', $value, $template);
            }
     
            return $template;
        }
    }
    

    抽象类:
    1、任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
    2、定义为抽象的类不能被实例化。
    3、被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
    4、继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。
    5、此外,子类方法可以包含父类抽象方法中不存在的可选参数。

    Static 关键字:
    1、声明类属性或方法为 static(静态),就可以不实例化类而直接访问。
    2、静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。
    3、由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。
    4、静态属性不可以由对象通过 -> 操作符来访问。
    5、自 PHP 5.3.0 起,可以用一个变量来动态调用类。但该变量的值不能为关键字 self,parent 或 static。

    Final 关键字:
    PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。

    调用父类构造方法:
    PHP 不会在子类的构造方法中自动的调用父类的构造方法。要执行父类的构造方法,需要在子类的构造方法中调用 parent::__construct() 。

    参考如下:


    PHP 教程 | 菜鸟教程

    相关文章

      网友评论

        本文标题:php代码基础入门

        本文链接:https://www.haomeiwen.com/subject/nhzemktx.html