💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] ## **echo、print、print_r、var_dump 区别** `echo`和`print`是语言结构、`print_r`和`var_dump`是普通函数。 * **echo**:输出一个或多个字符串 * **print**:输出字符串 * **print_r**:打印关于变量的易于理解的信息 * **var_dump**:打印关于变量的易于理解的信息(带类型) ## **单引号和双引号的区别** 双引号可以被分析器解析,单引号不行。 ## **isset 和 empty 的区别** * **isset**:检测变量是否已设置并且不为 Null * **empty**:判断变量是否为空。 以下全部认为是空的: * "" (空字符串) * 0 (作为整数的0) * 0.0 (作为浮点数的0) * "0" (作为字符串的0) * null * false * array() (一个空数组) * $var; (一个声明了,但是没有值的变量) ## **static、self、$this的区别** * static:可以用于静态或者非静态方法中,也可以访问类的静态属性,静态方法,常量和非静态方法,但不能访问非静态属性 * self:可以用于访问类的静态属性,静态方法和常量,但self 指向的是当前定义所在的类,这是 self 的限制。 * $this:指向的是实际调用时的对象。实际运行过程中,谁调用了类的属性或方法,$this 指向哪个对象。但 $this 不能访问类的静态属性和常量,且 $this 不能存在于静态方法中 ## **include、require、include_once、require_once 的区别** `include` 表达式包含并运行指定文件。 `require` 和 `include` 几乎完全一样,除了处理失败的方式不同。 `require` 在出错是产生 **E_COMPILE_ERROR** 级别的错误,将导致脚本终止。`include`产生警告(**E_WARNIMG**),脚本继续运行。 `include_once` 和 `include` 语句类似,唯一区别是如果该文件中已经被包含过,则不会再次包含,且 `include_once` 会返回 true。 顾名思义,`require_once`,文件仅仅包含(`require`)一次。 ## **Cookie 和 Session** Cookie:PHP 透明的支持 HTTP cookie。 cookie 是一种远程浏览器端存储数据并以此来跟踪和识别用户的机制 Session:会话机制(session)在 PHP 中用于保持用户连续访问web应用时的相关数据 ## **魔术方法** * `__construct()` - 在每次创建新对象时先调用此方法 * `__destruct()` - 在到某个对象的所有引用都被删除或者当对象被显式销毁时执行 * `__call()` - 在对象中调用一个不可访问方法时被调用 * `__callStatic()` - 在静态上下文中调用一个不可访问方法时被调用 * `__get()` - 读取不可访问(protected 或 private)或不存在的属性的值时被调用 * `__set()` - 在给不可访问(protected 或 private)或不存在的属性赋值时被调用 * `__isset()` - 当对不可访问(protected 或 private)或不存在的属性调用 `isset()` 或 `empty()` 时被调用 * ` __unset()` - 当对不可访问(protected 或 private)或不存在的属性调用 `unset()` 时被调用 * `__sleep()` - `serialize() `函数会检查类中是否存在一个魔术方法 `__sleep()`。如果存在,该方法会先被调用 * `__wakeup()` - `unserialize()` 会检查是否存在一个 `__wakeup()` 方法。如果存在,该方法会先被调用 * `__toString()` - 一个类被当成字符串时的回应 * `__invoke() ` - 当尝试以调用函数的方式调用一个对象时被调用 > 除了 `__construct()`, `__destruct()` ,和 `__clone()` 之外的所有魔术方法都 必须 声明为 **public**, 否则会发出 **E_WARNING** ## **public、protected、private、final 区别** 对属性或方法的访问控制,是通过在前面添加关键字 **public(公有)**,**protected(受保护)**或 **private(私有)**来实现的。被定义为公有的类成员可以在任何地方被访问。 PHP 5 新增了一个 **final** 关键字。**如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承** ## **类的静态调用和实例化调用** * 占用内存 静态方法在内存中只有一份,无论调用多少次,都是共用的 实例化不一样,每一个实例化是一个对象,在内存中是多个的 * 不同点 静态调用不需要实例化即可调用 静态方法不能调用非静态属性,因为非静态属性需要实例化后,存放在对象里 静态方法可以调用非静态方法,使用 `self `关键字。**php 里,一个方法被 `self::` 后,自动转变为静态方法** 调用类的静态函数时不会自动调用类的构造函数 ## **接口和抽象的区别** 抽象用于描述不同的事物,接口用于描述事物的行为。 ## **PHP 与 MySQL 连接的几种方式** ### **MySQLi** ```php // 创建一个连接诶 $conn = new mysqli('127.0.0.1:3306', 'root', '123456'); // 检查连接 if ($conn->connect_errno) { die($conn->connect_error . "\n"); } $conn->query("set names 'utf8';"); // 选择用于数据库查询的默认数据库 $select_db = $conn->select_db('user'); if (!$select_db) { die($conn->error . "\n"); } // 执行查询 $sql = "SELECT * FROM `user` LIMIT 1"; $res = $conn->query($sql); if (!$res) { die($conn->error . "\n"); } while ($row = $res->fetch_assoc()) { var_dump($row); } $res->free(); // 关闭连接 $conn->close(); ``` ### **PDO** ```php $pdo = new PDO('mysql:host=127.0.0.1:3306;dbname=user', 'root', '123456'); $pdo->exec("set names 'utf8'"); $sql = "SELECT * FROM `user` LIMIT 1"; $stmt = $pdo->prepare($sql); $stmt->bindValue(1, 1, PDO::PARAM_STR); $rs = $stmt->execute(); if ($rs) { while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { var_dump($row); } } $pdo = null; ``` ### **MySQLi、PDO 区别** 1. **连接** ~~~php // PDO $pdo = new PDO("mysql:host=localhost;dbname=database", 'username', 'password'); // mysqli, procedural way $mysqli = mysqli_connect('localhost','username','password','database'); // mysqli, object oriented way $mysqli = new mysqli('localhost','username','password','database'); ~~~ 2. **API支持** PDO 和 MySQL i都是通过面向对象的形式提供 API,但是同时**MySQLi也提供了面向过程的API**,这种形式对于新手来说更容易理解 3. **数据块支持** PDO比MySQLi最大的优点就是**PDO支持很多种数据库**,而MySQLi只支持MySQLi。 4. **命名参数支持** * PDO 参数绑定 ~~~php $params = array(':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600); $pdo->prepare(' SELECT * FROM users WHERE username = :username AND email = :email AND last_login > :last_login'); $pdo->execute($params); ~~~ * MySQLi 参数绑定 ~~~ $query = $mysqli->prepare(' SELECT * FROM users WHERE username = ? AND email = ? AND last_login > ?'); $query->bind_param('sss', 'test', $mail, time() - 3600); $query->execute(); ~~~ PDO是通过命名参数进行值的绑定,而MySQLi的参数绑定是通过点位符“?”并严格按这个问号的顺序来绑定值。 5. **对象映射(Object Mapping)** 基于数据库的开发一般都是从数据库中读取数据然后把这些数据用一个对象来承载。**PDO和MySQLi都支持对象映射** 6. **安全性** 二者**都可以防止sql注入** 7. **性能** 由于PDO能够支持其它非MySQL的数据库,而MySQLi专门针对MySQL设计的,所以MySQLi相对于PDO性能稍微好一些。 ## **PHP 代码执行过程** PHP 代码 => 启动 php 及 Zend 引擎,加载注册拓展模块 => 对代码进行词法/语法分析 => 编译成opcode(opcache) => 执行 opcode ## **主流 PHP 框架特点** ### Laravel 易于访问,功能强大,并提供大型,强大的应用程序所需的工具 - 简单快速的路由引擎 - 强大的依赖注入容器 - 富有表现力,直观的数据库 ORM - 提供数据库迁移功能 - 灵活的任务调度器 - 实时事件广播 ### ThinkPHP - 采用容器统一管理对象 - 支持 Facade - 更易用的路由 - 注解路由支持 - 路由跨域请求支持 - 验证类增强 - 配置和路由目录独立 - 取消系统常量 - 类库别名机制 - 模型和数据库增强 - 依赖注入完善 - 支持 PSR-3 日志规范 - 中间件支持 - 支持 Swoole/Workerman 运行 ## **串行、并行、并发的区别** * **串行**:执行多个任务时,各个任务按顺序执行,完成一个之后才能进行下一个 * **并行**:多个任务在同一时刻执行 * **并发**:同一时刻需要执行多个任务 - https://github.com/colinlet/PHP-Interview-QA#php-%E7%AF%87 - https://www.kancloud.cn/martist/be_new_friends/1704834