5

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

 2 years ago
source link: https://foofish.net/php-tutorial.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

因为某些原因需要临时接手一个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

%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20220409175431.png

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

php -S localhost:9000

企业微信截图_20220328175311.png

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

%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20220328175433.png

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 快速写入内容到文件, 文件不存在则创建
  • fopen 打开文件,可指定读写模式
  • fwrite 写入内容
  • fread 读内容
  • feof 判断是否读完文件
  • fclose 关闭文件
  • unlink 删除文件
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是一致的.

  • public 在类外面可以访问
  • protected 在继承类中可访问
  • private 在类内部可见
  • var 定义的属性是为了兼容PHP4的写法, 也等同于 public .

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

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之禅

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK