写给Python程序员的PHP快速入门教程

By 刘志军 , 2022-04-11, 分类: php

php

因为某些原因需要临时接手一个PHP项目,所以决定花点时间学习下PHP,对有其它语言编程经验的人来说来,上手还是很顺的。如果你也刚好在学PHP,希望本文对你有帮助。

安装Laragon

如果你是Windows系统,推荐用Laragon来搭建PHP开发环境。它集成了 Nginx/Apache、MySQL、Redis、Putty 等工具, 下载地址:https://laragon.org/download/ ,直接用laragon,会省去很多麻烦。

安装 PHPStorm

PHPStorm是Jetebrain旗下的IDE,与Pycharm类似,但没有社区版,不过可免费试用一个月。 下载地址:https://www.jetbrains.com/zh-cn/phpstorm/

hello world

//hello.php
<?php
echo "hello world";

php 文件第一行都是以 <?php 开头,估计是想告诉编译器,这是一个php文件。

运行

PHP运行方式有两种,一种是直接在命令行中执行

php hello.php

还有一种启动一个web服务器,通过浏览器访问该文件。通过cmder(cmder已经集成在Laragon中)进入hello.php所在目录, 执行

php -S localhost:9000

企业微信截图_20220328175311.png

浏览器访问 localhost:9000/hello.php 或者直接在PHPStorm选择浏览器运行

html 与 php

html 中可以集成php代码, 只需要把php代码用 <?php xxx ?> 包裹起来。把文件后缀改为php。解释器去自动去解释执行PHP代码。

<html>
<body>
<h1>
    hello PHP
</h1>
<h2>
    <?php echo "hello world 2"; ?>
</h2>
</body>
</html>

变量

php 的变量都是以 $ 开头,看来PHP之父当初写这门语言的时候比较穷 例如:

$hello = "hello";
$num = 123;

注意,PHP和Python一样,都是动态语言,定义变量无需指定类型。 与Python不同的是,PHP的变量的值还可以做变量名来使用。举个例子

$key = "name";
$name = "zhangsan";

echo $$key  //zhangsan

php语句都需要一个分号“;”表示结尾。

常量

python语法上没有所谓的常量概念,但是PHP从语法就支持常量,所谓常量就是你给这个特殊的“变量”指定了值之后,就不能再被改变。

定义常量方式有两种:

方式一:通过define函数定义常量

<? php
define("AUTHOR", "张三");
echo AUTHOR;

常量的访问前面带美元符号$

方式二:通过关键字 const 定义

const NAME = "张三";

字符串

单引号与双引号字符串的区别, 双引号可以解析变量,单引号不会对字符做任何处理,包括转义字符也是原样显示,看例子

$num =2;

echo "$num is number";
echo '$num is number'

输出

2 is number
$num is number

判断变量是否为字符串可以用函数is_string($name)来判断,返回值是bool类型。

常用的基本类型还包括整型、布尔类型、浮点型。 可以通过函数var_dump查看变量的数据类型。

<?php

$name = "zhangsan";
$num = 1;
$value = 12.2;
$is_ok = true;

echo(var_dump($name));
echo(var_dump($num));
echo(var_dump($value));
echo(var_dump($is_ok));

输出

string(8) "zhangsan"
int(1)
float(12.2)
bool(true)

数据类型转化

不同类型之间的转换只需要再变量前加上(目标类型),即可强制转换,例如:

$num = "123";
$num = (int)$num;
echo var_dump($num) . PHP_EOL;

输出

int(123)

如果将一个非数字字符串转换为int类型,会怎样呢? 不会报错,而是直接转换为0。这和python有很大的区别。

数组

PHP数组和Python一样,无需声明长度,初始化后就可以直接添加元素,不限制元素类型。

<?php

$nums = [1,2,3,4, 5, "6"];

print_r($nums);

输出

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
)

追加元素

$nums[] = 7;

获取元素

通过下标索引获取

echo $nums[1];

删除元素

删除元素使用函数unset()

<?php

$nums = [1,2,3,4, 5, "6"];
$nums[] = 7;

# 删除第0个元素
unset($nums[0]);

print_r($nums);

var_dump($nums[0]);

输出

Array                                                                                      
(                                                                                          
    [1] => 2                                                                               
    [2] => 3                                                                               
    [3] => 4                                                                               
    [4] => 5                                                                               
    [5] => 6                                                                               
    [6] => 7                                                                               
)                                                                                          

Notice: Undefined offset: 0 in C:\Users\lzjun\workspace\phphello\hello.php on line 10      
NULL                                                                                       

元素删除后,该值所在的位置依然还在,只不过这个值为NULL,后面的元素并不会前移。 但是通过函数count()获取数组长度时,被删除的元素并不会统计进来。也就是说长度会减1, 感觉很乱是不是。

这时候可以通过 array_values()函数重新编排,该函数会把NULL的元素移除掉,返回一个新数组

<?php

$nums = [1,2,3,4, 5, "6"];
$nums[] = 7;
unset($nums[0]);

print_r(array_values($nums));

输出

Array
(
    [0] => 2
    [1] => 3
    [2] => 4
    [3] => 5
    [4] => 6
    [5] => 7
)

unset整个数组后,整个数组被删除,该变量也不存在

unset($nums)

print_r($nums)

Notice: Undefined variable: new_nums in C:\Users\lzjun\workspace\phphello\hello2.php on line 46

PHP没有字典类型
PHP没有字典类型
PHP没有字典类型

关联数组

PHP虽然没有字典结构,其实,数组本质上也是字典结构,只不过key是数组的下标索引而已。 而PHP中数组的索引也可以是字符串,这就变相的实现了字典结构。

关联数组通过符号=> 关联 Key-Value

$books = [
    'name' => "PHP之禅",
    'pages' => 100,
    'price' => 200
];
print_r($books)
echo $books['name'] . PHP_EOL;

输出

Array
(
    [name] => PHP之禅
    [pages] => 100
    [price] => 200
)
PHP之禅

数组与关联数组二者还可以混用,在没有指定key时,PHP会自动维护一个Key,就是数组的数字下标索引。

$books = [
    'name' => "PHP之禅",
    'pages' => 100,
    'price' => 200,
    "PHP太逗了",
    "PHP是世界上最好的语言"
];

print_r($books);

输出

Array
(
    [name] => PHP之禅
    [pages] => 100
    [price] => 200
    [0] => PHP太逗了
    [1] => PHP是世界上最好的语言
)

比较操作符

$a == $b  //类型转换后相等
$a === $b // 类型转换前相等
$a !== $b // 类型不相等或者转换后值不相等

switch 语句

PHP支持switch语句

$a = 4;
switch($a){
    case 4:
        echo(1);
        break;
    case $a>20:
        echo(2);
        break;
    default:
        echo("3");
}

case里面一定要有break,否则case后面的语句全部会执行,直到遇到第一个break

foreach 语句

foreach适合用来迭代关联数组, 当然对于普通数组可支持用foreach

foreach($books as $key=>$value){
    echo $key, ":" , $value, "\n";
}

输出

name:PHP之禅
pages:100
price:200
0:PHP太逗了
1:PHP是世界上最好的语言

函数

函数用关键字function来定义

function add($a, $b){
    return $a+$b;
}

PHP7开始, 也像Python一样,支持对参数和返回值指定数据类型,

function add2(int $a, int $b):int{
    return $a+$b;
}

echo add2(3,3) . PHP_EOL;   //6
echo add2(3.4, 4.9) . PHP_EOL;  // 7
echo add2(3.4, "4.9") . PHP_EOL;  // 7

传入参数时,会强制转换为对应的类型,如果转换失败就会报错。

函数参数传递

参数的传递本质上都是值传递

function add3(int $a, int $b):int{
    $a = $a+$b;
    return $a;
}


$a = 3;
$b = 4;
echo add3($a,$b) . PHP_EOL;
echo $a . PHP_EOL;

输出:

7
3

调用add3($a,$b)时,传递的是$a的拷贝值, 函数外的变量 $a 并不会受影响。 除了直接传值之外,也可以传引用

function add4(int &$a, int $b):int{
    $a+=$b;
    return $a;
}


$a = 3;
$b = 4;
echo add4($a,$b) . PHP_EOL;
echo $a . PHP_EOL;

输出:

7
7

&表示传引用,相当于你传过去的是$a对应的内存地址,开始该地址对应的值是3, 函数处理后,改地址的值被改为了7。

数组排序

升序:sort
降序: rsort

$nums = [9, 1, 2, 3, 4, 5, "6"];

print_r($nums);
sort($nums);
print_r($nums);

输出

(
    [0] => 9
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => 5
    [6] => 6
)
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => 9
)

排序函数直接在数组上进行操作,因为原数组的顺序会发生改变。函数的返回值是bool。

文件读写函数

file_put_contents("hello.txt", "nihao ,php");

$file = fopen("hello.txt", 'aw');

fwrite($file, "php最好");
fclose($file);

$file = fopen("hello.txt", "r");
while (!feof($file)){
    $content = fread($file, 10);
    echo $content, "\n";
}
fclose($file);

unlink("hello.txt")

面向对象:类

class Car
{

    const WHEEL = 4;
    var $seat;
    var $door;
    var $engine;
    var $brand;

    // 构造方法
    public function __construct($seat, $door, $engine, $brand)
    {
        $this->seat = $seat;
        $this->door = $door;
        $this->engine = $engine;
        $this->brand = $brand;
    }

public function drive()
{
    echo "启动" . PHP_EOL;
}
}

// 实例化
$car = new Car();

// 调用公有方法
$car->driver();

// 访问常量
Car::WHEEL;



// 继承

class Benz extends Car
{
    public __construct($door)
    {
        $this->brand='benz'
        parent::__construct($door, $this->brand);
    }
}

常量访问使用 类名::,例如:Car::WHEEL

访问对象的属性和方法通过->符号, 属性的访问需要先赋值

class Car{
    var  $brand;
    const ENGINE='oil';
}

$car = new Car();

$car->brand=4;
var_dump($car->brand);

PHP中没有方法重载这一说,比如构造函数

class Car{
    var  $brand;
    var $seat;
    const ENGINE='oil';

    /**
     * @param $brand
     * @param $seat
     */
    public function __construct($brand, $seat)
    {
        $this->brand = $brand;
        $this->seat = $seat;
    }
}

只能定义一个构造函数,不像Java,可根据不同的参数和返回值构造多个同名不同参的方法.

类的访问控制

属性和方法可以通过public\ protected \ private 来修饰, 他们的可见范围和java是一致的.

私有方法只能在内里面使用,类外面不可访问, 但是可以通过反射进行访问

反射

class Bmw extends Car
{
    private function somking()
    {
        echo 'driver is smoking'
    }
}

$method = new RefelctionMethod(Bmw::class, "somking");
$method->setAccessible(true);
$bmw = new Bmw();
$method->invoke($bmw);

抽象类

abstract class Car{
    abstract public function drive();
}

class Byd extends Car
{
    public  function drive()
    {
        echo "drive at 100km/h";
    }
}

接口

接口中的方法必须都是公有的,顾名思义,不是公有的,怎么被实现类来访问实现呢。

interface Car
{
    public function drive();
}

Trait

Trait 是PHP独有的概念, 在其它语言中并没有找到类似的概念,这是一种全新的代码复用思想,Trait 的中文意思是"特点,特征". Trait 和 类相似,可以定义属性和方法.但是不支持构造方法(也不能被实例化), 只能给其它类来使用. 算是给别人做嫁衣的. 在类中使用 Trait 可以使用关键字use来引入, 引入了 Trait 的类, 等于完全拥有了Trait的属性和方法.

通过Trait 可以解决PHP中多继承问题, 因为在一个类中,可以 use 多个Trait.

<?php

trait Hand{
    private $num;

    public function clap(){
        echo "鼓掌\n";
    }
}

trait Leg{
    private $num;
    public function run(){
        echo "running\n";
    }
}

class Person{
    use Hand;
    use Leg;

    public function sleep(){
        echo "sleeping..\n";
    }
}

$person = new Person();
$person->clap();
$person->run();
$person->sleep();

这里我定义了一个Person类,两个Trait, 分别是 Hand 和 Leg, 被 Person使用, 相当于 Person 同时继承了这两个Trait的数据.

异常与错误

参考教程:https://laravelacademy.org/post/21614


关注公众号「Python之禅」,回复「1024」免费获取Python资源

python之禅