首页 > 编程语言 >PHP基础学习

PHP基础学习

时间:2022-11-24 19:45:38浏览次数:39  
标签:function content name age 基础 echo 学习 array PHP

PHP基础学习

在php中 , . 表示字符串连接符

    echo "1111111111" . "2222222222" . "333333333<br/>";
    print "1111111111" . "2222222222" . "333333333<br/>";

    echo "你好,你的余额为:" . 20000 . "元<br/>";

引号的问题:

  1. 双引号:里面可以包裹字符串和变量。

  2. 单引号:单引号只能表示字符串,不能引用变量。

  3. 反引号: 用于执行操作系统命令并返回结果

    $addr = "四川成都";
    echo "你当前所在城市为:$addr <br/>";
    echo '你当前所在城市为:$addr <br/>';
    echo `date /T`;  

代码理解部分

  $i = date("s");
    while ($i <= 30) {
        ob_flush();     // 清空缓冲区,直接输出
        flush();
        echo date("Y-m-d H:i:s") . "<br/>";
        $i = date("s");
        sleep(1);
    }

数组部分

php中数组的定义方式
$students = array("李源远","王佳乐","李园翔","刘俊","冉攀","邹松鹤","陈凯","王一清","胡涛","李云颢","张先发","王淼", "徐志豪","张霖","崇青平","范金辉","李浩民","王昀东","张亚飞","何思成","王亮","张良","翁通达","廖志凌");
取数组的长度
$len = count($students);
echo $len . "<br/>";
删除最后一个值
array_pop($students);
print_r($students);
echo '<p/>';
数组的遍历

用循环生成下标的方式

for ($i=0; $i<count($students); $i++) {
     echo $students[$i] . "<br/>";
 }

foreach遍历

foreach ($students as $stu) {
    echo $stu . "<br/>";
}

注意:这两种遍历方式,输出的结果一致!

数组去重
$grade = array(87, 95, 38, 59, 67, 49, 99, 82, 59, 99, 67, 73);
$new = array_unique($grade);
print_r($new);
echo '<p/>';
数组排序
$grade = array(87, 95, 38, 59, 67, 49, 99, 82, 59, 98, 67, 73);
rsort($grade);
foreach ($grade as $g) {
    echo $g . "<br/>";
}

关联数组:以key=>value组成的键值对,取值的时候用key来取值,而不是下标 索引数组的key就是0、1、2、3这种数字

$student01 = array('name'=>'张三', 'age'=>30, 'addr'=>'成都高新区', 'phone'=>'18812345678');
$student02 = array('name'=>'李中', 'age'=>30, 'addr'=>'成都高新区', 'phone'=>'18912345676');
$student03 = array('name'=>'王九', 'age'=>25, 'addr'=>'成都高新区', 'phone'=>'19812345678');
$student04 = array('name'=>'赵六', 'age'=>30, 'addr'=>'成都高新区', 'phone'=>'18112345679');
$student05 = array('name'=>'周七', 'age'=>27, 'addr'=>'成都高新区', 'phone'=>'18812345978');

print_r($student01);
echo "<br/>";

echo $student01['name']. "<br/>";
$student01['addr'] = '成都天府新区';
补充4个重要的数组相关函数

直接取最后一个值,无所谓是哪种数组

echo end($student05) . "<br/>";     
if (in_array('周八', $student05)) {
    echo "在<br/>";
}

把字符串打散为数组。

$source = "Typora.exe#9284#Console#1#92680K";
$myarray = explode("#", $source);
print_r($myarray);
echo '<br/>';

把数组合并成字符串

$grade = array(87, 95, 38, 59, 67, 49, 99, 82, 59, 98, 67, 73);
$result = implode(",", $grade);
echo $result . "<br/>";
$student01 = array('name'=>'张三', 'age'=>30, 'addr'=>'成都高新区', 'phone'=>'18812345678');
$student02 = array('name'=>'李四', 'age'=>30, 'addr'=>'成都高新区', 'phone'=>'18912345676');
$student03 = array('name'=>'王九', 'age'=>25, 'addr'=>'成都高新区', 'phone'=>'19812345678');
$student04 = array('name'=>'赵六', 'age'=>30, 'addr'=>'成都高新区', 'phone'=>'18112345679');
$student05 = array('name'=>'周七', 'age'=>27, 'addr'=>'成都高新区', 'phone'=>'18812345978');

二维数组

$class01 = array($student01, $student02, $student03, $student04, $student05);
echo $class01[1]['name'];   // 李四

设置使用中国北京时间作为系统时区

date_default_timezone_set("PRC");

后端与数据库端连接

 定义一个方法,用于建立与数据库的连接
    private function create_connection() {
         $conn = mysqli_connect($this->host, $this->username, $this->password, $this->database) 
                 or die("数据库连接不成功.");
         mysqli_query($conn, "set names utf8");
         return $conn;
     }
设置编码格式的两种方式
mysqli_query($conn, "set names utf8");  
mysqli_set_charset($conn, 'utf8')
拼接SQL语句并执行它
$sql = "select * from user where username='$username' and password='$password'";
$result = mysqli_query($conn, $sql);    // $result获取到的查询结果,称结果集

函数

function calc($a, $b) {
    $result = $a + $b;
    echo "运算结果为:$result <br/>";
    return $result;
}
function checkPhone_01($phone) {

    $len = strlen($phone);
    if ($len != 11) {
        echo "长度必须为11位.<br/>";
        return false;   // 代码运行到此,就会返回到调用的地方,不再往下运行
    }

    if ($phone[0] != 1) {
        echo "第1位必须为1.<br/>";
        return false;
    }

    if ($phone[1] < "3" || $phone[1] > "9") {
        echo "第2位必须为3-9.<br/>";
        return false;
    }

    for ($i=2; $i<11; $i++) {
        if ($phone[$i] < "0" || $phone[$i] > "9") {
            echo "后9位必须是数字.<br/>";
            return false;
        }
    }
    
    return true;    // 如果前面的代码块均没有return,则认为电话号码是有效的
}

使用正则表达式判断手机号码

function checkPhone($phone) {
    $result = preg_match("/^1[3-9]\d{9}$/", $phone);
    return $result;
}

获取请求数据的方式:

// 前端用GET请求发,后台用$_GET函数取,前端用POST请求发,后台用$_POST函数取

// $username = $_GET['username'];
// $password = $_GET['password'];
// $vcode = $_GET['vcode'];

$username = $_POST['username'];
$password = $_POST['password'];
$vcode = $_POST['vcode'];

Session部分

Session的声明与使用

  Session的设置不同于Cookie,必须先启动,在PHP中必须调用session_start()。session_start()函数的语法格式如下:

  Bool session_start(void) //创建Session,开始一个会话,进行Session初始化

  注意:session_start()函数之前不能有任何输出

代码理解部分
session_start();

if ($_SESSION['islogin'] != 'true' || $_SESSION['role'] != 'editor') {
    die("你无权新增文章");
}
session_start();

    if ($_SESSION['islogin'] != 'true') {
         die ("请先登录.");

当第一次访问网站时,Seesion_start()函数就会创建一个唯一的Session ID,并自动通过HTTP的响应头,将这个Session ID保存到客户端Cookie中。同时,也在服务器端创建一个以Session ID命名的文件,用于保存这个用户的会话信息。当同一个用户再次访问这个网站时,也会自动通过HTTP的请求头将Cookie中保存的Seesion ID再携带过来,这时Session_start()函数就不会再去分配一个新的Session ID,而是在服务器的硬盘中去寻找和这个Session ID同名的Session文件,将这之前为这个用户保存的会话信息读出,在当前脚本中应用,达到跟踪这个用户的目的。 Session以数组的形式使用,如:$_SESSION['session名']

代码理解部分
<?php
//启动session的初始化
session_start();
//注册session变量,赋值为一个用户的名称
$_SESSION["username"]="skygao";
//注册session变量,赋值为一个用户的ID
$_SESSION["uid"]=1;
?>

执行该脚本后,两个Session变量就会被保存在服务器端的某个文件中,该文件的位置是通过php.ini文件,在session.save_path属性指定的目录下。

代码理解部分
<?php
//第一步:开启Session并初始化
session_start();
 
//第二部:删除所有Session的变量,也可以用unset($_SESSION[XXX])逐个删除
$_SESSION = array();
 
//第三部:如果使用基于Cookie的session,使用setCookkie()删除包含Session ID的cookie
if(isset($_COOKIE[session_name()])) {
    setCookie(session_name(), "", time()-42000, "/");
}
 
//第四部:最后彻底销毁session
session_destroy();
 
?>
session.cookie_path = / ; cookie的有效路径
session.cookie_domain = ; cookie的有效域
session.name = PHPSESSID; 用在cookie里的session的名字
session.save_handler = files ; 用于保存/取回数据的控制方式
session.save_path = /tmp ; 在 save_handler 设为文件时传给控制器的参数, 这是数据文件将保存的路径.
session.use_cookies = 1 ; 是否使用cookies
<?php
//开启session
session_start();
 
//在每个URL后面附加上参数,变量名为session_name()获取名称,值通过session_id()获取
echo '<a href="demo.php?'.session_name().'='.session_id().'">连接演示</a>';
?>
在使用Linux系统做服务器时,则在编辑PHP时如果使用了–enable-trans-sid配置选项,和运行时选项session.use_trans_sid都被激活,在客户端禁用Cookie时,相对URL将被自动修改为包含会话ID。如果没有这么配置,或者使用Windows系统作为服务器时,可以使用常量SID。该常量在会话启动时被定义,如果客户端没有发送适当的会话Cookie,则SID的格式为session_name=session_id,否则就为一个空字符串。因此可以无条件地将其嵌入到URL中去。在下例中使用两个脚本程序,演示了Session ID的传送方法。
<?php
session_start();
 
$_SESSION["username"]="admin";
 
echo "session ID:".session_id()."<br>";
 
?>

文件读写操作

代码理解部分
<?php
 
// 创建文件
$touch = ('./a.php');
var_dump($touch);
 
// 移动文件 重命名
$touch = rename('./a.php','./b.txt');
var_dump($touch);
 
//删除文件
$touch = unlink('./a.php');
 
 
// 获取文件大小
$filesize = filesize('./fa.jpg');
var_dump($filesize);
 
//判断是否是文件 判断文件为true 判断目录为false
$is_file = is_file('./test.php');
var_dump($is_file);
$is_file = is_file('./PHP');
var_dump($is_file);
 
// 判断文件是否存在,存在则删除
if(file_exists('./b.txt')){
    echo "文件存在";
    unlink('./b.txt');
    echo "文件已删除";
}
else{
    echo '文件不存在';
}
 
// 文件是否可执行
$is_executable = is_executable('./../xray_windows_amd64.exe');
var_dump($is_executable);
 
// 文件是否可写可读
$is_write = is_writeable('./test.php');
$is_read = is_readable('./test.php');
var_dump($is_write);
var_dump($is_read);
 
// 获取文件的创建时间
$time = filectime('./test.php');
var_dump(date('Y-m-d H:i:s',$time));
 
// 获取文件的修改时间
$time = filemtime('./test.php');
var_dump(date('Y-m-d H:i:s',$time));
 
// 获取文件上次访问时间
$time = fileatime('./ ');
var_dump(date('Y-m-d H:i:s',$time));
 
// 打开文件 读取文件 关闭文件 写入文件
$content = ''; // 声明一个空字符串
$file_open = fopen('./test.php','r'); // 只读文件
$file_write = fopen('./test.txt','w'); // w 是写入文件,如果文件不存在则会创建,如果文件有内容则会清空后再次写入
fwrite($file_write,'<?php phpinfo(); ?>');
fclose($file_write);
while(!feof($file_open)){ // feof 判断指针是否到文件末尾
    //$content .= fread($file_open,1); // 一个字节一个字节读
    $content = fgets($file_open); // 读取一行的内容
}
echo $content;
fclose($file_open);
 
// 读取文件 :打开、读取、关闭一步到位
$res = file_get_contents('./test.php');
echo $res;
 
// 写入文件
$file_write = file_put_contents('./test.txt','<?php phpinfo(); ?>'); // 以w方式写入文件
$file_write = file_put_contents('./test.txt','<?php phpinfo(); ?>',FILE_APPEND); // 在文本后追加语句
var_dump($file_write);
 
文件读写的步骤

1、打开文件:fopen

2、读写文件:fgets,fwrite

3、关闭文件:fclose

附加函数:
  • 1、判断文件是否已经到达末尾:feof($fp)
  • 2、一次性将文件所有内容读出:file_get_contents($filename)
  • 3、使用file_get_contents还可以发送GET请求
  • 4、使用file_put_contents一次性写入文件
  • 5、获取当前文件指针所在位置:ftell
  • 6、直接将文件指针指向某个位置:fseek
最基本的按行循环读取整份文件
$fp = fopen("E:/userpass.csv", "r");
 while (!feof($fp)) {
     $line = fgets($fp);
     $line = str_replace("\n", "<br/>", $line);
     echo $line;
 }
 fclose($fp);
往文件中写入内容
$fp = fopen("E:/userpass.csv", "a");
fwrite($fp, "\ntest,test123,login-fail");
 fclose($fp);
使用file_get_contents直接读取文件内容
使用file_get_contents直接读取文件内容
 header("content-type:text/html; charset='gbk'");
 $content = file_get_contents("E:/Test.txt");
 $content = iconv("GBK", "UTF-8", $content);
 $content = str_replace("\n", "<br/>", $content);
 echo $content;
 $list = explode("\n", $content);
 print_r($list);
使用file_get_contents发送GET请求访问网页
content = file_get_contents("http://www.woniunote.com/");
echo $content;
//是否可以用于下载一个文件、一张图片呢? 小任务,完成它,进而思考网页爬虫的设计思路。
 $content = file_get_contents("http://www.woniunote.com/img/banner-1.jpg");
 file_put_contents("E:\\test.jpg", $content);
使用file_put_contents一次性写入文件

拓展部分:

/*
 * UTF-8处理中文时使用的是3字节,而GBK处理中文时是2个字节
 * 11001011 01011011 01011110 10100101 01011110 10100101
 */
content = iconv("UTF-8", "GBK", "\nHello蜗牛哦");
// file_put_contents("E:\\Test.txt", $content, FILE_APPEND);
读取一个CSV文件(逗号分隔符),并且解析为二维数组
$content = file_get_contents("E:/userpass.csv");
$rows = explode("\n", $content);
代码理解部分
 $list = array();
 for ($i=1; $i<count($rows); $i++) {
     $temp = explode(",", $rows[$i]);
     array_push($list, $temp);
 }
 print_r($list);
使用PHP模拟tail -f实时查看文件内容
$fp = fopen("E:\\userpass.csv", "r");
 fseek($fp, 32);
 while ($line = fgets($fp)) {
    echo $line . "<br/>";
 }
 fclose($fp);

 @error_reporting(0);
 set_time_limit(0);

$pos = 0;
 while (true) {
     $fp = fopen("./test.txt", "r");
    fseek($fp, $pos);
   while ($line = fgets($fp)) {
        $line = iconv("GBK", "UTF-8", $line);
         echo $line . "<br/>"; 
    }
    $pos = ftell($fp);
     fclose($fp);

     ob_flush();
     flush();
     sleep(2);
}

PHP操作JSON数据

代码理解部分
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSON</title>
    <script>
        function json() {
            // var users = ["张三",  "李四",  "王五",  "赵六",  "田七"];
            // for (var i=0; i<users.length; i++) {
            //     document.write(users[i] + "<br/>");
            // }
            
            // var user1 = {"name":"张三", sex:"男", age:30, phone:"18012345678", addr:"成都"}; 
            // document.write(user1.name);

            // var user1 = {"name":"张三", sex:"男", age:30, phone:"18012345678", addr:"成都"}; 
            // var user2 =  {name:"李四",  sex:"女",  age:25, phone:"13012365659",addr:"重庆"}; 
            // var users = [user1, user2];

            // var users = [{"name":"张三", sex:"男", age:30, phone:"18012345678", addr:"成都"},
            //             {name:"李四",  sex:"女",  age:25, phone:"13012365659",addr:"重庆"}];
            // document.write(users[1]['name']);

            var users =  {user1:["张三","男",30,"18012345678","成都", {province:'四川'}],
			              user2:["李四","女",25,"13012365659","重庆", {province:'重庆'}]};
            // document.write(users.user2[3]);
            document.write(users.user1[5].province);
            
        }
    </script>
</head>
<body>
    <?php
        // 引用common.php,如果之前已经引用则不再引用
        // require_once('common.php');
        // include_once('common.php');
        // $conn = create_connection();
        // $sql = "select articleid, viewcount, createtime from article where articleid < 10";
        // $result = mysqli_query($conn, $sql);
        // $data = mysqli_fetch_all($result, MYSQLI_ASSOC);

        // echo json_encode($data);

        $student01 = array('name'=>'张三', 'age'=>30, 'addr'=>'成都高新区', 'phone'=>'18812345678');
        $student02 = array('name'=>'李中', 'age'=>30, 'addr'=>'成都高新区', 'phone'=>'18912345676');
        $student03 = array('name'=>'王九', 'age'=>25, 'addr'=>'成都高新区', 'phone'=>'19812345678');
        $student04 = array('name'=>'赵六', 'age'=>30, 'addr'=>'成都高新区', 'phone'=>'18112345679');
        $student05 = array('name'=>'周七', 'age'=>27, 'addr'=>'成都高新区', 'phone'=>'18812345978');
        $class01 = array($student01, $student02, $student03, $student04, $student05);

        print_r($class01);
        echo json_encode($class01);     // JSON序列化:将对象转换成字符串

        // JSON反序列化:把一个字符串再转换成对象
        $string = '[{"name":"\u5f20\u4e09","age":30,"addr":"\u6210\u90fd\u9ad8\u65b0\u533a","phone":"18812345678"},{"name":"\u674e\u4e2d","age":30,"addr":"\u6210\u90fd\u9ad8\u65b0\u533a","phone":"18912345676"},{"name":"\u738b\u4e5d","age":25,"addr":"\u6210\u90fd\u9ad8\u65b0\u533a","phone":"19812345678"},{"name":"\u8d75\u516d","age":30,"addr":"\u6210\u90fd\u9ad8\u65b0\u533a","phone":"18112345679"},{"name":"\u5468\u4e03","age":27,"addr":"\u6210\u90fd\u9ad8\u65b0\u533a","phone":"18812345978"}]';
        $array = json_decode($string);
        print_r($array);
    ?>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="jquery-3.4.1.min.js"></script>
    <title>通过JS动态渲染JSON数据</title>
    <style>
        table {
            width: 800px;
            margin: auto;
            border: solid 1px green;
            border-spacing: 0px;
        }
        td {
            border: solid 1px gray;
            height: 30px;
        }
    </style>
    <script>
        // window.onload = function() {
        function list() {
            $.get('list-json.php', function(data){
                // 后台响应给前端的JSON数据,其content-type有可能是:
                // 1、text/plain或text/html,此时必须用eval执行将其转成JS对象
                // 2、application/json,则不需要eval,直接使用即可
                var data = eval(data); 
                var content = "";
                // data.forEach(function(article) {
                data.forEach(article => {
                    content += "<tr>";
                    content += "<td>" + article['articleid'] + "</td>";
                    content += "<td>" + article['author'] + "</td>";
                    content += "<td>" + article['headline'] + "</td>";
                    content += "<td>" + article['viewcount'] + "</td>";
                    content += "<td>" + article['createtime'] + "</td>";
                    content += "<td><button>删除</button></td>";
                    content += "</tr>";
                });
                $("#articleTable").append(content);
                $("#articleTable").css('display', '');
            });
        }
    </script>
</head>
<body>
    <button onclick="list()">加载</button>

    <table id="articleTable" style="display: none;">
        <tr>
            <td>编号</td>
            <td>作者</td>
            <td>标题</td>
            <td>次数</td>
            <td>时间</td>
            <td>操作</td>
        </tr>
    </table>
</body>
</html>
<?php

    include_once('common.php');
    $conn = create_connection();
    $sql = "select articleid, author, headline, viewcount, createtime from article where articleid < 20";
    $result = mysqli_query($conn, $sql);
    $data = mysqli_fetch_all($result, MYSQLI_ASSOC);

    echo json_encode($data);

?>

PHP读取XML数据

XML代码
<?xml version="1.0" encoding="utf8"?>
<class id="WNCDC085">
  <student sequence="1">
    <id>WNCD201703015</id>
    <name>敬小越</name>
    <sex>男</sex>
    <age>24</age>
    <degree>本科</degree>
    <school>电子科技大学成都学院</school>
  </student>
  <student sequence="2">
    <id>WNCD201703020</id>
    <name>何小学</name>
    <sex>男</sex>
    <age>29</age>
    <degree>本科</degree>
    <school>成都理工大学</school>
  </student>
  <student sequence="3">
    <id>WNCD201703025</id>
    <name>杨小言</name>
    <sex>女</sex>
    <age>22</age>
    <degree>大专</degree>
    <school>四川华新现代职业学院</school>
  </student>
</class>
读取class节点的属性id和对应的值
$nodes = $doc->getElementsByTagName('class');
    echo $nodes->item(0)->nodeName;
     echo $nodes->item(0)->attributes->item(0)->nodeName;
   echo $nodes->item(0)->attributes->item(0)->nodeValue;
读取第二个学生的所有信息
$nodes = $doc->getElementsByTagName('student');
     $childNodes = $nodes->item(1)->childNodes;
  foreach ($childNodes as $node) {
         echo $node->nodeValue . "<br/>";
  }
读取所有学生的姓名
$nodes = $doc->getElementsByTagName("name");
foreach ($nodes as $node) {
    echo $node->nodeValue . "<br/>";
 }
将XML文件读取为PHP的二维数组
 $nodes = $doc->getElementsByTagName("student");
$students = array();
  foreach ($nodes as $k=>$v) {
      $students[$k]['id'] = $v->getElementsByTagName('id')->item(0)->nodeValue;
        $students[$k]['name'] = $v->getElementsByTagName('name')->item(0)->nodeValue;
       $students[$k]['sex'] = $v->getElementsByTagName('sex')->item(0)->nodeValue;
         $students[$k]['age'] = $v->getElementsByTagName('age')->item(0)->nodeValue;
        $students[$k]['degree'] = $v->getElementsByTagName('degree')->item(0)->nodeValue;
      $students[$k]['school'] = $v->getElementsByTagName('school')->item(0)->nodeValue;
   }
    print_r($students);

    //适当优化,简化代码

    $nodes = $doc->getElementsByTagName("student");
   $students = array();
    $tag = array('id', 'name', 'sex', 'age', 'degree', 'school');
   foreach ($nodes as $k=>$v) {
       foreach ($tag as $t) {
             $students[$k][$t] = $v->getElementsByTagName($t)->item(0)->nodeValue;
         }
   }
     print_r($students);
读取firewall.xml的所有端口信息
 $doc->load('../demo/firewall.xml');
     $nodes = $doc->getElementsByTagName('port');
    foreach ($nodes as $node) {
       $attr = $node->attributes;
       echo $attr->item(1)->nodeValue . "<br/>";
   }

XML更新与XPATH

修改节点的属性或值
$doc = new DOMDocument();
     $doc->preserveWhiteSpace = false;   // 不保留空白节点
     $doc->formatOutput = true;          // 格式化输出
     $doc->load('./student.xml');
    $nodes = $doc->getElementsByTagName('student');
修改节点的属性值
$nodes->item(2)->attributes->item(0)->nodeValue = '5';
    修改节点的值
    $nodes->item(2)->childNodes->item(1)->nodeValue = '杨大言';
    foreach($nodes->item(2)->childNodes as $node) {
        echo $node->nodeValue . "<br/>";
     }
删除节点操作
// 删除一个节点:先找到父节点,再找到子节点,调用父节点的removeChild方法删除
    $parent = $nodes->item(2);
     $child = $parent->childNodes->item(4);
    $parent->removeChild($child);

    // // 直接找到要删除的节点自身,再向上一层找到父节点,再调用removeChild进行删除
    $child = $doc->getElementsByTagName('degree')->item(2);
     $child->parentNode->removeChild($child);
    //
    $doc->save('./student.xml');
将数组写入XML
 // 先定义数组,也可以直接从数据库读取
    $student01=array("id"=>"WNCD201703015", "name"=>"敬小越", "sex"=>"男", "age"=>"24", "degree"=>"本科", "school"=>"电子科技大学成都学院");
     $student02=array("id"=>"WNCD201703020", "name"=>"何小学", "sex"=>"男", "age"=>"29", "degree"=>"本科", "school"=>"成都理工大学");
     $student03=array("id"=>"WNCD201703025", "name"=>"杨小言", "sex"=>"女", "age"=>"22", "degree"=>"大专", "school"=>"四川华新现代职业学院");
     $students = array($student01, $student02, $student03);

     $doc = new DOMDocument('1.0', 'utf8');
     $doc->preserveWhiteSpace = false;
     $doc->formatOutput = true;
    
     // 创建根节点 class 并设置 id 属性
     $class = $doc->createElement('class');
     $class->setAttribute('id', 'WNCDC085');
     $doc->appendChild($class);

     foreach ($students as $index => $student) {
         // 为class节点添加student子节点
         $nodeStudent = $doc->createElement('student');
        $nodeStudent->setAttribute('sequence', $index+1);
         $class->appendChild($nodeStudent);
         // 为student节点添加id, name, sex等子节点
        foreach ($student as $key => $value) {
            $node = $doc->createElement($key);
            $nodeStudent->appendChild($node);
             // 为各子节点赋值
            $nodeValue = $doc->createTextNode($value);
             $node->appendChild($nodeValue);
       }
     }

     $doc->save('./write.xml');
XPATH定位元素
 $doc = new DOMDocument();
    $doc->preserveWhiteSpace = false;
    $doc->load('./student.xml');
    $xpath = new DOMXPath($doc);    // 实例化XPATH对象
    // $expression = "/class/student[@sequence='1']/school";
    // $expression = "/class/student[@sequence='2']/school";
    // $expression = "//student[@sequence='3']/name";
    // $expression = "//student[2]/name";      // 找第2个学生的姓名
    $expression = "//student/school[contains(text(), '科技')]";
    $nodes = $xpath->query($expression);    // 返回的是找到的所有节点
    echo $nodes->item(0)->nodeValue;

网页爬虫原理与实现

理论部分:

(1)XML与HTML本质上是相同的结构:DOMDocument可以处理XML,原则上来说也可以处理HTML

(2)爬虫主要是爬取网页的内容(基于HTTP和HTML的内容),可以爬取一个网站上的图片,文件,页面内容等。

(3)搜索引擎的工作原理;爬取网页内容,对内容进行分词,分词后建议索引(倒排索引),进行排序后提高服务。

(4)爬取的基本过程;给定一个网址,然后解析响应的HTML页面内容,并下载保存(HTML文件),然后解析其中的超链接或其他资源(比如 图片等),超链接就进行继续的访问和存储,图片就进行下载存档,基于新找到的超链接,又继续解析更多的超链接。

(5)技术层面的实现要点:

1.发送GET请求并获取响应的内容:file_get_contents

2.解析页面中的URL地址或资源地址:DOMDocument

3.继续访问解析出来的地址或资源:根据地址的特点分类和拼接,构建一个完成的URL地址库,继续访问,继续前两步。(广度优先 , 深度优先)

代码理解部分:

DOMDocumen

$content = file_get_contents("http://www.woniunote.com/");
 $html = new DOMDocument();
 $html->preserveWhiteSpace = false;
 @$html->loadHTML($content);

 $links = $html->getElementsByTagName('a');

 $linkList = array();

 foreach ($links as $link) {
    // echo $link->nodeValue . "<br/>";
   // echo $link->attributes->item(0)->nodeValue . "<br/>";
     foreach ($link->attributes as $attr) {
        if ($attr->nodeName == "href") {
            // echo $attr->nodeValue . "<br/>";
            // 利用 / 、 #、 http 三个特征来判断URL地址类型,并完成完整的地址拼接
             if (strpos($attr->nodeValue, '/') == 0) {
                 array_push($linkList, 'http://www.woniunote.com' . $attr->nodeValue);
             }
             else if (strpos($attr->nodeValue, 'http://') == 0) {
                 array_push($linkList, $attr->nodeValue);
             }
        }
     }
 }

 set_time_limit(0);

 foreach ($linkList as $link) {
     $filename = str_replace("http://www.woniunote.com/", "", $link);
     $filename = str_replace("/", "-", $filename);
     $content = file_get_contents($link);
     file_put_contents("./download/html/$filename.html", $content);
    echo "成功下载:$filename <br/>"; 
   ob_flush();
     flush();
    sleep(0.5);
 }

使用Simple HTML Dom库

// 使用Simple HTML Dom库
include_once "simple_html_dom.php";
$html = file_get_html('http://www.woniunote.com/');

// 查找所有的超链接
$links = $html->find('a');
foreach ($links as $link) {
    echo $link->href . "<br/>";
}

// 查找所有图片地址
$images = $html->find('img');
foreach ($images as $image) {
    $src = $image->src;
    if (strpos($src, '/') == 0) {
        $url = 'http://www.woniunote.com' . $src;
    }
    else if (strpos($src, 'http') == 0) {
        $url = $src;
    }
    $filename = end(explode("/", $url));
    $content = file_get_contents($url);
    file_put_contents("./download/image/$filename", $content);

    echo "图片 $filename 下载完成. <br/>";
    ob_flush();
    flush();
    sleep(0.5);
}

// 使用其他的定位方式

// 使用类似于Xpath的方式来定位元素
$titles = $html->find("div[@class='title']");
$titles = $html->find("div[class='title']");
$titles = $html->find("div.title");
foreach ($titles as $title) {
    // echo $title->innertext . "<br/>";
    echo $title->plaintext . "<br/>";
    // echo $title->outertext . "<br/>";
}

// 使用ID属性定位元素
$nodes = $html->find("input[@id='keyword']");
$nodes = $html->find("input#keyword");
$nodes = $html->find("#keyword");
foreach ($nodes as $node) {
    echo $node->placeholder;
}

// 直接给定元素下标找对应某一个元素
$html = file_get_html('http://www.woniunote.com/article/609');
$node = $html->find("#content", 0);
echo $node->plaintext;

// 元素之间的层次关系
$titles = $html->find("div.title");
foreach ($titles as $title) {
    echo $title->first_child()->innertext . "<br/>";
}

// 用完整个页面的DOM结构后,清空内存
$html->clear(); 

使用正则表达式

// 使用正则表达式如何解析页面元素
// 正则表达式是将一份HTML源码理解为一个长长的字符串,进而使用正则表达式进行字符串解析和匹配
// 设定左右边界来查找超链接或者其他元素
$content = file_get_contents('http://www.woniunote.com/');
// $pattern = '/<a href="(.*)"/';      // 贪婪模式 :匹配到最后一个
$pattern = '/<a href="(.+?)"/';        // 非贪婪模式 ;匹配到最靠前的一个
preg_match_all($pattern, $content, $result);
print_r($result[1]);

?>

面向对象基础

$name = '张三';

function test() {
    // PHP中默认的变量是有作用域的,如果要在函数内部使用函数外的变量,则必须声明为全局变量
    global $name;
    echo "你好 $name";  
 }

test();
面向对象编程基础用法
// 定义类:People,单纯定义一个类,本身并不会真正解决问题
class People {
    var $name = '';     // 不再称为变量,而是叫类属性
    var $age = 0;
    var $addr = '';
    var $nation = '';

    // 定义People类所具备的方法,默认情况下,方法的定义与函数完全一致
    function talk() {
        // 在类的定义中, $this 指类的具体实例
        echo "$this->name 正在说话. <br/>";
    }

    function work() {
        echo "$this->name 正在工作. <br/>";
    }
}

// 实例化类People并进行属性和方法的调用
$p1 = new People();
$p1->name = "张三";
$p1->age = 30;
$p1->addr = "成都高新区";
$p1->nation = "汉族";

echo $p1->name . "<br/>";
$p1->talk();

// 一旦完成类的实例化,实例与实例之间并无关系,分布于不同的内存中
$p2 = new People();
$p2->name = "李四";
$p2->age = 25;
$p2->addr = "成都金牛区";
$p2->nation = "藏族";

echo $p2->addr . "<br/>";
$p2->work();

?>
利用面向对象的特性改造数据库操作
// class DB {
//     // 为DB类定义数据库连接的必要属性
//     var $host = '127.0.0.1';
//     var $username = 'root';
//     var $password = '123456';
//     var $database = 'learn';

//     // 定义一个方法,用于建立与数据库的连接
//     private function create_connection() {
//         $conn = mysqli_connect($this->host, $this->username, $this->password, $this->database) 
//                 or die("数据库连接不成功.");
//         mysqli_query($conn, "set names utf8");
//         return $conn;
//     }

//     // 封装两个操作方法,一个用于查询,一个用于更新
//     function query($sql) {
//         $conn = $this->create_connection();
//         $result = mysqli_query($conn, $sql);
//         $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
//         return $rows;
//     }

//     function modify($sql) {
//         $conn = $this->create_connection();
//         $result = mysqli_query($conn, $sql);
//         if (! $result) {
//             die("数据库更新操作不成功.");
//         }
//     }

//     // 类的析构方法:当类的实例使用完并从内存中释放时,将会触发调用该方法
//     function __destruct() {
//         $conn = $this->create_connection();
//         mysqli_close($conn);
//     }
// }




class DB {
    // 为DB类定义数据库连接的必要属性
    // private $host = '127.0.0.1';
    // private $username = 'root';
    // private $password = '123456';
    // private $database = 'learn';

    var $host = '127.0.0.1';
    var $username = 'root';
    var $password = '123456';
    var $database = 'learn';

    // 将数据库连接对象定义为类属性
    private $conn = null;

    // 定义一个方法,用于建立与数据库的连接
    private function create_connection() {
        $this->conn = mysqli_connect($this->host, $this->username, $this->password, $this->database) 
                or die("数据库连接不成功.");
        mysqli_query($this->conn, "set names utf8");
        return $this->conn;
    }

    // 封装两个操作方法,一个用于查询,一个用于更新
    function query($sql) {
        $result = mysqli_query($this->conn, $sql);
        $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
        return $rows;
    }

    function modify($sql) {
        $result = mysqli_query($this->conn, $sql);
        if (! $result) {
            die("数据库更新操作不成功.");
        }
    }

    // 类的构造方法:当类在进行实例化时会触发执行该方法
    function __construct($host='127.0.0.1', $username='root', $password='123456', $database='learn') {
        $this->host = $host;
        $this->username = $username;
        $this->password = $password;
        $this->database = $database;
        echo "调用构造方法,并建立数据库的连接 <br/>";
        $this->create_connection();     // 每一个实例化的过程,就会执行一次
    }

    // 类的析构方法:当类的实例使用完并从内存中释放时,将会触发调用该方法
    function __destruct() {
        echo "调用析构方法,并关闭数据库的连接 <br/>";
        mysqli_close($this->conn);
    }

    // 当类进行序列化时自动调用,并且返回一个数组,包含要实例化的类属性
    function __sleep() {
        echo "DB类正在进行序列化. <br/>";
        return array('host', 'username', 'password', 'database');
    }

    // 在类进行反序列时调用,并且可以在该方法中定义恢复类状态的代码,以便于让反序列化的实例可以正常调用方法。
    function __wakeup() {
        echo "DB类正在被反序列化. <br/>";
        $this->create_connection();     // 恢复数据库的连接状态
    }
}
封装,继承,多态

封装

/**
 * 封装:public, private, protected
 * 1. 默认情况下,所有属性和方法,在没有明确设置访问修饰符时,均为public
 * 2. private 表示类私有,在类的定义中可以使用,而在实例和子类中均无法使用
 * 3. protected 表示受类的保护,实例中不能直接使用,但是在子类中可以使用
 */
class People {
    private $name = '王五';     // 定义类时,可以给属性一个初始值,使用了访问修饰符后,不再需要var
    var $age = 0;
    var $addr = '';
    var $nation = '';

    // 定义People类所具备的方法,默认情况下,方法的定义与函数完全一致
    public function talk() {
        // 在类的定义中, $this 指类的具体实例
        echo "$this->name 正在说话. <br/>";
    }

    private function work() {
        echo "$this->name 正在工作. <br/>";
    }

    // 公有方法调用私有方法
    protected function eat($type='米饭') {
        echo "$this->name 正在吃 $type <br/>";
        $this->work();
    }

    // 针对私有属性,如何在实例中对其进行修改?设置一个公有方法,对类的私有属性进行修改或取值
    // 以下两个方法是封装这个特性最经典的演示:公有方法操作私有属性。
    public function setName($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

 $p = new People();
// $p->name = "张三";   // 实例无法使用类的私有属性
 //echo $p-> . "<br/>";
 $p->talk();
 $p->setName('张三');
 echo $p->getName() . "<br/>";
 //$p->eat();

继承

// /**
//  * 继承:子承父业、继承传统、发扬光大父类的属性和方法(非
//  * 定义类:Man,让其继承父类People,则Man这个类就称为子类,可以继承私有)
//  * 子类继承父类时,可以在子类调用protected修改的属性和方法,同时也可以覆盖或重写父类方法
//  * 子类也可以在自己类的扩展或创建新的方法和属性
//  * 关键字:final,如果一个类被final修饰,则该类不能被继承
//  */

class Man extends People {
    // Man这个类,什么都不做,People的所有非私有属性和方法均可以使用

    // 父类中有的方法,在子类中可以进行覆盖,也称为“重写”,override
    function work() {
        // $this->eat();
        parent::eat(); 
           // 更加正统的做法,在子类中使用parent::调用父类的方法
        echo "$this->name 正在工作 <br/>";
    }

    public function talk() {
        echo "$this->name 正在说话. <br/>";
    }

    // 父类中不存在的方法,子类新建的方法(扩展)
    public function drive() {
        echo "$this->name 正在开车. <br/>";
    }
}

 $m = new Man();
// // echo $m->name;      // 子类无法直接使用父类的私有属性
// // $m->work();            // 子类无法直接使用父类的私有方法
// // $m->talk();

// // 子类直接定义一个父类拥有的相同的属性,是可以正常工作的
 $m->name = "子姓名";
echo $m->name;
$m->work();
 $m->talk();

//$m->eat();  // 在子类的实例中,一样无法调用父类的protected方法
 $m->drive();

多态

// 多态:多种形态
// 抽象类:只有类的方法中有一个方法使用abstract关键字定义,则该类就是抽象类,该方法就是抽象方法
// 抽象类的特点:不能被实例化,只能被继承,抽象方法不能有实现代码
// 接口:极端的抽象,只能有方法的定义,不能有方法的实现,通常用于定义一些规则
abstract class animal{
    // function can(){
    //     echo "this function weill be re-write in the children. <br/>";
    // }
    abstract function can();    // 抽象方法不能实现代码,只能定义方法名和参数
    // abstract function work();
    function dosth() {
        echo "做一些事情";
    }
}
class cat extends animal{
    function can(){
        echo "I can climb. <br/>";
    }
}
class dog extends animal{
    function can(){
        echo "I can swim. <br/>";
    }
}
function test($obj){
    $obj->can();
}
test(new cat());    // 传递cat的实例时,运行的就是cat的can的方法
test(new dog());    // 传递dog的实例时,运行的就是dog的can的方法


// $a = new animal();  // 抽象类不能被实例化

序列化和反序列化

序列化:

将对象转换成字符串: 便于储存,便于运输。

 $student = array('name'=>'张三', 'age'=>30, 'addr'=>'成都高新区', 'phone'=>'18812345678');
 echo serialize($student);

输出:a:4:{s:4:"name";s:6:"张三";s:3:"age";i:30;s:4:"addr";s:15:"成都高新区";s:5:"phone";s:11:"18812345678";}

只要符合序列化规则的字符串,无论是否由serialize函数生成,均可以被反序列化。

如果要序列化一个类,则最好在_sleep魔术方法明确指定类属性,序列化的过程。只包含类的属性,不包含类的方法。

反序列化

将一个字符串转换成对象 比如:

$source = 'a:4:{s:4:"name";s:9:"张三娃";s:3:"age";i:30;s:4:"addr";s:15:"成都高新区";s:5:"phone";s:11:"18812345679";}';
 $student = unserialize($source);    // 将字符串反序列化为数组
 print_r($student);

反序列化类的构造当中,会调用类的析构方法,但是不会调用类的构造方法。

魔术方法

_sleep:在类进行序列化时调用,并用在里面需要明确定义序列化哪些类属性,以数组方式定义和返回。

_wakeuop():在类进行反序列化时调用,并且可以在该方法中定义恢复类状态的的代码,以便于让反序列化的实例可以正常调用方法。

// 当类进行序列化时自动调用,并且返回一个数组,包含要实例化的类属性
    function __sleep() {
        echo "DB类正在进行序列化. <br/>";
        return array('host', 'username', 'password', 'database');
    }

    // 在类进行反序列时调用,并且可以在该方法中定义恢复类状态的代码,以便于让反序列化的实例可以正常调用方法。
    function __wakeup() {
        echo "DB类正在被反序列化. <br/>";
        $this->create_connection();     // 恢复数据库的连接状态
    }
}

反序列化漏洞

1.字符串变对象过程中,如果没有对字符串输入进行检查,很有可能注入恶意代码。

2.通常情况下,反序列化漏洞并非通过黑盒测试或者盲注的方式进行探测,而是通过代码评审的方式进行漏洞验证。

标签:function,content,name,age,基础,echo,学习,array,PHP
From: https://www.cnblogs.com/Nige-W/p/16923007.html

相关文章

  • 网安学习-HTML
    一、HTML概述及发展史二、互联网原理三、开发工具的使用四、HTML骨架DTD|关于html标签|字符集|视口标签|浏览器私有设置|title标签|keywords关键字 |des......
  • 基于深度学习的AI绘画为何突然一下子火了?
    CLIP|Midjourney|dreamstudio AIGC|StableDiffusion |Imagen随着Disco、Midjourney、dreamstudio、AIGC、StableDiffusion、Imagen、深度学习、高性能计算、数据......
  • linux基础 | 基础介绍、目录、操作系统命令、用户管理、常用指令
    1、Linux目录知识Linux在根目录下有很多目录都是规定好的,比如etc里面是配置信息,boot是启动时用到的文件Linux会把计算机的硬件映射成一个文件来管理在Linux里面一切皆是......
  • 时间序列 工具库学习(18)adtk模块-异常类型
    1.异常类型异常是一个广义的概念,它可以指代时间序列中许多不同类型的事件。根据具体情况,价值飙升、波动性转变、违反季节性模式等都可能是异常的或正常的。ADTK提供了一组......
  • 机器学习 数学基础 学习笔记 (5)常见统计量
    1.期望离散型随机变量的一切可能的取值xi与对应的概率Pi(=xi)之积的和称为该离散型随机变量的数学期望(设级数绝对收敛),记为E(x)。随机变量最基本的数学特征之一。它反映随机......
  • 数据结构——学习经验
    数据结构各位读者朋友,我是你们的好朋友IT黑铁,最近巩固一下数据结构,大部分适合我当前阶段的知识都已做了简介,而其他只列出了名字的有的是省略点到即可,有些高深的暂未研究。......
  • Blazor和Vue对比学习(进阶2.2.5):状态管理之持久化保存(3),LocalStorage和IndexedDB
    PS1:点击查看Blazor中C#和JS互操作PS2:Vue中,可以直接使用LocalStorage和IndexedDB对象,本章节案例主要以Blazor的使用为主 一、Storage对象1、浏览器内置的键值对存储。l......
  • Kafka学习
    Kafka学习一、kafka所需的命令启动kafka要先启动zookeeper,zookeeper学习可以参考bilibili的尚硅谷的教程:07_尚硅谷_zk_本地_安装_哔哩哔哩_bilibili。启动kafka需要执行......
  • PHP 如何使用 Elasticsearch API接口
    一、实战场景如何在 PHP 中使用 ElasticsearchAPI 接口二、知识点PHPElasticsearchRestful 接口三、菜鸟实战1、安装 Elasticsearch 官方 PHPSDK​​https://gith......
  • php获取/dev/urandom随机数
    1.有一种算是比较好的随机数算法,但是需要支持​​Mcrypt​​模块://equivtorand,mt_rand//returnsintin*closed*interval[$min,$max]functiondevurandom_rand($mi......