php/3.Basic at master · LWM108/php · GitHub
Skip to content

Latest commit

 

History

History
 
 

README.org

变量/作用域/类型系统

变量

在 php 中,变量必须以 $ 开始,这样做有下面好处:

  1. 所有的变量都是 $ 开始的话,那么非常容易分析源码,所以,能够简化编译器的实现。
  2. 因为所有变量都是 $ 开始,所以,解析起来非常 easy,能够减少解析的时间,提高解析的效率。
  3. 我们所有看代码的人,看到 $ 符号,就知道,这是个变量,所以,能够减少我们看代码的大脑消耗,也就是易阅读。
  4. 所以,php 又有一个名字,叫面向美元编程的语言,无形增加了大家对 php 的喜爱还有追求。
  5. 可以非常方便把变量嵌入到字符串中,即所谓的模板字符串。
  6. 其实,这些玩意,是从 perl 还有 shell 编程中借鉴的。
# // /* */ 注释有很多种,可以是 shell 格式的注释,也可以是 c 格式的注释,特别自由。

# php 中,变量是大小写敏感的
$yourname = "kitty";
yourname = "kitty";   // error!
$yourName = "Kitty";
$变量a = "hahaha";

// 跟变量相关的一些函数
isset();    // 测试变量是否已经被定义
unset();    // 将一个变量定义删除掉
gettype();  // 获取一个变量的数据类型
is_int();   // 判断一个变量是否为 int 类型
empty();    // 判断一个变量是否为空,0/null/[]/false/"" 等等
var_dump(); // 打印变量的类型
var_export();

常量

定义之后就不会发生变化的量

define("COUNTRY", "中华人民共和国");
define("COUNTRY", "朝鲜");  // 再次定义是无效的
echo COUNTRY;  ## 中华人民共和国

几个特殊的常量:

__LINE__/__DIR__/__FILE__/PHP_VERSION/PHP__MAJOR__VERSION

作用域(Scope)

在 php 中,有三种作用域:

  1. Global, 全局作用域
  2. Local, 函数内部作用域
  3. Static, 静态作用域
  4. 超级全局作用域
    • $_GET
    • $_POST
    • $_FILES
    • $_REQUEST
    • $_COOKIE
    • $_SESSION
    • $_SERVER
    • $_ENV

int/float/bool/resource/null

int/float 分别代表整数和浮点数。

bool 类型有两个值, 分别是 true/false,用来做逻辑判断

resource 代表打开的文件或数据库等资源。 打开的文件会自动释放,不需要我们手动关闭。 但是,数据库还是需要我们自己手动释放的。

null 表示空。

String

函数列表:

http://www.w3school.com.cn/php/php_ref_string.asp

// 有三种写法:
// 1. 使用双引号引起来的写法
// 2. 使用单引号引起来的写法
// 3. HEREDOC 方式的写法


// 比较重要的函数:
strstr()/substr()/strpos()/strlen();
md5()/...();

Array

PHP 中最核心的数据库类型,号称 万能的数组

数组分为三种:

  1. 索引数组,即以数字为下标
  2. 关联数组,即以字符串为下标
  3. 多维数组,数组里有数组

使用关键词 array() 初始化一个数组:

$cars = array();

// 所谓的索引数组
$cars = array("宝马", "奔驰", "奥迪");
$cars = array(0 => "宝马", 1 => "奔驰", 2 => "奥迪");

echo "我有很多车,比如,我有一辆" . $cars[0];
var_dump($cars);

// 所谓的关联数组
$car = array("name" => "宝马", "price" => 888898);
echo "我有一辆车,它的品牌叫" . $car["name"];

// 所谓的多维数组
$cars = array(
    array("name" => "宝马", "price" => 888898),
    array("name" => "奔驰", "price" => 688898),
    array("name" => "奥迪", "price" => 678898)
);

// 从 php 5.x 开始,初始化数组的语句可以简化为
$cars = [
    ["name" => "宝马", "price" => 888898],
    ["name" => "奔驰", "price" => 688898],
    ["name" => "奥迪", "price" => 678898]
];
print_r($cars);

数组相关的函数们,你们好啊! http://www.w3school.com.cn/php/php_ref_array.asp

问题:

1. INF 是什么意思
2. PHP 中能够表现的最大数字是多少
3. 如何在 PHP 中输出 1x2x3...x9999x10000 的结果

控制流程

条件判断:

  • if 语句,如果条件为真,那么执行代码
  • if..else,如果条件威震,执行代码,否则,执行 else 里的代码
  • if..elseif..else,根据条件,选择某个分支的代码来执行
  • switch 语句,是上面多分支选择方式的另一种写法,更加简洁

循环迭代:

  • while,只要条件为真,就一直执行
  • do..while,先执行一次,后面判断条件。只要条件为真,就一直执行
  • for,循环代码块执行次数
  • foreach,遍历数组中的每个元素

包含/加载:

  • include
  • include_once
  • require
  • require_once

函数

php 真正的力量来自于其数不清的函数。除了使用自定义的函数,我们也可以自定义函数。

常用函数:

function_exists("some_fun");  // 检查某个函数是否被定义

// 所有以 get 开始的函数们,你们好吗?
get_declared_classes/interfaces/traints(); // 显示所有
get_defined_vars/contants/functions();     // 显示所有
get_included_files();
get_loaded_extensions();
get_head/getallheaders();
getcwd/getenv/getdate/gethostbyname...();

// call_user_func/call_user_func_array()
// 动态调用函数,相当于 eval, 免去了 new 对象过程
class A { function b($name) {} }
call_user_func_array(['A', 'b'], ['jerry']);

自定义函数

// 定义函数
function sayHello($name) {
    echo "Hello $name!";
}
// 调用函数
sayHello("TOM");  # Hello Tom!

// 可以使用默认参数
function double($n = 1) {
    $res = $n * 2;
    echo "Double of $n is $res.";
    return $res;
}
$r = double();
$r = double(222);

输出函数

有很多,比如:

  • echo/print
  • print_r
  • var_export/var_dump
  • printf/sprintf

简单示例:

# echo, print 用于输出字符串
# 它们是语句不是函数,可以不带括号调用
# 区别: echo 可带多参数,print 有返回值
echo("go");
echo "go", "go";

# print_r 是函数,可输出复杂对象
# 如果第二个参数为 true,那么不打印,只返回字符串
print_r($arr);
$ret = print_r($str, true);

# printf/sprintf 用来格式化字符串
# 不过,前者为了打印,后者为了返回
printf("String: %s", "a demo string");

# var_export/var_dump 用来显示变量情况
var_export($v);

文件操作

简单示例:

// demo file
$filename = "e:/xxx.txt";

// open -> operate -> close
@$myfile = fopen($filename, "r") or die("unable to open file");
echo fread($myfile, filesize($filename));
fclose($myfile);

// 读取文件并显示到页面
// readFile 也可以用来下载
$content = readFile($filename);

// 读取文件到数组/字符串
$arr = file($filename);
$str = file_get_content($filename); // file_set_content();

// 其他很多,比如 feof/fgetc/fgets/fwrite/scandir 等

日期函数

使用日期前需要先设置时区,要么代码中设定,要么 php.ini 中设置:

date_default_timezone_set('Asia/Shanghai');
ini_set('date.timezone','PRC');

常用日期函数有:

  • mktime(hour,minute,second,month,day,year) 创建时间
  • date(format, timestamp) 获取时间
  • time() 获取时间,整数

format:

  • d - 表示月里的某天(01-31)
  • m - 表示月(01-12)
  • Y - 表示年(四位数)
  • 1 - 表示周里的某天
  • h - 带有首位零的 12 小时小时格式
  • i - 带有首位零的分钟
  • s - 带有首位零的秒(00 -59)
  • a - 小写的午前和午后(am 或 pm)

示例:

date_default_timezone_set("Asia/Shanghai");
echo "今天是 " . date("Y/m/d") . "<br>";
echo "现在时间是 " . date("H:i:s");

另外,请大家自行研究 DateTime 类的使用。

更改日期函数: http://www.w3school.com.cn/php/php_ref_date.asp

上传下载

使用 CURL 扩展进行上传下载,需要打开 php_curl.dll 插件支持:

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://image.baicai.me/pic.html');
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $fileds);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_close($curl);

如果觉得 Curl 难用,请使用 Guzzle 模块。首先需要向项目中添加模块:

composer require guzzlehttp/guzzle

Guzzle 示例:

$url = 'https://www.qiushibaike.com/';
$client = new Client();

# get/post/...
$reponse = $client->get($url);
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);

# aync request
$promise = $client->getAsync('http://httpbin.org/get');
$promise->then(
    function (ResponseInterface $res) {
        echo $res->getStatusCode() . "\n";
    },
    function (RequestException $e) {
        echo $e->getMessage() . "\n";
        echo $e->getRequest()->getMethod();
    }
);

面向对象(OOP)

命名空间

命名空间是为了防止类名冲突。

student.php, 定义:

// 定义文件中的命名空间
namespace aaa\bbb;
class Student {}  // 所以,这个类的全名是 aaa\bbb\Student

index.php, 使用

require "student.php";
// 使用类的全名调用相关类
new \aaa\bbb\Student();
// 或者
use aaa\bbb\Student;
new Student();

异常处理

首先, PHP 默认是轻异常的语言。

如果出错,除非非常严重,都会继续执行。

错误信息,会在页面上显示出来。

可以定制什么样的错误会被显示:

  • 通过修改 ini 文件中的 error_reporting
  • 在 php 中执行函数 error_reporting

也可以通过 @ 符号,去抑制错误信息。

你也可以定制,出现错误后如何处理:

function error_rep($errno, $errstr) {
    echo "<br>出现了一个不应该出现的错误 hahaha";
}
set_error_handler(error_rep);

php5 提供了一种面向对象的错误处理方式,也就是异常。变成了重异常的机制:

// 使用示例
try {
    throw new Exception("description");
} catch (Exception $e) {
    echo "error: " . $e->getMessage();
}

// 可以通过注册默认处理器的方式,处理未捕获异常
set_exception_handler(function ($e) {
    // 写我们的异常处理方式
    // 1. 显示什么给用户
    // 2. 跳转到什么页面
    // 3. 将相关错误日志保存到文件或数据库
    // 4. 其他
}

Web

1. 获取参数

_GET/_POST/_FILES

2. 数据验证

  1. 使用 empty/length 等进行简单校验
  2. 使用正则表达式进行通用校验(preg_match 等)
  3. 使用内置的校验函数 filter_var/filter_input 等进行快速校验

3. 响应数据

通过 echo 将字符串返回给客户端。

使用 header 设置响应的头部,或者完成页面跳转:

# 设置返回格式还有字符集
header("Content-Type: text/html;charset=UTF-8");

# 页面重定向
header("Location: http://www.bing.com");

cookie

_COOKIE
setcookie($name, $value, $expired);

session

session 必须先要开启才能使用:

# 开启,需要写在最前面
session_start();
# 状态
session_status();
# 销毁
session_destroy();

Database

在 php5 之前,推荐使用的方式是例如 php_mysql.dll/php_psql.dll 等原生驱动。

比如, php_mysql.dll 的语法如下:

// 首先,设置页面编码
header("Content-Type: text/html; charset=UTF8");

// 其次,建立数据库连接
$conn = mysql_connect("localhost", "root", "root") or die("数据库连接失败");

// 创建数据库
if(mysql_query("create database xxx", $con)) {
    echo "创建数据库成功。";
} else {
    echo "创建数据库失败:" . mysql_error() . "<br>";
}

// 切换到数据库
mysql_select_db("xxx") or dir("打卡数据库失败。");

// 设置 utf8 编码
mysql_query("select names utf8");

// 创建表
$sql = "create table person
(
  id int primary key auto_increment,
  name varchar(20) not null,
  salary float default 1500
)
";
mysql_query($sql);

// 插入数据
mysql_query("insert into person (name, salary) values ('张飞', 3333)");
mysql_query("insert into person (name, salary) values ('关羽', 3334)");

// 查询数据
// 返回结果是:万能的数组
$res = mysql_query("select * from person");

// 显示数据,使用 foreach 循环
echo "<table>\n";
foreach($res as $r) {
    echo "  <tr><td>$r[name]</td><td>$r[salary]</td></tr>\n";
}
echo "\n</table>";

// 最后,释放连接
mysql_close($conn);

因为 mysql 插件有很多问题,所以,后来出现了 php_mysqli.dll 插件,其中 i 代表 improvement(改进/升级) 的意思,对连接数据库的效率及安全性进行了大量优化。

mysqli 插件除了完全兼容 mysql 的语法之外,还支持用 oo 的方式连接数据库:

// 连接数据库
$conn = new mysqli("localhost", "root", "root", "text");
$conn -> query("set names utf8");

// 查询
$sql = $conn->query("select * from person");

// 获取结果
$res = $conn->fetch_array(MYSQLI_ASSOC);

// 显示结果
echo "<table>\n";
echo "<tr><td>" . $res['name'] . "</td><td>" . $res['salary'] . "</td></tr><br>";
echo "</table>";

虽然 mysqli 插件已经非常好用。但是…

php 能连接的数据库可不止 mysql 啊,还有 oracle/sqlserver/postgres/sqlite 等,每个数据库都有自己的插件,都有自己的语法…所以后来,PHP 推出了自己的连接数据库的标准, 即 PDO(PHP Data Object) 接口,对数据库的连接进行了规范。所以,采用 DPO 的所有数据库,语法得到了统一。

http://php.net/manual/zh/book.pdo.php

请首选 PDO 进行数据库操作:

// 连接数据库
$pdo = new PDO("mysql:host=localhost;dbname=test", "root", "root", "test");

// 操作数据库n
$pdo->exec("set names utf8");
$pdo->exec("create table person ...") or die("创建失败");
$pdo->exec("insert into  person ...") echo and ("插入成功");

// query
$st = $pdo->query("select xxx from yyy");
$rows =  $st->fetch(PDO::FETCH_ASSOC);
print_r($rows);

// 使用 Prepare 的方式进行操作
$stmt = $pdo->prepare("select name from person where id = :id");
$stmt->bindParam(":id", $xxx, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($rows);

// 释放链接
$pdo = null;

问题:

什么是 SQLITE?
怎么使用 PHP 操作 SQLITE 数据库。

ThinkPHP