如何做一个网站?
MagicalFlower · · 科技·工程
前言
大家好,又来挖坑了,前段时间做了一个网站,网站主要是一个休闲娱乐为主题的,但平时感觉不常用、而且比较简单且垃圾。
接下来我就给大家介绍一下我的网站的制作过程(全是免费的,没有花一分钱),还有一些坑给大家避一下。
一样一样,还是 Windows,别的用不了这个方法。
准备工作
Html or php
::::info[一大堆废话]
首先我们先把他们的全称写一下:
- HTML:HyperText Markup Language(超文本标记语言)
- PHP:Hypertext Preprocessor(超文本预处理器)
通过全称,我们可以看到:HTML 其实就是将你的代码放在网页上;php 你可以理解为就是把你的代码预处理成 html,然后再运行 html 在网页上。
如果你只是想做一个静态的,那就用 html,因为 html 在本地电脑上就可以运行。
但你想做一个网站比如可以登录的,那就用 php,但是 php 有一个缺点就是你需要下载一些可以运行 php 的东西。 ::::
一句话概括上面的废话,建议用 php。
链接:https://www.php.net/downloads.php 我就是从这里下载的,里面翻译一下找到自己的版本下载就行。
解压,然后放到,D 盘?E 盘?哪个盘的哪个位置都行,当一个样板或直接在上面做网站。
如果按照上面的链接,你需要复制一个
php.ini-development,粘贴在原文件夹,重命名为php.ini。
这里有个坑:千万不要下载 phpStudy 或所谓的 php 编辑器,因为那基本上要么和你想要的不是一个东西,要么要花钱。
数据库
这里我比较推荐 MySQL,因为如果从上面的链接里下载的 php 是有自带的 mysqli 的,比较方便。
但你还需要下载一个 mysqli,下载链接:https://dev.mysql.com/downloads/installer 这个的操作步骤可以问 AI 大人,Ta 是会给你解答的。
这一部分是在样板里改。
但是,你需要开启这个 mysqli,在 php.ini 中改,例如下图 898 行处,把前面的分号删了:
别的啥也不用改。
开始写网站
做一个网站最重要的就是开始写!
先复制一个样板过来,重命名任意。
接下来用管理员权限运行你的 Windows PowerShell。
用 cd 命令切到你的项目主文件夹,例如:你的项目主文件夹为 D:/www/,那你就写:
cd D:/www
然后,让 php 能够运行到网页上(此处的 80 是端口号,可以改):
php -S 127.0.0.1:80
这样你访问 http://127.0.0.1:80 就能出来你的网站了。
写网站
初始化数据库
在网站主文件夹下写一个 database.php,可以参考我的。
::::success[database.php]{open}
这一段不用怀疑,是 AI 大人写的。
<?php
// 连接参数
$host = 'localhost';
$user = 'root';
$pass = ''; // 你的 MySQL 密码
$link = mysqli_connect($host, $user, $pass);
if ($link) {
// SQL 文件路径
$sql_file = $_SERVER['DOCUMENT_ROOT'].'cc';
if (!file_exists($sql_file)) {
die("❌ SQL 文件不存在: $sql_file\n");
}
// 读取 SQL 文件内容
$sql_content = file_get_contents($sql_file);
// 分割 SQL 语句(处理分号,但保留存储过程中的分号)
$queries = [];
$current_query = '';
$in_string = false;
$string_char = '';
for ($i = 0; $i < strlen($sql_content); $i++) {
$char = $sql_content[$i];
// 处理字符串
if ($char === "'" || $char === '"') {
if (!$in_string) {
$in_string = true;
$string_char = $char;
} elseif ($char === $string_char) {
// 检查是否是转义
if ($i > 0 && $sql_content[$i-1] !== '\\') {
$in_string = false;
}
}
}
$current_query .= $char;
// 不在字符串中且遇到分号,结束当前语句
if (!$in_string && $char === ';') {
$queries[] = trim($current_query);
$current_query = '';
}
}
// 添加最后一个查询(如果没有分号结尾)
if (!empty(trim($current_query))) {
$queries[] = trim($current_query);
}
// 执行每个查询
$success = 0;
$failed = 0;
foreach ($queries as $index => $query) {
if (empty(trim($query))) {
continue;
}
$query_num = $index + 1;
echo "[$query_num] 执行: " . substr($query, 0, 60) . "... ";
if ($link->query($query)) {
echo "✅ 成功\n";
$success++;
} else {
echo "❌ 失败: " . $link->error . "\n";
$failed++;
}
}
echo "\n📊 执行结果:\n";
echo "✅ 成功: $success 条\n";
echo "❌ 失败: $failed 条\n";
} else {
echo "❌ 连接失败: " . mysqli_connect_error() . "\n";
echo "\n可能原因:\n";
echo "1. MySQL 服务未运行 - 运行: net start MySQL80\n";
echo "2. 密码错误 - 你设置的密码是: '$pass'\n";
echo "3. 端口被占用 - 检查端口 3306\n";
}
?>
::::
但是先别运行。
接下来再新建一个 /db/app_db233.sql,里面先写:
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+08:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `app_db233` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
USE `app_db233`;
接下来就是新建各种数据表,比如。
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `user_id` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `user_id`
--
LOCK TABLES `user_id` WRITE;
/*!40000 ALTER TABLE `user_id` DISABLE KEYS */;
/*!40000 ALTER TABLE `user_id` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `user_info`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `user_info` (
`username` varchar(20) NOT NULL,
`password` char(32) NOT NULL,
`encrypt` int(11) NOT NULL DEFAULT '0',
`decrypt` int(11) NOT NULL DEFAULT '0',
`color` varchar(32) NOT NULL DEFAULT 'cyan',
`manage` char(1) DEFAULT NULL,
`banned` char(1) DEFAULT NULL,
`muted` char(1) DEFAULT NULL,
PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `user_info`
--
LOCK TABLES `user_info` WRITE;
/*!40000 ALTER TABLE `user_info` DISABLE KEYS */;
/*!40000 ALTER TABLE `user_info` ENABLE KEYS */;
UNLOCK TABLES;
最后可以运行 /database.php 了。
运行方法:浏览器访问 http://127.0.0.1:80/database.php 进行初始化数据库。
网站主体可以用 Route 实现
我建议写一个 Route,可以直接套用我这个,在主文件夹下建很多文件可以参考下图:
主文件夹
|- models
| |- Route.php
|- index.php
|- route.php
注:不包括已有文件。
这里的所有文件都可以抄我的:
::::success[/models/Route.php]{open}
这个显然不是 AI 大人写的。
<?php
class Route {
protected static $routes = array();
protected static $patterns = array();
protected static $groupStack = array(array());
public static function match($methods, $uri, $action) {
return self::addRoute(array_map('strtoupper', (array)$methods), $uri, $action);
}
public static function any($uri, $action) {
return self::addRoute(array('GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'), $uri, $action);
}
public static function get($uri, $action) {
return self::addRoute(['GET', 'HEAD'], $uri, $action);
}
public static function post($uri, $action) {
return self::addRoute('POST', $uri, $action);
}
public static function put($uri, $action) {
return self::addRoute('PUT', $uri, $action);
}
public static function patch($uri, $action) {
return self::addRoute('PATCH', $uri, $action);
}
public static function delete($uri, $action) {
return self::addRoute('DELETE', $uri, $action);
}
public static function group(array $attributes, Closure $callback) {
self::$groupStack[] = array_merge(self::getGroup(), $attributes);
call_user_func($callback);
array_pop(self::$groupStack);
}
public static function getGroup() {
return self::$groupStack[count(self::$groupStack) - 1];
}
public static function pattern($name, $pat) {
self::$patterns[$name] = $pat;
}
public static function dispatch() {
foreach (self::$routes as $route) {
if (self::checkRoute($route)) {
include $_SERVER['DOCUMENT_ROOT'].$route['action'];
return $route;
}
}
// 你个人的 404 页面
}
protected static function addRoute($methods, $uri, $action) {
if (is_string($methods)) {
$methods = [$methods];
}
$cur = array();
$cur['methods'] = $methods;
$cur['uri'] = rtrim($uri, '/');
$cur['action'] = $action;
$cur = array_merge(self::getGroup(), $cur);
self::$routes[] = $cur;
return $cur;
}
public static function httpHost() {
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
return $_SERVER['HTTP_X_FORWARDED_HOST'];
} elseif (isset($_SERVER['HTTP_HOST'])) {
return $_SERVER['HTTP_HOST'];
} else {
return $_SERVER['SERVER_NAME'].($_SERVER['SERVER_PORT'] == '80' ? '' : ':'.$_SERVER['SERVER_PORT']);
}
}
public static function requestPath() {
$uri = $_SERVER['REQUEST_URI'];
$p = strpos($uri, '?');
if ($p === false) {
return $uri;
} else {
return substr($uri, 0, $p);
}
}
protected static function checkRoute($route) {
if (!in_array($_SERVER['REQUEST_METHOD'], $route['methods'])) {
return false;
}
$rep_arr = array();
foreach (self::$patterns as $name => $pat) {
$rep_arr['{'.$name.'}'] = "(?P<$name>$pat)";
}
$rep_arr['/'] = '\/';
$rep_arr['.'] = '\.';
$matches = array();
if (isset($route['domain'])) {
$domain_pat = strtr($route['domain'], $rep_arr);
if (!preg_match('/^'.$domain_pat.'$/', self::httpHost(), $domain_matches)) {
return false;
}
$matches = array_merge($matches, $domain_matches);
}
$uri_pat = strtr($route['uri'], $rep_arr);
if (!preg_match('/^'.$uri_pat.'$/', rtrim(self::requestPath(), '/'), $uri_matches)) {
return false;
}
$matches = array_merge($matches, $uri_matches);
foreach ($matches as $key => $val) {
if (!is_numeric($key)) {
$_GET[$key] = $val;
}
}
return true;
}
}
注意要改一下第 50 行。
::::
::::success[route.php]{open}
<?php
Route::pattern('username', '[a-zA-Z0-9_]{1,20}');
Route::pattern('id', '[1-9][0-9]{0,9}');
// 如果还有还可以加,左边是字符串名,右边是格式
Route::group([
'domain' => ''// 网站域名,不加 'http://'
], function() {
Route::any('/', '/app/index.php');
Route::any('/user/{username}', '/app/user_info.php');
// 还可以加,左边是网站链接,右边是本地具体文件
}
);
::::
::::success[index.php]{open}
<?php
require $_SERVER['DOCUMENT_ROOT'].'/models/Route.php';
require $_SERVER['DOCUMENT_ROOT'].'/route.php';
Route::dispatch();
?>
::::
其他文件都要按照网站主体来走
建议大家按照我的这个来,后面的文件/文件夹:
主文件夹
|- app
| |- index.php // 真正的主页
| |- // 其他文件,但都要是 route.php 里出现的
|- views
| |- header.php
| |- footer.php
| |- // 其他特殊的,比如:main.php
|- libs
| |- html-lib.php
| |- query-lib.php
| |- rand-lib.php
| |- security-lib.php
| |- validate-lib.php
下面是分别解释
/app/ 的文件是网站最终显示的页面
基本是这个结构
<!DOCTYPE html>
<html>
<?php
$host = 'localhost';
$user = 'root';
$pass = '';// 密码
$DB = mysqli_connect($host, $user, $pass);
$DB->query('USE `app_db233`;');
include $_SERVER['DOCUMENT_ROOT'].'/libs/rand-lib.php';
include $_SERVER['DOCUMENT_ROOT'].'/libs/validate-lib.php';
include $_SERVER['DOCUMENT_ROOT'].'/libs/query-lib.php';
include $_SERVER['DOCUMENT_ROOT'].'/libs/html-lib.php';
include $_SERVER['DOCUMENT_ROOT'].'/libs/security-lib.php';
?>
<head>
<meta charset="utf-8" />
<title>标题</title>
<?php include $_SERVER['DOCUMENT_ROOT'].'/views/header.php'; ?>
</head>
<body>
正文
<?php include $_SERVER['DOCUMENT_ROOT'].'/views/footer.php'; ?>
</body>
</html>
有了上面的代码结构写 /views/ 的代码就不难了
基本大家都知道要写什么了。
/libs/ 基本要写的东西不多
/libs/html-lib.php一般写一些比如becomeMsgPage(msg, title), become403Page(), become404Page()等等…… ::::info[参考代码,我做的网站的]{open}<?php function user() { $host = 'localhost'; $user = 'root'; $pass = ''; $DB = mysqli_connect($host, $user, $pass); $DB->query('USE `app_zyxot233`;'); if (Cookie::get("zyxOT_username") && Cookie::get("zyxOT_username_checksum")) { if (Cookie::get("zyxOT_username_checksum") != Cookie::checksum("zyxOT_username", Cookie::get("zyxOT_username")) || !$DB->query("select `password` from user_info where `username` = '{$_COOKIE['zyxOT_username']}'")->num_rows || $DB->query("select banned from user_info where `username` = '{$_COOKIE['zyxOT_username']}'")->fetch_assoc()['banned']) { return 0; } return $_COOKIE['zyxOT_username']; } return 0; } function isSuperuser() { $host = 'localhost'; $user = 'root'; $pass = ''; $DB = mysqli_connect($host, $user, $pass); $DB->query('USE `app_zyxot233`;'); if (user() && $DB->query("select manage from user_info where `username` = '{$_COOKIE['zyxOT_username']}'")->fetch_assoc()['manage']) return 1; return 0; } function nowTime() { date_default_timezone_set('Asia/Shanghai'); return date('Y-m-d H:i:s'); } function nowTimeYear() { date_default_timezone_set('Asia/Shanghai'); return date('Y'); } function becomeMsgPage($msg, $title = '消息') { echo '<script>document.querySelector("title").innerHTML = "'.$title.' - 在线加密系统";</script>'; echo '<div class="uoj-content container flex-fill">'.$msg.'</div>'; include $_SERVER['DOCUMENT_ROOT'].'/view/footer.php'; echo '</div> <!-- /container --> </body>
</html>';
die();
}
function become404Page() {
becomeMsgPage('<div class="text-center"><div style="font-size:233px">404</div><p>唔……未找到该页面……你是从哪里点进来的……>_<……</p></div>', '404');
}
function become403Page() {
becomeMsgPage('<div class="text-center"><div style="font-size:233px">403</div><p>禁止入内! T_T</p></div>', '403');
}
function getClickZanBlock(