HTML
inline and block
🧱 Block(块级元素)
块级元素有点像“独占一行的大盒子”,一上场就要把整行空间占下来。
特点:
- 独占一行(上下会自动换行)
- 默认宽度是 100% 父容器宽度
- 可以设置 宽、高、margin、padding
- 常见元素:
div、p、h1~h6、ul、ol、li、header、section等
常见的 block 元素:
divph1~h6ul,olliheaderfootersectionarticlenavasidemaintable(注意:它是个特别的 block-level 元素)formblockquoteprehr
📝 Inline(行内元素)
行内元素更像“跟文字混在一起的小伙伴”,不会独占一行,排队躺在同一行里。
特点:
- 不会换行,宽度由内容决定
- 不能设置宽高
padding和margin只能左右有效,上下很有限- 常见元素:
span、a、strong、em、img*(注意:img是 inline-level 但能设置宽高)
常见的 inline 元素:
spanastrongembiusmallsub,supbrcodelabelimg(注意:inline-level,但能设宽高)
CSS
选择器
child: main > h2
descendent: main h2
外部引入
<link rel="stylesheet" href="style.css">
rel="stylesheet" → 告诉浏览器这是样式表
href="style.css" → 指向你的 CSS 文件路径
JS
var and let
🟡 1. 作用域(Scope)不一样
var → 函数作用域(function scope)
if (true) {
var a = 1;
}
console.log(a); // 1 ← 能访问let → 块级作用域(block scope)
在 {} 区域外就访问不了。
if (true) {
let b = 2;
}
console.log(b); // ❌ 报错:b is not defined简单记:let 更安全,变量不会乱飞。🟣 2. var 允许重复声明,let 不行
var x = 1;
var x = 2; // OK
let y = 1;
let y = 2; // ❌ 报错let 强制你别瞎重名,避免 bug。外部引入
<!-- 推荐:放在 body 底部,页面先渲染再加载 JS -->
<script src="main.js"></script>Object
对象就是一组“键值对”的集合。
键(key)是名字,值(value)可以是任何东西:数字、字符串、数组、函数都行。
key可以不加引号!但是如果非法变量名就一定要加引号
const person = {
name: "Alice",
age: 18,
isStudent: true
};对象里放函数时,它就叫“方法”:
const person = {
name: "Alice",
sayHi: function() {
console.log("Hi!");
}
};
person.sayHi(); // "Hi!"
使用对象的另一种方式:通过构造函数或 class
function Person(name, age) {
this.name = name;
this.age = age;
}
const p = new Person("Alice", 18);
遍历对象属性
for (let key in person) {
console.log(key, person[key]);
}
数组
const arr = ["a", "b", "c"];它内部更像这样:
{
"0": "a",
"1": "b",
"2": "c",
length: 3
}➕ 添加元素
arr.push(4); // 尾部添加
arr.unshift(0); // 头部添加➖ 删除
arr.pop(); // 删除最后一个
arr.shift(); // 删除第一个长度
arr.length // 自动更新forEach(遍历做事)
arr.forEach(item => console.log(item));map(返回一个“新数组”)
const doubled = arr.map(x => x * 2);for循环
for (let i = 0; i < 5; i++) {
console.log(i);
}
遍历数组:for…of(最推荐)
const arr = ["a", "b", "c"];
for (const item of arr) {
console.log(item);
}
注意:for…in 是遍历对象的属性名,不能用于数组!
const obj = { name: "Tom", age: 20 };
for (const key in obj) {
console.log(key, obj[key]);
}
// name Tom
// age 20XHR
// 1. 创建 XHR 对象
const xhr = new XMLHttpRequest();
// 2. 配置请求:方法 + URL
xhr.open("GET", "data.json", true); // true = 异步
// 3. 监听请求完成
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log("响应内容:", xhr.responseText);
}
};
// 4. 发送请求
xhr.send();💛 接收 JSON(常用)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
console.log(data.name);
}
};PHP
变量
PHP 是弱类型语言
$name = "Alice";
$age = 20;
$isAdmin = true;
$score = 99.5;
$a = 10; // 数字
$a = "hi"; // 改成字符串也没事数组
索引数组(Index Array)
$nums = array(10, 20, 30);
$nums = [10, 20, 30];
echo $nums[0]; // 10关联数组(Associative Array)
$user = [
"name" => "Tom",
"age" => 18,
"city" => "Shanghai"
];
echo $user["name"]; // Tom添加元素
索引数组添加(自动编号)
$nums[] = 40;指定键添加
$user["gender"] = "male";循环
while
while ($i < 5) {
echo $i;
$i++;
}for
for ($i = 0; $i < 5; $i++) {
echo $i;
}foreach
$nums = [10, 20, 30];
foreach ($nums as $value) {
echo $value;
}
// 键值遍历
$user = [
"name" => "Tom",
"age" => 18
];
foreach ($user as $key => $value) {
echo "$key : $value <br>";
}函数
function 函数名(参数...) {
// 函数体
}
function sayHi() {
echo "Hello!";
}
sayHi();带参数
function add($a, $b) {
return $a + $b;
}
echo add(3, 5); // 8带默认值
function greet($name = "Guest") {
echo "Hello, $name!";
}
greet(); // Hello, Guest!
greet("Tom"); // Hello, Tom!返回值
function getAge() {
return 20;
}
$age = getAge(); // 20变量作用域:局部与全局
函数里的变量是 局部的:
$x = 10;
function test() {
$x = 5; // 局部变量
echo $x;
}
test(); // 5
echo $x; // 10
访问全局变量必须用 global
$x = 10;
function test() {
global $x;
echo $x; // 10
}
作用域
写在函数外的变量就是“全局变量”。
$x = 10; // 全局变量
function test() {
echo $x; // ❌ 直接用会报错
}⚠ 函数内部不能直接访问全局变量!
要访问必须写:global 关键字
$x = 10;
function test() {
global $x;
echo $x; // 10
}
function test1() {
echo $GLOBALS['x']; // 10
}
局部作用域
function demo() {
$a = 5;
echo $a; // 5
}
demo();
echo $a; // ❌ 不存在static
function counter() {
static $count = 0;
$count++;
echo $count;
}
counter(); // 1
counter(); // 2
counter(); // 3PHP常用函数
按 值 排序(索引数组常用)
升序:sort()
$arr = [3, 1, 5, 2];
sort($arr);
print_r($arr);
// [1, 2, 3, 5]降序:rsort()
$arr = [3, 1, 5, 2];
rsort($arr);
print_r($arr);
// [5, 3, 2, 1]按 键名 排序(关联数组常用)
升序:ksort()
ksort($arr);降序:krsort()
krsort($arr);按 值 排序但保留键名(关联数组常用)
升序:asort()
$arr = ["a" => 3, "b" => 1, "c" => 5];
asort($arr);
print_r($arr);
// ["b" => 1, "a" => 3, "c" => 5]降序:arsort()
arsort($arr);usort():按值自定义排序
$arr = ["apple", "kiwi", "banana"];
usort($arr, function($a, $b) {
return strlen($a) - strlen($b); // 按字符串长度升序
});
print_r($arr);
// ["kiwi", "apple", "banana"]常用计算
// 求和
$sum = array_sum($arr);
// 元素个数
$count = count($arr);
// 平均值
$avg = $sum / $count;
echo $avg; // 25数组去重
$arr = [1, 2, 2, 3, 3, 3, 4];
$result = array_unique($arr);
print_r($result);
// [1, 2, 3, 4]数组切片
✂️ 示例:从第 2 个元素开始取 3 个
$arr = [10, 20, 30, 40, 50];
$chunk = array_slice($arr, 1, 3);
print_r($chunk);
// [20, 30, 40]
array_slice($arr, -2);
// [40, 50]遍历打印并加间隔
$arr = [10, 20, 30, 40];
echo implode(",", $arr);
// 输出:10,20,30,40找子串
$pos = strpos("hello world", "world");
echo $pos; // 输出 6
// 不区分大小写:stripos()
$pos = stripos("Hello World", "world");
echo $pos; // 6substr_count() 不会重叠计数。
$str = "abababa";
$needle = "aba";
echo substr_count($str, $needle);
// 输出 2 (位置 0 和 4)字符串大小写
全部转成小写:strtolower()
$str = "Hello World";
echo strtolower($str);
// hello world全部转成大写:strtoupper()
echo strtoupper("Hello World");
// HELLO WORLD首字母大写:ucfirst()
echo ucfirst("hello world");
// Hello world每个单词首字母大写:ucwords()
echo ucwords("hello world");
// Hello World修改字符串
ltrim() 可以从字符串左边移除指定字符,刚好用它来干掉前导 0。
$str = "00012345";
echo ltrim($str, "0");
// 输出:12345计算日期间隔
<?php
$datetime1 = new DateTime("2012-06-01 02:12:51");
$datetime2 = new DateTime("2014-05-12 11:10:00");
// 计算差值
$interval = $datetime1->diff($datetime2);
// 输出
echo "Difference: "
. $interval->y . " years, "
. $interval->m . " months, "
. $interval->d . " days, "
. $interval->h . " hours, "
. $interval->i . " minutes, "
. $interval->s . " seconds.";
?>
Error and exception
Error handling
function customError($errno, $errstr) {
echo "<b>Error:</b> [$errno] $errstr<br>";
echo "Ending Script";
die();
}
set_error_handler("customError", E_USER_WARNING);
// 这行告诉 PHP:
// “当出现 E_USER_WARNING 这种级别的错误时,别用默认的报错方式,把错误交给 customError() 这个函数处理。”
$test = 2;
if ($test > 1) {
trigger_error("Value must be 1 or below", E_USER_WARNING);
}Exception handling
function checkNum($number) {
if($number > 1) {
throw new Exception("Value must be 1 or below");
}
return true;
}
try {
checkNum(2);
echo 'If you see this, the number is 1 or below';
}
catch(Exception $e) {
echo 'Message: ' . $e->getMessage();
}| 特点 | Error Handling(错误) | Exception Handling(异常) |
|---|---|---|
| 机制 | 基于 error 级别 | 基于 try/catch 面向对象 |
| 捕获方式 | set_error_handler | try{} catch(){} |
| 异常继续运行? | 通常终止脚本 | 只要 catch 住就能继续 |
| 适用场景 | 程序内部的普通警告/错误 | 业务逻辑、流程控制、严重异常 |
Form表单
更安全的post
<form action="welcome.php" method="post">
Name: <input type="text" name="name"><br>
E-mail: <input type="text" name="email"><br>
<input type="submit">
</form>action="welcome.php"
当用户点“submit”,浏览器会把表单数据发送到 welcome.php。
method="post"
表示用 POST 方法发送数据,而不是 GET。
php接收数据并且渲染:
Welcome <?php echo $_POST["name"]; ?><br>
Your email address is: <?php echo $_POST["email"]; ?>拼接url的get
<form action="welcome_get.php" method="get">
Name: <input type="text" name="name"><br>
E-mail: <input type="text" name="email"><br>
<input type="submit">
</form>
Welcome <?php echo $_GET["name"]; ?><br>
Your email address is: <?php echo $_GET["email"]; ?>$_SERVER["PHP_SELF"]
是 PHP 的一个超级全局变量,代表当前正在执行的脚本的文件名
表单会“自我提交”,提交回同一个文件。
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
避免危险,可以写 htmlspecialchars
<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>">检查提交方法
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = ($_POST["name"]);
$email = ($_POST["email"]);
$website = ($_POST["website"]);
$comment = ($_POST["comment"]);
$gender = ($_POST["gender"]);
}
// 确保是post表单验证
// 如果表单被提交
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 验证 name 是否为空
if (empty($_POST["name"])) {
$nameErr = "Name is required";
} else {
$name = htmlspecialchars($_POST["name"]);
}
// 验证 email 是否有效
if (empty($_POST["email"])) {
$emailErr = "Email is required";
} else {
$email = htmlspecialchars($_POST["email"]);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "Invalid email format";
}
}
}
?>表单对文本框的回填
<input type="text" name="name" value="<?php echo $name; ?>">
// 把用户之前输入的 $name 再放回输入框里。php for mysql
PDO和mysqli 都要掌握
mysql i
procedural: 函数式
<?php
$host = "localhost";
$user = "root";
$pass = "";
$dbname = "test";
$conn = mysqli_connect($host, $user, $pass, $dbname);
// dbname可以省略
if (!$conn) {
die("连接失败:" . mysqli_connect_error());
}
echo "连接成功";
?>
面向对象方式:
<?php
$host = "localhost";
$user = "root";
$pass = "";
$dbname = "test";
$conn = new mysqli($host, $user, $pass, $dbname);
// dbname 可以省略
// 检查是否连接成功
if ($conn->connect_error) {
die("连接失败:" . $conn->connect_error);
}
echo "连接成功!";
?>查询
$sql = "SELECT id, name, age FROM users";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "ID: {$row['id']} Name: {$row['name']} Age: {$row['age']} <br>";
}
} else {
echo "没有数据";
}
预处理语句
$stmt = $conn->prepare("INSERT INTO users (name, age) VALUES (?, ?)");
$stmt->bind_param("si", $name, $age);
$name = "Alice";
$age = 22;
$stmt->execute();
$stmt->close();
| 字母 | 类型 |
|---|---|
| s | string |
| i | integer |
| d | double |
| b | blob(二进制) |
PDO
PDO 是 PHP 官方提供的 统一数据库接口。可以连接 多种数据库(MySQL、SQLite、PostgreSQL...)
try {
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
// 设置 PDO 错误模式为异常模式
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 让错误变成异常,方便排查。
echo "Connected successfully";
}
catch(PDOException $e){
echo "Connection failed: " . $e->getMessage();
}
PDO可以把异常throw出去 但是mysqli不行。PDO一定要写try catch
<?php
$conn = new PDO("mysql:host=localhost;dbname=test;charset=utf8", "root", "");
$sql = "INSERT INTO users (name, age) VALUES ('Tom', 18)";
$conn->exec($sql);
echo "插入完成";
?>
// exec() 会返回影响的行数:查询
$sql = "SELECT * FROM users";
$result = $conn->query($sql);有返回结果的语句,要用 query
没有返回结果的语句,用 exec
预处理语句
$stmt = $conn->prepare("INSERT INTO users (name, age) VALUES (:name, :age)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':age', $age);
$name = "Bob";
$age = 20;
$stmt->execute();
插入多个数据:
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
VALUES (:firstname, :lastname, :email)");
$stmt->bindParam(':firstname', $firstname);
$stmt->bindParam(':lastname', $lastname);
$stmt->bindParam(':email', $email);
$firstname = "John";
$lastname = "Doe";
$email = "john@example.com";
$stmt->execute();
$firstname = "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt->execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "julie@example.com";
$stmt->execute();
因为 bindParam() 绑定的是变量的“引用”,所以只要修改变量值,再调用一次 execute() 就行!