编程语言对比手册(横向版)[-PHP-]

php-运行在服务端的跨平台免费面向对象的脚本语言

一、环境的搭建
1.WAMPServer集成环境下载和安装

Windows Apache MySQL PHP,官网:www.wampserver.com/ (首页挺狂放)


2.安装

安装软件可以随便在哪里下,官网挺慢的。安装next,也没什么好说的


3.运行

访问localhost,出现界面,表示服务端已经通了。(虽然目前什么都没做)


4.小面板

也就是便捷操作的面板

比如进入MySQL的控制台(WAMPServer会自动帮我们装一个MySQL,默认无密码)


5.网站访问

现在将一个以前的静态站点放在项目下的poem文件夹下

然后访问:http://localhost/poem/,不出所料,正常访问。
注意:到现在为止都是Apache的功劳,和PHP还没太大的关系。


6.多站点的支持

这里在:J:\PHP\webset文件夹下放一个站点的文件,只需要简单的修改以下配置,再重启即可

---->[D:\M\WAMP\wamp64\bin\apache\apache2.4.23\conf\extra\httpd-vhosts.conf]------------------------
<VirtualHost *:80>
	ServerName toly1994328.com #站点名
	DocumentRoot J:/PHP/webset #站点源码文件夹
	<Directory  "J:/PHP/webset">
		Options Indexes FollowSymLinks #站点权限相关
        AllowOverride all
        Require all granted
	</Directory>
</VirtualHost>

---->[C:\Windows\System32\drivers\etc\hosts]------------------------
127.0.0.1       toly1994328.com

---->[D:\M\WAMP\wamp64\bin\apache\apache2.4.23\conf\httpd.conf]------------------------
# Virtual hosts
Include conf/extra/httpd-vhosts.conf #这句话如果封住要解封(我这默认就开的)
复制代码


7.修改端口号

详见图片上的url中的端口号

---->[D:\M\WAMP\wamp64\bin\apache\apache2.4.23\conf\httpd.conf]------------------------
Listen 0.0.0.0:8081
Listen [::0]:8081

ServerName localhost:8081

|-- 多站点的话也要修改 httpd-vhosts 里的端口号
---->[D:\M\WAMP\wamp64\bin\apache\apache2.4.23\conf\extra\httpd-vhosts.conf]------------------------
<VirtualHost *:8081>
	ServerName localhost
	...
	
<VirtualHost *:8081>
	ServerName toly1994328.com #站点名
	...
</VirtualHost>
复制代码


二、php语法初识
1.什么都不说,来个Hello World先 : echo 输出

感觉挺爽的嘛,SpringBoot的HelloWorld比这麻烦多了

---->[Hello.php]---------------------------
<?php 
echo "Hello World!"; 
复制代码

2.变量 $ 名称 = 变量

---->[vartest.php]---------------------------
<?php
    $name="张风捷特烈";//生成变量
    echo $name;//输出变量
    echo "<br />";//输出换行
    $name="toly";//改变变量
    echo $name;//输出变量
复制代码

3.几种数据组织形式

感觉比JavaScript还要奔放,比Python要收敛一丢丢。就是$符号太多...晃眼

<?php

$t = true;//1.布尔型
$fa = false;//布尔型

$i = 5; //2.整型
$a = 0xff; // 支持十六进制数 -- 255
$b = 074; // 支持八进制数 -- 60

$f = 3.14159;//3.浮点型
$f1 = 3.14159e4;//浮点型 31415.9
$f2 = 3.14159e-3;//浮点型 0.00314159

$str = "String Type";//4.字符串
$str = 'String Type';//字符串

$color = array("red", "green", "blue");//5.数组
echo $color[0];//获取元素

$colorMap = array("red"=>"红色", "green"=>"绿色", "blue"=>"蓝色");//6.类似映射或字典
echo $colorMap["red"];//红色

$shape = new Shape("四维空间");//7.对象
echo $shape->getName(); //调用方法

$n=null;//8.null

class Shape{
    var $name;
    function __construct($name = "green"){
        $this->name = $name;
    }

    /**
     * @return string
     */
    public function getName() {
        return $this->name;
    }

    /**
     * @param string $name
     */
    public function setName($name){
        $this->name = $name;
    }
}
复制代码

4.看一下请求和响应:Hello.php
|--- 客户端请求 (此时不太关心)
GET http://toly1994328.com/Hello.php HTTP/1.1
Host: toly1994328.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

|--- 服务端响应 
HTTP/1.1 200 OK
Date: Wed, 13 Mar 2019 14:06:15 GMT
Server: Apache/2.4.23 (Win64) PHP/5.6.25
X-Powered-By: PHP/5.6.25
Content-Length: 13
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8  <----text/html 表示可以让浏览器解析请求体中的html代码

Hello World! <---- 可见echo可以将数据放入请求体里
复制代码

5.小测试

既然echo可以输出,放个静态页面输出会怎么样,就来个粒子吧
这说明echo可以将整个html页面输出让浏览器解析,这样的话php的地位应该是控制服务端的输出流。

<?php
echo "<!doctype html>
<html>
<head>
    <meta charset=\"utf-8\">
    <title>液态粒子字体</title>
    <style>
        body,html {
            margin:0;
            width:100%;
            overflow:hidden;
        }
        canvas {
            width:100%;
        }
        .control {
            position:absolute;
        }
        .control input {
            border:0;
            margin:0;
            padding:15px;
            outline:none;
            text-align:center;
        }
        .control button {
            border:0;
            margin:0;
            padding:15px;
            outline:none;
            background:#333;
            color:#fff;
        }
        .control button:focus,.control button:hover {
            background:#222
        }
    </style>
</head>
<body>
<div class = \"control\" style = \"position:absolute\">
    <input type = \"text\" value = \"张风捷特烈\" id = \"t\">
    <button onclick = \"changeText(t.value)\">
        change
    </button>
</div>
<script>
    var can = document.createElement(\"canvas\");
    document.body.appendChild(can);
    var ctx = can.getContext('2d');
    function resize(){
        can.width = window.innerWidth;
        can.height = window.innerHeight;
    }
    const max_radius = 3;
    const min_radius = 1;
    const drag = 50;
    window.onresize = function(){
        resize();
    };
    function cfill(){
        ctx.fillStyle = \"#000\";
        ctx.fillRect(0,0,can.width,can.height);
        ctx.fill();
    }
    var mouse = {
        x:-1000,
        y:-1000
    };
    can.onmousemove = function(e){
        mouse.x = e.clientX;
        mouse.y = e.clientY;
    };
    can.ontouchmove = function(e){
        mouse.x = e.touches[0].clientX;
        mouse.y = e.touches[0].clientY;
    };
    resize();
    cfill();

    function distance(x,y,x1,y1){
        return Math.sqrt( ( x1-x ) * ( x1-x ) + ( y1-y ) * ( y1-y ) );
    }
    class Particle{
        constructor(pos,target,vel,color,radius){
            this.pos = pos;
            this.target = target;
            this.vel = vel;
            this.color = color;
            this.radius = radius;
            var arr = [-1,1];
            this.direction = arr[~~(Math.random()*2)]*Math.random()/10;
        }
        set(type,value){
            this[type] = value;
        }
        update(){
            this.radius += this.direction;
            this.vel.x = (this.pos.x - this.target.x)/drag;
            this.vel.y = (this.pos.y - this.target.y)/drag;
            if(distance(this.pos.x,this.pos.y,mouse.x,mouse.y) < 50){
                this.vel.x += this.vel.x - (this.pos.x - mouse.x)/15;
                this.vel.y += this.vel.y - (this.pos.y - mouse.y)/15;
            }
            if(this.radius >= max_radius){
                this.direction *= -1;
            }
            if(this.radius <= 1){
                this.direction *= -1;
            }
            this.pos.x -= this.vel.x;
            this.pos.y -= this.vel.y;
        }
        draw(){
            ctx.beginPath();
            ctx.fillStyle = this.color;
            ctx.arc(this.pos.x,this.pos.y,this.radius,0,Math.PI*2);
            ctx.fill();
        }
    }
    var particles = [];
    var colors = [\"#bf1337\",\"#f3f1f3\",\"#084c8d\",\"#f2d108\",\"#efd282\"];
    var bool = true;
    var current = 0,i;
    function changeText(text){
        var current = 0,temp,radius,color;
        cfill();
        ctx.fillStyle = \"#fff\";
        ctx.font = \"120px Times\";
        ctx.fillText(text,can.width*0.5-ctx.measureText(text).width*0.5,can.height*0.5+60);
        var data = ctx.getImageData(0,0,can.width,can.height).data;
        cfill();
        for(i = 0;i < data.length;i += 8){
            temp = {x:(i/4)%can.width,y:~~((i/4)/can.width)};
            if(data[i] !== 0 && ~~(Math.random()*5) == 1/*(temp.x % (max_radius+1) === 0 && temp.y % (max_radius+1) === 0)*/){
                if(data[i+4] !== 255 || data[i-4] !== 255 || data[i+can.width*4] !== 255 || data[i-can.width*4] !== 255){
                    if(current < particles.length){
                        particles[current].set(\"target\",temp);
                    }else{
                        radius = max_radius-Math.random()*min_radius;
                        temp = {x:Math.random()*can.width,y:Math.random()*can.height};
                        if(bool){
                            temp = {x:(i/4)%can.width,y:~~((i/4)/can.width)};
                        }
                        color = colors[~~(Math.random()*colors.length)];
                        var p = new Particle(
                            temp,
                            {x:(i/4)%can.width,y:~~((i/4)/can.width)},{x:0,y:0},
                            color,
                            radius);
                        particles.push(p);
                    }
                    ++current;
                }
            }
        }
        bool = false;
        particles.splice(current,particles.length-current);
    }
    function draw(){
        cfill();
        for(i = 0;i < particles.length;++i){
            particles[i].update();
            particles[i].draw();
        }
    }
    changeText(\"张风捷特烈\");
    setInterval(draw,1);</script>
</body>
</html>"
复制代码

6、Idea 集成PHP环境

工欲善其事必先利其器,总不能在文本编辑器里写代码吧,IDE 本人首选Idea

6.1.先装插件


6.2.配置php环境

然后就开心的敲代码了,提示什么的都有

好了,引入到此为止,下面开始正文


三、PHP中的面向对象
1.类的定义和构造函数+析构函数

---->[obj/Shape.php]----------------
<?php
namespace toly1994;

class Shape{
    public function __construct(){
        echo "Shape构造函数";
    }
    
    function __destruct(){
        echo "Shape析构函数";
    }
}

---->[obj/Client.php]----------------
<?php
include './Shape.php';//引入文件
use toly1994\Shape;

$shape = new Shape();
复制代码

2.类的封装(成员变量,成员方法)
---->[obj/Shape.php]----------------
<?php
namespace toly1994;
class Shape{
    private $name;
    public function __construct($name){
        echo "Shape构造函数<br/>";
        $this->name = $name;
    }
    public function getName(){
        return $this->name;
    }
    public function setName($name){
        $this->name = $name;
    }
    public function draw(){
        echo "绘制$this->name <br/>";
    }
    function __destruct(){
        echo "Shape析构函数";
    }
}

|-- 使用 --------------------------
$shape = new Shape("Shape");
$shape->draw();//绘制Shape
$shape->setName("四维空间<br/>");
echo $shape->getName();//四维空间 
复制代码

3.类的继承
---->[obj/Point.php]----------------
<?php
namespace toly1994;
class Point extends Shape{
    public $x;
    public $y;
}

|-- 使用 --------------------------
$point = new Point("二维点");
$point->draw();//绘制二维点
echo $point->getName();//二维点
$point->x=20;//二维点
echo $point->x;//20
复制代码

4.类的多态
---->[obj/Circle.php]----------------
<?php
namespace toly1994;
class Circle extends Shape{
    private $radius;
    public function getRadius(){
        return $this->radius;
    }

    public function setRadius($radius){
        $this->radius = $radius;
    }
    public function draw(){
        echo "Draw in Circle<br/>";
    }
}

---->[obj/Point.php]----------------
<?php
namespace toly1994;
class Point extends Shape{
    public $x;
    public $y;
    public function draw(){
        echo "Draw in Point<br/>";
    }
}

|-- 使用 --------------------------
$point=new Point("");
doDraw($point);//Draw in Point
$circle=new Circle("");
doDraw($circle);//Draw in Circle

function doDraw(Shape $shape){
    $shape->draw();
}
复制代码

5.接口及抽象类
抽象类---->[obj/Shape.php]----------------
abstract class Shape{
    ...
    //抽象方法
    abstract protected function draw();
}

接口---->[obj/Drawable.php]----------------
<?php
namespace toly1994;

interface Drawable{
    public function draw();
}

|-- 实现接口 implements 关键字-----------
include './Drawable.php';//引入文件
abstract class Shape implements Drawable
复制代码

四、PHP中的函数:
1.PHP中函数的定义

在Circle类中,定义一个函数计算圆的面积:getArea

---->[obj/Circle.php]----------------
<?php
namespace toly1994;
define("PI", 3.141592654);//定义常量
class Circle extends Shape{
    private $radius;
    public function __construct($radius) {
        $this->radius = $radius;
    }
    ...
    /**
     * 获取圆的面积
     * @return float|int
     */
    public function getArea(){
        $area = PI * $this->radius * $this->radius;
        return $area;
    }
}

|-- 对象使用函数(方法)
$circle = new Circle(10);
echo $circle->getArea();//314.15926541
$circle->setRadius(20);
echo $circle->getArea();//256.6370616
复制代码

函数名调用时竟然不区分大小写,方法也不支持重载,真是神奇的语言...


2.类的静态方法以及参数

创建一个工具类来换行

---->[utils/Utils.php]--------------------
<?php
class Utils{
    /**
     *  换行工具方法
     * @param int $num 行数
     * @param bool $line true <hr>   false <br>
     */
    public static function line($num = 1, $line = true)
    {
        for ($i = 0; $i < $num; $i++) {//for循环控制
            if ($line) {//条件控制
                echo "<hr>";
            } else {
                echo "<br>";
            }
        }
    }
}

---->[base/Funtest.php]------调用--------------
<?php
include '../utils/Utils.php';

Utils::line();//默认一行 有线
Utils::line(2,false);//两行 无线
Utils::line(5);//五行 无线
复制代码

3.二维数组的使用来创建table

/** 创建表格
 * @param $content 二维数组
 * @param string $css 表格样式
 * @return string
 */
public static function createTable($content, $css = "border='1' cellspacing='0' cellpadding='0' width='80%'")
{
    $row = count($content);
    $col = count($content[0]);
    $table = "<table $css>";
    for ($i = 0; $i < $row; $i++) {//for循环控制
        $table .= "<tr/>";
        for ($j = 0; $j < $col; $j++) {
            $value = $content[$i][$j];
            $table .= "<td>$value</td>";
        }
        $table .= "</tr>";
    }
    $table .= "</table>";
    return $table;
}

|-- 使用---------------------------
<?php
include '../utils/Utils.php';
$content = [
    ["姓名", "年龄", "性别", "武器", "职业"],
    ["捷特", 24, "男", "黑风剑", "战士"],
    ["龙少", 23, "男", "控尊戒", "铸士"],
    ["巫缨", 23, "女", "百里弓", "弓士"],
];
echo Utils::createTable($content);
Utils::line();
$css = "border='5' cellspacing='0' cellpadding='0' width='80%' bgcolor=#81D4F5";
echo Utils::createTable($content, $css);//自定义表格样式
复制代码

4.变量作用域
4.1 局部变量

局部变量不能在块的外面被调用

|--- 方法中[局部变量-动态变量]在函数调用完成会释放------------------
function area1(){
   static $inArea = true;
    if ($inArea) {
        echo "true<br/>";
    } else {
        echo "false<br/>";
    }
    $inArea = !$inArea;
}
area1();//true
area1();//true
area1();//true

|--- 方法中[局部变量-静态变量]在函数调用完成不会释放,在静态内存区----------------
function area1(){
   static $inArea = true;
    if ($inArea) {
        echo "true<br/>";
    } else {
        echo "false<br/>";
    }
    $inArea = !$inArea;
}
area1();//true
area1();//false
area1();//true
复制代码

4.2 全局变量
|-- 方法体中不能使用外面定义的变量
$name = "toly";
function say(){
    echo "My name is $name" ;//Undefined variable: name
}
say();

|-- 解决方,1,在方法体中使用global关键字对变量进行修饰
$name = "toly";
function say(){
    global $name;
    echo "My name is $name";
}
say();

|-- 解决方法2,使用$GLOBALS键值对获取全局变量
$name = "toly";
function say(){
    echo "My name is " . $GLOBALS['name'];
}
say();
复制代码

5.传值与传引用
|-- 传入值,并不会导致原值污染
function add($target){
    $target = $target + 1;
    return $target;
}
$num = 10;
$res = add($num);
echo $res;//11
echo $num;//10

|-- 传引用,方法中对入参的修改会修改原值
function add(&$target)//取地址{
    $target = $target + 1;
    return $target;
}
$num = 10;
$res = add($num);
echo $res;//11
echo $num;//11
复制代码

6.其他特点
|-- 可变函数(函数的变量化)----------------
function add($x, $y){
    return $x + $y;
}
$fun = "add";//函数变量化
echo $fun(3, 4);//7 

|-- 函数作为入参(俗称回调) ----------------
function add($x, $y, $fun){
    return $fun($x) + $fun($y);
}

echo add(3, 4, function ($i) {//此处通过匿名函数
    return $i * $i;
});//25

|-- //此处通过create_function创建匿名函数(php7.2后过时)
echo add(3, 4, create_function('$i', 'return $i * $i;'));//25

|-- 通过 call_user_func 来调用函数--------感觉挺诡异
call_user_func("md5", "张风捷特烈");//20ce3e8f34f3a3dd732a150a36d41512

|-- 通过 call_user_func_array 来调用函数--------第二参是参数的数组
function add($x, $y){
    return $x + $y;
}
echo call_user_func_array("add", array(3,4));//7
复制代码

五、PHP中对文件的操作
1.创建文件(含递归文件夹)

$path = 'G:/Out/language/php/2/3/45/dragon.txt';
createFile($path);

function createFile($path){
    $dir = dirname($path);//获取父文件
    if (!file_exists($dir)) {
        mkdirs($dir);
        createFile($path);
    } else {
        fopen($path, "w");
    }
}

function mkdirs($dir){
    return is_dir($dir) or mkdirs(dirname($dir)) and mkdir($dir, 0777);
}
复制代码

2.写入字符文件

文件不存在,则创建文件再写入

/**
 * 将内容写入文件
 * @param $path 路径
 * @param $content 内容
 */
function writeStr($path, $content){
    if (file_exists($path)) {
        if ($fp = fopen($path, 'w')) {
            fwrite($fp, $content);
            fclose($fp);
            echo "<br>写入成功 " . $content;
        } else {
            echo "<br>创建失败 ";
        }
    } else {
        createFile($path);
        writeStr($path, $content);
    }
}
复制代码

3.读取文件

|-- 内置函数 readfile 读取文件
echo readFile($path);

|-- fgetc 逐字读取
function readFileByPath($path){
    $result = "";
    $file = fopen($path, "r") or $result . "无法打开文件!";
    while (!feof($file)) {
        $result .= fgetc($file);
    }
    fclose($file);
    return $result;
}

|-- fgets 逐行读取
function readFileByLine($path){
    $result = "";
    $file = fopen($path, "r") or $result . "无法打开文件!";
    while (!feof($file)) {
        $result .= fgets($file)."<br/>";
    }
    fclose($file);
    return $result;
}

|-- 以行划分将文件读入数组
var_dump(file($path));

array(3) { [0]=> string(26) "应龙----张风捷特烈 " [1]=> string(49) "一游小池两岁月,洗却凡世几闲尘。 " [2]=> string(48) "时逢雷霆风会雨,应乘扶摇化入云。" }
复制代码

4.文件信息

还有很多乱七八糟的方法...用的时候再找吧,感觉和Python挺像的

$path = 'G:/Out/language/php/2/3/45/dragon.txt';

$stat = stat($path);
echo "创建时间:" . date("Y-m-d H:i", $stat["ctime"]);//2019-03-14 04:45
echo "修改时间:" . date("Y-m-d H:i", $stat["mtime"]);//2019-03-14 04:54
echo "文件大小:" . $stat["size"] . " 字节";
echo "文件模式:" . $stat["mode"];
echo "文件名:" . basename($path);
echo "父文件夹:" . dirname($path);
echo "是否是文件夹:" . (is_dir($path) ? "true" : "false");
echo "是否是文件:" . (is_file($path) ? "true" : "false");
echo "是否存在:" . (file_exists($path) ? "true" : "false");
echo "文件所在磁盘可用大小:" . disk_free_space(dirname($path)) . " 字节";
echo "文件所在磁盘总大小:" . disk_total_space(dirname($path)) . " 字节";
echo "文件类型:" . filetype($path);//file
复制代码

5.文件读写权限

基本上和其他语言一样

r	只读。在文件的开头开始。
r+	读/写。在文件的开头开始。

w	只写。打开并清空文件的内容;如果文件不存在,则创建新文件。
w+	读/写。打开并清空文件的内容;如果文件不存在,则创建新文件。

a	追加。打开并向文件末尾进行写操作,如果文件不存在,则创建新文件。
a+	读/追加。通过向文件末尾写内容,来保持文件内容。

x	只写。创建新文件。如果文件已存在,则返回 FALSE 和一个错误。
x+	读/写。创建新文件。如果文件已存在,则返回 FALSE 和一个错误。
复制代码

六、PHP和MySQL的结合

还是玩sword表吧


1.连接MySQL

<?php
$host = "localhost";
$user = "root";
$pwd = "----";
$conn = mysqli_connect($host, $user, $pwd);

// 检测连接
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
}
echo "连接成功";
$conn->close();//关闭数据库
复制代码

2.查询数据库并封装实体类

连上数据库然后就是SQL的领域了

<?php
include './Sword.php';
$host = "localhost";
$user = "root";
$pwd = "----";
$conn = mysqli_connect($host, $user, $pwd);
// 检测连接
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
}
echo "连接成功";
mysqli_select_db($conn, "zoom");//选择数据库
$sql = "SELECT * FROM sword";//sql语句
$result = $conn->query($sql);
$swords = array();
if ($result->num_rows > 0) {
    // 输出数据
    while ($row = $result->fetch_assoc()) {
        $sword = new Sword(
            $row["id"],
            $row["name"],
            $row["atk"],
            $row["hit"],
            $row["crit"],
            $row["attr_id"],
            $row["type_id"]
        );
        array_push($swords, $sword);
    }
}
复制代码

3.将查询的结果转化为json

echo json_encode($swords);
复制代码

也可以将结果输出成表格

function createTable($content, $css = "border='1' cellspacing='0' cellpadding='0' width='80%'"){
    $row = count($content);
    $table = "<table $css >";
    for ($i = 0; $i < $row; $i++) {//for循环控制
        $table .= "<tr/>";
        $value = $content[$i];
        $table .= "<td >$value->id</td>";
        $table .= "<td >$value->name</td>";
        $table .= "<td >$value->atk</td>";
        $table .= "<td >$value->hit</td>";
        $table .= "<td >$value->crit</td>";
        $table .= "<td >$value->attr_id</td>";
        $table .= "<td >$value->type_id</td>";
        $table .= "</tr>";
    }
    $table .= "</table>";
    return $table;
}
复制代码

4.创建数据库

// 创建数据库
$sql = "CREATE DATABASE php";
echo $conn->query($sql) ? "数据库创建成功" : "数据库创建失败" . $conn->error;
复制代码

5.创建表

mysqli_select_db($conn, "php");//选择数据库
$sql="create table sword
(
  id      smallint(5) unsigned auto_increment
    primary key,
  name    varchar(32)                       not null,
  atk     smallint(5) unsigned              not null,
  hit     smallint(5) unsigned              not null,
  crit    smallint(5) unsigned default '10' null,
  attr_id smallint(5) unsigned              not null,
  type_id smallint(5) unsigned              not null
)";
echo $conn->query($sql) ? "sword创建成功" : "sword创建失败" . $conn->error;
复制代码

另外增删改查的操作关键是sql语句,本文就不引申了


七、PHP的字符串及正则语法
1.PHP的字符串

|-- 双引号 : 可解析变量    解析所有转移符--------------
<?php
$name = "toly-张风捷特烈-1994328";
echo "$name";

|-- 单引号: 不可解析变量 只解析\'  \\两个转义符------------
<?php
$name = "toly-张风捷特烈-1994328";
echo '$name';

|-- 字符冲突时用转义符 : \---------------------
\\      \'      \$      \"      \r      \n      \t      \f

|-- {}的辅助 --- {}要紧贴变量,不要加空格----------------
echo "{$name}s";//toly-张风捷特烈-1994328s
echo "${name}s";//toly-张风捷特烈-1994328s

|-- 字符的操作 
echo $name[0];//t
Utils::line();
echo $name{1};//o
Utils::line();
 $name[2]='L';
echo $name;//toLy-张风捷特烈-1994328
复制代码

2.heredoc 和 nowdoc
|-- heredoc作用同双引号,只是在其中双引号不用转义------------
$html = <<<EOF
"在"""""s这里面'''""'原样输出"
EOF;
echo $html;

|-- nowdoc作用同单引号,只是在其中双引号不用转义------------
$html = <<<'EOD'
""""""s这里面'''""'原样输出"
EOD;
echo $html;
复制代码

3.其他类型转换为字符串
数字: 原样
布尔: ture 1  false ''
null:  ''
数组: Array

$num=1;
$res = (string)$num;//类型转换
strval($num);//类型转换

settype($num,'string')//$num本身转变

|-- php中布尔值为false的情况
$flag = '';//假
$flag = "";//假
$flag = null;//假
$flag = 0;//假
$flag = "0";//假
$flag = 0.0;//假
$flag = "0.0";//真
$flag = array();//假
$flag = 'false';//真

echo $flag ? "真" : "假";
复制代码

4.字符串的一些方法
$name = "kiNg tolY-张风捷特烈-1994328";

echo is_string($name) ? "是字符串" : "不字符串";//是字符串
echo empty($name) ? "为空" : "不为空";//不为空
echo "字符串长度:" . strlen($name);//字符串长度:33
echo "转大写:" . strtoupper($name);//转大写:KING TOLY-张风捷特烈-1994328
echo "转小写:" . strtolower($name);//转小写:king toly-张风捷特烈-1994328
echo "首字母大写:" . ucfirst($name);//首字母大写:KiNg tolY-张风捷特烈-1994328
echo "单词首字母大写:" . ucwords($name);//单词首字母大写:KiNg TolY-张风捷特烈-1994328
echo substr($name, 2, 8);//Ng tolY-
echo substr($name, -7, 4);//1994
echo substr($name, 2);//Ng tolY-张风捷特烈-1994328
echo substr($name, 2, -4);//Ng tolY-张风捷特烈-199
echo trim("  rry   ");//rry  去除两端的空格
echo rtrim("  rry   ");// rry 去除右端的空格
echo ltrim("  rry   ");//rry 去除左端的空格
echo trim($name, "k");//iNg tolY-张风捷特烈-1994328 指定字符trim
$arr = ["java","kotlin","javascript","c++"];
echo join($arr, "-->");//java-->kotlin-->javascript-->c++ 

|-- 字符串的正则操作
$split = preg_split("/-/", $name);//正则切割
print_r($split);//Array ( [0] => kiNg tolY [1] => 张风捷特烈 [2] => 1994328 )
$match = preg_match("/\d{10,16}/", $name);//匹配连续10~16个数字
print_r($match ? "匹配成功" : "匹配失败");//匹配失败
echo preg_replace("/-/","·",$name);//kiNg tolY·张风捷特烈·1994328
复制代码

八、表单及上传与下载
1.php获取表单传入的数据

---->[reg.php]-----------------------
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
</head>
<body>
<h1>注册页面</h1>
<form action="doReg.php" method="post">
    <label>用户名:</label>
    <input type="text" name="username" placeholder="请输入用户名">

    <label>密码:</label>
    <input type="password" name="password" placeholder="请输入密码">

    <label>确认密码:</label>
    <input type="password" name="conform-password" placeholder="确认密码">
    <input type="submit" name="submit">
</form>
</body>
</html>

---->[doReg.php]-----------------------
<?php
$name = $_POST['username']; //获取表单数据
echo $name;  //这样就可以连接mysql插入数据库了
复制代码

2.php上传文件

---->[upload.php]-----客户端-----------------------
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传页面</title>
</head>
<body>
    <h1>上传页面</h1>
    <form action="doUploadFile.php" method="post" enctype="multipart/form-data">
        <label>选择文件:</label>
        <input type="file" name="filename" placeholder="请输入用户名">
        <input type="submit" name="submit">
    </form>
</body>
</html>

---->[doUploadFile.php]-----服务端-----------------------
<?php
print_r($_FILES); //打印一下信息(非必要)

$file = $_FILES["filename"];
$name = $file["name"];//上传文件的名称
$type = $file["type"];//MIME类型
$tempName = $file["tmp_name"];//临时文件名
$size = $file["size"];//文件大小
$error = $file["error"];//错误
//方式一:将临时文件移动到指定文件夹
//move_uploaded_file($tempName, "G:/Out/" . $name);

//方式二: 拷贝到目标文件夹
copy($tempName, "G:/Out/" . $name);
复制代码

3.php上传文件的配置项

D:\M\WAMP\wamp64\bin\php\php5.6.25\php.ini

file_uploads = On 允许HTTP上传
upload_tmp_dir ="D:/M/WAMP/wamp64/tmp" 临时文件夹
upload_max_filesize = 2M 文件最大尺寸
max_file_uploads = 20 最大单次上传文件数
post_max_size = 8M post发送的最大尺寸

|-- 错误码----------------------
UPLOAD_ERR_OK;//0 没有错误
UPLOAD_ERR_INI_SIZE;//1  超过 upload_max_filesize
UPLOAD_ERR_FORM_SIZE;//2  超过max_file_uploads
UPLOAD_ERR_PARTIAL;//3 只有部分上传
UPLOAD_ERR_NO_FILE;//4 没有文件
UPLOAD_ERR_NO_TMP_DIR;//6 没有找到临时文件夹
UPLOAD_ERR_CANT_WRITE;//7 文件写入失败
UPLOAD_ERR_EXTENSION;//8 上传被中断
复制代码

4.上传的条件约束及封装
function upload(
    $file, //文件信息对象
    $dir = "G:/Out/", //目标文件夹
    $acceptType = ["png", "jpg", "jpeg", "gif", "bmp"],//允许的类型
    $all = false, //是否忽略类型
    $maxSize = 2 * 1024 * 1024){//文件大小
    
    $name = $file["name"];//上传文件的名称
    $tempName = $file["tmp_name"];//临时文件名
    $size = $file["size"];//文件大小
    $error = $file["error"];//错误
    $ext = pathinfo($name, PATHINFO_EXTENSION);;
    judge_dirs($dir);
    $dest = $dir . md5(uniqid(microtime(true), true)) . ".$ext";
    if ($error == 0) {//1.上传正确
        if ($size < $maxSize) {//2.上传文件大小
            if (in_array($ext, $acceptType) || $all) {//3.拓展名
                if (is_uploaded_file($tempName)) {//4.通过http post上传
                    copy($tempName, $dest);// 拷贝到目标文件夹
                    return $dest;
                }
            }
        }
    }
    exit("上传错误");
}
/**
 * 递归创建文件夹
 * @param $dir 文件夹
 * @return bool
 */
function judge_dirs($dirName)
{
    if (file_exists($dirName)) {
        return true;
    }
    return is_dir($dirName) or judge_dirs(dirname($dirName)) and mkdir($dirName, 0777);
}
复制代码

九、简单实现多文件上传
1.name不同时多文件上传结果

从获取的数据上来看,一个二维数组,每个装载了一个文件信息

---->[upload.php]--------form表单---------
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传页面</title>
</head>
<body>
<h1>上传页面</h1>
<form action="doUploadFile.php" method="post" enctype="multipart/form-data">
    <label>选择文件:</label><input type="file" name="filename1"><br>
    <label>选择文件:</label><input type="file" name="filename2"><br>
    <label>选择文件:</label><input type="file" name="filename3"><br>
    <input type="submit" name="submit">
</form>
</body>
</html>

---->[doUploadFile.php]--------上传处理---------
<?php
print_r($_FILES);
复制代码


2.name名称为XXX[]

从获取的数据上来看,一个三维数组,针对每个属性对多个文件进行规整成数组

---->[upload2.php]--------form表单---------
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传页面</title>
</head>
<body>
<h1>上传页面</h1>
<form action="doUploadFile.php" method="post" enctype="multipart/form-data">
    <label>选择文件:</label><input type="file" name="filename[]"><br>
    <label>选择文件:</label><input type="file" name="filename[]"><br>
    <label>选择文件:</label><input type="file" name="filename[]"><br>

    <input type="submit" name="submit">
</form>
</body>
</html>

---->[doUploadFile.php]--------上传处理---------
<?php
print_r($_FILES);
复制代码


3.对两种结果的格式化

这里封装一个Uploader类来进行上传管理

class Uploader
{
    /** 格式化多文件上传返回数据
     * @param $files 文件信息
     * @return mixed
     */
    public function format($files)
    {
        $i = 0;
        foreach ($files as $file) {
            if (is_string($file['name'])) {//说明是二维数组
                $result[$i] = $file;
                $i++;
            } elseif (is_array($file['name'])) {//说明是三维数组
                foreach ($file['name'] as $k => $v) {
                    $result[$i]['name'] = $file['name'][$k];
                    $result[$i]['type'] = $file['type'][$k];
                    $result[$i]['tmp_name'] = $file['tmp_name'][$k];
                    $result[$i]['size'] = $file['size'][$k];
                    $result[$i]['error'] = $file['error'][$k];
                    $i++;
                }
            }
        }
        return $result;
    }
}
复制代码

4.封装一下上传错误
public static $errorInfo = [
    "上传成功",
    "超过 upload_max_filesize",
    "超过max_file_uploads",
    "只有部分上传",
    "没有文件",
    "文件类型不匹配",
    "没有找到临时文件夹",
    "文件写入失败",
    "上传被中断",
    "文件大小超出限制",
    "文件不是通过POST上传",
    "文件移动失败",
];
复制代码

5.上传核心逻辑
public function upload(
    $file,
    $dir = "C:/Users/Administrator/upload/temp",//目标文件夹
    $all = false, //是否忽略类型,//文件大小
    $maxSize = 2 * 1024 * 1024,//文件大小
    $acceptType = ["png", "jpg", "jpeg", "gif", "bmp"]//允许的类型
)
{
    $name = $file["name"];//上传文件的名称
    $tempName = $file["tmp_name"];//临时文件名
    $size = $file["size"];//文件大小
    $error = $file["error"];//错误
    $ext = File::getExt($name);
    $dest = $dir . File::getUniName() . "." . $ext;//输出文件名
    new File($dest);//文件夹不存在则创建文件夹
    $msg["code"] = $error;
    $msg["src"] = $name;
    $msg["dest"] = $dest;
    $msg['info'] = Uploader::$errorInfo[$error];
    if ($file["error"] == UPLOAD_ERR_OK) {//1.成功
        if ($size > $maxSize) {//2.文件大小限制
            $msg['info'] = Uploader::$errorInfo[9];
        }
        if (!in_array($ext, $acceptType) && !$all) {//3.文件类型匹配
            $msg['info'] = Uploader::$errorInfo[5];
        }
        if (!is_uploaded_file($tempName)) {//4.通过http post上传
            $msg['info'] = Uploader::$errorInfo[10];
        }
        if (!move_uploaded_file($tempName, $dest)) {// 拷贝到目标文件夹
            $msg['info'] = Uploader::$errorInfo[11];
        }
    }
    return $msg;
}
复制代码

6.文件File类的简单封装
<?php
namespace file;
class File
{
    private $path;
    /**
     * File constructor.
     * @param $path
     */
    public function __construct($path)
    {
        $this->path = $path;
        if (is_dir($path)) {
            $this->judge_dirs_or_create($path);
        } else {
            $this->createFile($path);
        }
    }
    public function createFile($path)
    {
        $dir = dirname($path);//获取父文件
        if (!file_exists($dir)) {
            $this->judge_dirs_or_create($dir);
            $this->createFile($path);
        } else {
            fopen($path, "w");
        }
    }
    /**
     * 递归创建文件夹
     * @param $dir 文件夹
     * @return bool
     */
    public function judge_dirs_or_create($dirName)
    {
        if (file_exists($dirName)) {
            return true;
        }
        return is_dir($dirName) or $this->judge_dirs_or_create(dirname($dirName)) and mkdir($dirName, 0777);
    }
    
    /**
     * 获取文件拓展名
     * @param $name
     * @return mixed
     */
    public static function getExt($name)
    {
        return pathinfo($name, PATHINFO_EXTENSION);
    }
    /**
     * 获取唯一名称
     * @param $name
     * @return mixed
     */
    public static function getUniName()
    {
        return md5(uniqid(microtime(true), true));
    }
}
复制代码

7.对一些字段进行抽取和封装

<?php
namespace file;
include 'File.php';

class Uploader{
    private $files;
    private $dir;
    private $acceptType;
    private $all;
    private $maxSize;
    private $msgs = [];
    
//getter setter方法....略...

    public static $errorInfo = [
        "上传成功",
        "超过 upload_max_filesize",
        "超过max_file_uploads",
        "只有部分上传",
        "没有文件",
        "文件类型不匹配",
        "没有找到临时文件夹",
        "文件写入失败",
        "上传被中断",
        "文件大小超出限制",
        "文件不是通过POST上传",
        "文件移动失败",
    ];

    /**
     * Uploader constructor.
     * @param string $dir 文件夹
     * @param array $acceptType 上传类型
     * @param bool $all 是否忽略类型
     * @param float|int $maxSize 文件大小限制
     */
    public function __construct(
        $dir = "C:/Users/Administrator/upload/temp",
        $acceptType = ["png", "jpg", "jpeg", "gif", "bmp"],
        $all = false, //是否忽略类型,//文件大小
        $maxSize = 2 * 1024 * 1024
    ){
        $this->files = $_FILES;
        $this->dir = $dir;
        $this->acceptType = $acceptType;
        $this->maxSize = $maxSize;
        $this->all = $all;
    }

    public function uploadFile(){
        $format = $this->format($this->files);
        foreach ($format as $file) {
            $res = $this->upload($file);
            array_push($this->msgs, $res);
        }
        return $this->msgs;
    }

    private function upload($file){
        $name = $file["name"];//上传文件的名称
        $tempName = $file["tmp_name"];//临时文件名
        $size = $file["size"];//文件大小
        $error = $file["error"];//错误

        $ext = File::getExt($name);
        $dest = $this->dir . File::getUniName() . "." . $ext;//输出文件名
        new File($dest);//文件夹不存在则创建文件夹
        $msg["code"] = $error;
        $msg["src"] = $name;
        $msg["dest"] = $dest;
        $msg['info'] = Uploader::$errorInfo[$error];
        if ($file["error"] == UPLOAD_ERR_OK) {//1.成功
            if ($size > $this->maxSize) {//2.文件大小限制
                $msg["code"] = 9;
            }
            if (!in_array($ext, $this->acceptType) && !$this->all) {//3.文件类型匹配
                $msg["code"] = 5;
            }
            if (!is_uploaded_file($tempName)) {//4.通过http post上传
                $msg["code"] = 10;
            }

            if (!move_uploaded_file($tempName, $dest)) {//拷贝到目标文件夹
                $msg["code"] = 11;
            }
        }

        $msg['info'] = Uploader::$errorInfo[$msg["code"]];
        return $msg;
    }


    /** 格式化多文件上传返回数据
     * @param $files 文件信息
     * @return mixed
     */
    public function format($files){
        $i = 0;
        foreach ($files as $file) {
            if (is_string($file['name'])) {//说明是二维数组
                $result[$i] = $file;
                $i++;
            } elseif (is_array($file['name'])) {//说明是三维数组
                foreach ($file['name'] as $k => $v) {
                    $result[$i]['name'] = $file['name'][$k];
                    $result[$i]['type'] = $file['type'][$k];
                    $result[$i]['tmp_name'] = $file['tmp_name'][$k];
                    $result[$i]['size'] = $file['size'][$k];
                    $result[$i]['error'] = $file['error'][$k];
                    $i++;
                }
            }
        }
        return $result;
    }
}
复制代码

8.使用:两行代码搞定
<?php
use file\Uploader;
require "../lib/file/Uploader.php";

$uploader = new Uploader("G:/a/d/f/g");
$uploader->uploadFile();
复制代码

OK ,第一次接触PHP,感觉还好吧,个人感觉和python有点像,很多东西都是函数调用
而不是像Java,Kotlin等用对象的api来操作,所以感觉函数多起来,挺乱的。
PHP和JavaScript怎么说呢,感觉侧重点不同,谁好谁坏的说不清,各有千秋吧。
语言都类似,基本模块都差不多,关键还是看能不能玩转起来,不吹不黑,PHP还不错。


后记:捷文规范
1.本文成长记录及勘误表
项目源码日期附录
V0.1--无2018-3-14

发布名:编程语言对比手册(横向版)[-PHP-]
捷文链接:juejin.im/post/5c8a19…

2.更多关于我
笔名QQ微信
张风捷特烈1981462002zdl1994328

我的github:github.com/toly1994328
我的简书:www.jianshu.com/u/e4e52c116…
我的简书:www.jianshu.com/u/e4e52c116…
个人网站:www.toly1994.com

3.声明

1----本文由张风捷特烈原创,转载请注明
2----欢迎广大编程爱好者共同交流
3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正
4----看到这里,我在此感谢你的喜欢与支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值