乐于分享
好东西不私藏

一个简单的GitHub项目更新软件

一个简单的GitHub项目更新软件
提到管理GitHub代码,第一个想到的就是Git,于是我们就根据Git命令写一个python编写的ui界面,实现简单的拉取和更新github项目的目的。
python代码如下
"""GitHub 项目更新工具功能:一键 Pull(同步远程到本地)或 Push(提交并推送到远程)依赖:Python 内置库(tkinter、subprocess、os、threading)打包:pyinstaller --onefile --windowed github_updater.py"""import tkinter as tkfrom tkinter import ttk, filedialog, scrolledtext, messageboximport subprocessimport osimport threadingimport jsonCONFIG_FILE = "github_updater_config.json"DEFAULT_GITIGNORE = """.Rhistory*.exe*.zip*.pyc__pycache__/.DS_Store"""# ────────────────────────────────────────────────────────────────────────────# 配置持久化# ────────────────────────────────────────────────────────────────────────────def load_config() -> dict:    if os.path.exists(CONFIG_FILE):        try:            with open(CONFIG_FILE, "r", encoding="utf-8"as f:                return json.load(f)        except Exception:            pass    return {}def save_config(data: dict):    try:        with open(CONFIG_FILE, "w", encoding="utf-8"as f:            json.dump(data, f, ensure_ascii=False, indent=2)    except Exception:        pass# ────────────────────────────────────────────────────────────────────────────# Git 工具函数# ────────────────────────────────────────────────────────────────────────────def build_remote_url(user: str, repo: str, token: str) -> str:    """构造带 token 的 HTTPS 远程地址(格式与 bash 脚本一致)。"""    repo = repo.strip().rstrip("/")    if not repo.endswith(".git"):        repo += ".git"    return f"https://{user.strip()}:{token.strip()}@github.com/{user.strip()}/{repo}"def build_clean_url(user: str, repo: str) -> str:    """不含 token 的干净远程地址(push 后用于还原,避免 token 残留)。"""    repo = repo.strip().rstrip("/")    if not repo.endswith(".git"):        repo += ".git"    return f"https://github.com/{user.strip()}/{repo}"def run_git(args: list[str], cwd: str) -> tuple[intstr]:    """执行 git 命令,返回 (returncode, output)。"""    try:        result = subprocess.run(            ["git"] + args,            cwd=cwd,            capture_output=True,            text=True,            encoding="utf-8",            errors="replace",            env=os.environ.copy(),        )        return result.returncode, result.stdout + result.stderr    except FileNotFoundError:        return -1"错误:未找到 git 命令,请确保已安装 Git 并加入 PATH。"    except Exception as e:        return -1f"执行出错:{e}"# ────────────────────────────────────────────────────────────────────────────# 主窗口# ────────────────────────────────────────────────────────────────────────────class App(tk.Tk):    def __init__(self):        super().__init__()        self.title("GitHub 项目更新工具")        self.resizable(TrueTrue)        self.minsize(660600)        self._build_ui()        self._load_saved_config()    # ── UI 构建 ──────────────────────────────────────────────────────────────    def _build_ui(self):        pad = {"padx"10"pady"4}        # ── 账号配置 ──        acct_frame = ttk.LabelFrame(self, text="GitHub 账号配置")        acct_frame.pack(fill="x", **pad)        # 用户名        ttk.Label(acct_frame, text="GitHub 用户名:").grid(row=0, column=0, sticky="w", **pad)        self.github_user = tk.StringVar()        ttk.Entry(acct_frame, textvariable=self.github_user, width=30).grid(            row=0, column=1, sticky="ew", **pad)        # 仓库名        ttk.Label(acct_frame, text="仓库名(Repo):").grid(row=1, column=0, sticky="w", **pad)        self.repo_name = tk.StringVar()        ttk.Entry(acct_frame, textvariable=self.repo_name, width=30).grid(            row=1, column=1, sticky="ew", **pad)        # Token        ttk.Label(acct_frame, text="Personal Access Token:").grid(row=2, column=0, sticky="w", **pad)        self.token = tk.StringVar()        self.token_entry = ttk.Entry(acct_frame, textvariable=self.token, width=50, show="*")        self.token_entry.grid(row=2, column=1, sticky="ew", **pad)        self.show_token = tk.BooleanVar(value=False)        ttk.Checkbutton(acct_frame, text="显示", variable=self.show_token,                        command=self._toggle_token).grid(row=2, column=2, **pad)        acct_frame.columnconfigure(1, weight=1)        # ── 本地项目配置 ──        proj_frame = ttk.LabelFrame(self, text="本地项目配置")        proj_frame.pack(fill="x", **pad)        # 本地目录        ttk.Label(proj_frame, text="本地项目目录:").grid(row=0, column=0, sticky="w", **pad)        self.local_dir = tk.StringVar()        ttk.Entry(proj_frame, textvariable=self.local_dir, width=48).grid(            row=0, column=1, sticky="ew", **pad)        ttk.Button(proj_frame, text="浏览…", command=self._browse_dir).grid(row=0, column=2, **pad)        # 分支        ttk.Label(proj_frame, text="分支名称:").grid(row=1, column=0, sticky="w", **pad)        self.branch = tk.StringVar(value="master")        ttk.Entry(proj_frame, textvariable=self.branch, width=20).grid(            row=1, column=1, sticky="w", **pad)        proj_frame.columnconfigure(1, weight=1)        # ── Push 选项 ──        push_frame = ttk.LabelFrame(self, text="Push 选项")        push_frame.pack(fill="x", **pad)        ttk.Label(push_frame, text="提交说明(Commit message):").grid(row=0, column=0, sticky="w", **pad)        self.commit_msg = tk.StringVar(value="update")        ttk.Entry(push_frame, textvariable=self.commit_msg, width=45).grid(            row=0, column=1, sticky="ew", **pad)        self.auto_init = tk.BooleanVar(value=True)        ttk.Checkbutton(push_frame, text="目录非 git 仓库时自动 git init",                        variable=self.auto_init).grid(row=1, column=1, sticky="w", **pad)        self.auto_gitignore = tk.BooleanVar(value=True)        ttk.Checkbutton(push_frame, text="不存在 .gitignore 时自动创建",                        variable=self.auto_gitignore).grid(row=2, column=1, sticky="w", **pad)        # .gitignore 内容编辑        ttk.Label(push_frame, text=".gitignore 内容:").grid(row=3, column=0, sticky="nw", **pad)        self.gitignore_text = tk.Text(push_frame, height=4, width=45, font=("Consolas"9))        self.gitignore_text.insert("1.0", DEFAULT_GITIGNORE)        self.gitignore_text.grid(row=3, column=1, sticky="ew", **pad)        self.clean_token = tk.BooleanVar(value=True)        ttk.Checkbutton(push_frame, text="Push 后从 git 配置中移除 token(推荐)",                        variable=self.clean_token).grid(row=4, column=1, sticky="w", **pad)        push_frame.columnconfigure(1, weight=1)        # ── 记住配置 ──        misc_frame = ttk.Frame(self)        misc_frame.pack(fill="x", padx=10, pady=2)        self.remember = tk.BooleanVar(value=True)        ttk.Checkbutton(misc_frame, text="记住配置(保存到 github_updater_config.json)",                        variable=self.remember).pack(side="left")        # ── 按钮区 ──        btn_frame = ttk.Frame(self)        btn_frame.pack(fill="x", padx=10, pady=6)        ttk.Button(btn_frame, text="⬆  Push(提交推送)", width=22,                   command=self._on_push).pack(side="left", padx=6)        ttk.Button(btn_frame, text="⬇  Pull(拉取更新)", width=22,                   command=self._on_pull).pack(side="left", padx=6)        ttk.Button(btn_frame, text="🔄  Clone(初次克隆)", width=22,                   command=self._on_clone).pack(side="left", padx=6)        ttk.Button(btn_frame, text="清空日志", width=10,                   command=self._clear_log).pack(side="right", padx=6)        # ── 日志区 ──        log_frame = ttk.LabelFrame(self, text="操作日志")        log_frame.pack(fill="both", expand=True, padx=10, pady=4)        self.log_box = scrolledtext.ScrolledText(            log_frame, state="disabled", height=12,            font=("Consolas"9), wrap="word"        )        self.log_box.pack(fill="both", expand=True, padx=6, pady=6)        # 状态栏        self.status_var = tk.StringVar(value="就绪")        ttk.Label(self, textvariable=self.status_var, anchor="w",                  relief="sunken").pack(fill="x", side="bottom")    # ── UI 辅助 ──────────────────────────────────────────────────────────────    def _browse_dir(self):        d = filedialog.askdirectory(title="选择本地项目目录")        if d:            self.local_dir.set(d)    def _toggle_token(self):        self.token_entry.config(show="" if self.show_token.get() else "*")    def _log(self, text: str):        def _append():            self.log_box.config(state="normal")            self.log_box.insert("end", text + "\n")            self.log_box.see("end")            self.log_box.config(state="disabled")        self.after(0, _append)    def _clear_log(self):        self.log_box.config(state="normal")        self.log_box.delete("1.0""end")        self.log_box.config(state="disabled")    def _set_status(self, msg: str):        self.after(0lambdaself.status_var.set(msg))    # ── 配置持久化 ────────────────────────────────────────────────────────────    def _load_saved_config(self):        cfg = load_config()        for key, var in [            ("github_user"self.github_user),            ("repo_name",   self.repo_name),            ("token",       self.token),            ("branch",      self.branch),            ("commit_msg",  self.commit_msg),            ("local_dir",   self.local_dir),        ]:            if cfg.get(key):                var.set(cfg[key])        if cfg.get("gitignore_content"):            self.gitignore_text.delete("1.0""end")            self.gitignore_text.insert("1.0", cfg["gitignore_content"])    def _maybe_save_config(self):        if self.remember.get():            save_config({                "github_user":      self.github_user.get(),                "repo_name":        self.repo_name.get(),                "token":            self.token.get(),                "branch":           self.branch.get(),                "commit_msg":       self.commit_msg.get(),                "local_dir":        self.local_dir.get(),                "gitignore_content"self.gitignore_text.get("1.0""end"),            })    # ── 输入校验 ──────────────────────────────────────────────────────────────    def _validate(self, need_local=True) -> bool:        if not self.github_user.get().strip():            messagebox.showwarning("提示""请填写 GitHub 用户名。")            return False        if not self.repo_name.get().strip():            messagebox.showwarning("提示""请填写仓库名(Repo)。")            return False        if not self.token.get().strip():            messagebox.showwarning("提示""请填写 Personal Access Token。")            return False        if need_local and not self.local_dir.get().strip():            messagebox.showwarning("提示""请先选择本地项目目录。")            return False        return True    # ── 共用:初始化本地仓库 ──────────────────────────────────────────────────    def _ensure_git_repo(self, local: str) -> bool:        """若目录不是 git 仓库且勾选了自动 init,则执行 git init。"""        if os.path.isdir(os.path.join(local, ".git")):            return True        if self.auto_init.get():            self._log("[init] 检测到非 git 仓库,正在执行 git init…")            code, out = run_git(["init"], cwd=local)            self._log(out.strip())            if code != 0:                self._log("❌ git init 失败。")                return False            # 设置默认分支名            branch = self.branch.get().strip() or "master"            run_git(["checkout""-b", branch], cwd=local)            return True        else:            self._log('❌ 该目录不是 git 仓库,请先使用【Clone】或勾选"自动 git init"。')            return False    def _ensure_gitignore(self, local: str):        """若不存在 .gitignore 且勾选了自动创建,则写入。"""        path = os.path.join(local, ".gitignore")        if not os.path.exists(path) and self.auto_gitignore.get():            content = self.gitignore_text.get("1.0""end")            with open(path, "w", encoding="utf-8"as f:                f.write(content)            self._log("[.gitignore] 已自动创建 .gitignore")    def _setup_remote(self, local: str, remote_url: str):        """移除旧 origin 再添加新 origin(含 token)。"""        run_git(["remote""remove""origin"], cwd=local)        code, out = run_git(["remote""add""origin", remote_url], cwd=local)        if code != 0:            self._log(f"[警告] 设置 remote 失败:{out.strip()}")    # ── 操作:Push ────────────────────────────────────────────────────────────    def _on_push(self):        if not self._validate():            return        if not self.commit_msg.get().strip():            messagebox.showwarning("提示""请填写提交说明(Commit message)。")            return        self._maybe_save_config()        threading.Thread(target=self._push_task, daemon=True).start()    def _push_task(self):        local  = self.local_dir.get().strip()        branch = self.branch.get().strip() or "master"        msg    = self.commit_msg.get().strip()        user   = self.github_user.get().strip()        repo   = self.repo_name.get().strip()        token  = self.token.get().strip()        remote_url = build_remote_url(user, repo, token)        clean_url  = build_clean_url(user, repo)        self._set_status("正在推送…")        self._log(f"\n{'='*50}")        self._log(f"[Push] 目录:{local}  分支:{branch}  提交说明:{msg}")        # 1. 确保是 git 仓库        if not self._ensure_git_repo(local):            self._set_status("Push 失败")            return        # 2. 自动创建 .gitignore        self._ensure_gitignore(local)        # 3. 设置 remote        self._setup_remote(local, remote_url)        # 4. git add .        code, out = run_git(["add""."], cwd=local)        self._log(out.strip() if out.strip() else "[add] 已暂存所有改动")        if code != 0:            self._log("❌ git add 失败。")            self._set_status("Push 失败")            return        # 5. 检查是否有改动(git diff --cached --quiet)        check_code, _ = run_git(["diff""--cached""--quiet"], cwd=local)        if check_code == 0:            self._log("⚠️ 没有新文件需要提交(工作区与最后一次提交相同)。")            self._set_status("无改动,跳过提交")        else:            # 6. git commit            code, out = run_git(["commit""-m", msg], cwd=local)            self._log(out.strip() if out.strip() else "(无 commit 输出)")            if code != 0:                self._log("❌ git commit 失败,请查看上方日志。")                self._set_status("Push 失败")                return        # 7. git push -u origin branch        code, out = run_git(["push""-u""origin", branch], cwd=local)        self._log(out.strip() if out.strip() else "(无 push 输出)")        # 8. Push 后清除 token(安全措施)        if self.clean_token.get():            run_git(["remote""set-url""origin", clean_url], cwd=local)            self._log(f"[安全] token 已从 git 配置中移除,远程地址已还原为:{clean_url}")        if code == 0:            self._log("✅ Push 成功!")            self._log("⚠️  建议在 GitHub 设置中定期轮换(regenerate)此 token。")            self._set_status("Push 完成")        else:            self._log("❌ Push 失败,请查看上方日志。")            self._set_status("Push 失败")    # ── 操作:Pull ────────────────────────────────────────────────────────────    def _on_pull(self):        if not self._validate():            return        self._maybe_save_config()        threading.Thread(target=self._pull_task, daemon=True).start()    def _pull_task(self):        local  = self.local_dir.get().strip()        branch = self.branch.get().strip() or "master"        user   = self.github_user.get().strip()        repo   = self.repo_name.get().strip()        token  = self.token.get().strip()        remote_url = build_remote_url(user, repo, token)        clean_url  = build_clean_url(user, repo)        self._set_status("正在拉取…")        self._log(f"\n{'='*50}")        self._log(f"[Pull] 目录:{local}  分支:{branch}")        if not os.path.isdir(os.path.join(local, ".git")):            self._log("❌ 该目录不是 git 仓库,请先使用【Clone】按钮初始化。")            self._set_status("Pull 失败")            return        self._setup_remote(local, remote_url)        code, out = run_git(["pull""origin", branch], cwd=local)        self._log(out.strip() if out.strip() else "(无输出)")        # 还原 remote(移除 token)        if self.clean_token.get():            run_git(["remote""set-url""origin", clean_url], cwd=local)            self._log(f"[安全] token 已从 git 配置中移除。")        if code == 0:            self._log("✅ Pull 成功!")            self._set_status("Pull 完成")        else:            self._log("❌ Pull 失败,请查看上方日志。")            self._set_status("Pull 失败")    # ── 操作:Clone ───────────────────────────────────────────────────────────    def _on_clone(self):        if not self._validate(need_local=False):            return        parent = filedialog.askdirectory(title="选择克隆到哪个父目录")        if not parent:            return        self._maybe_save_config()        threading.Thread(target=self._clone_task, args=(parent,), daemon=True).start()    def _clone_task(self, parent: str):        user   = self.github_user.get().strip()        repo   = self.repo_name.get().strip()        token  = self.token.get().strip()        branch = self.branch.get().strip()        remote_url = build_remote_url(user, repo, token)        repo_name  = repo.replace(".git""")        target_dir = os.path.join(parent, repo_name)        self._set_status("正在克隆…")        self._log(f"\n{'='*50}")        # 先尝试指定分支,失败则克隆默认分支        if branch:            self._log(f"[Clone] 目标目录:{target_dir}  分支:{branch}")            code, out = run_git(["clone""-b", branch, remote_url], cwd=parent)            if code != 0:                self._log(f"[警告] 分支 '{branch}' 不存在,改为克隆默认分支…")                code, out = run_git(["clone", remote_url], cwd=parent)        else:            self._log(f"[Clone] 目标目录:{target_dir}  使用仓库默认分支")            code, out = run_git(["clone", remote_url], cwd=parent)        self._log(out.strip() if out.strip() else "(无输出)")        if code == 0:            # 检测实际分支(symbolic-ref 在空仓库也可用)            b_code, b_out = run_git(["symbolic-ref""--short""HEAD"], cwd=target_dir)            actual = b_out.strip() if b_code == 0 and b_out.strip() else (branch or "master")            self._log(f"✅ Clone 成功!当前分支:{actual}")            self._set_status("Clone 完成")            self.after(0lambdaself.branch.set(actual))            self.after(0lambdaself.local_dir.set(target_dir))        else:            self._log("❌ Clone 失败,请查看上方日志。")            self._set_status("Clone 失败")# ────────────────────────────────────────────────────────────────────────────if __name__ == "__main__":    app = App()    app.mainloop()
然后需要exe可以使用pyinstaller --onefile --windowed --name "GitHub更新工具" github_updater.py转换成GitHub更新工具.exe
界面很简单
这里就是需要生成一个GitHub的token,方便上传
第一步,打开https://github.com/settings/tokens,进入token管理界面,然后点击Generate new token(classic),
填写你想要的名字和可以使用token的地方,我全选了
点击Generate token即可生成
记得复制保存对应的token,只显示一次
然后我们就可以填到GitHub更新工具.exe对应的token填写位置
怎么用呢,如果还没有初始化,我们点击
就在本地新建了一个.git文件,后面就在对应的文件夹下添加或修改自己的文件,代码等,修改完之后点击
就可以完成推送,如果GitHub项目中已经有内容了,我们可以使用
检测后在进行
就可以完成GitHub项目的更新了。
代码很简单,实现的结果也很简单,使用token,避免失败的情况。
关于这里,我们打开新建的GitHub项目,可以看到
这里的https://github.com/chen167777/myip.git就有我们填写的信息,按照这个来填写即可。
基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-06-02 05:56:06 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/694781.html
  2. 运行时间 : 0.103451s [ 吞吐率:9.67req/s ] 内存消耗:4,801.88kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=166a9381be96b665aa0a8b774e11bb03
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000787s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000825s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000396s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000294s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000485s ]
  6. SELECT * FROM `set` [ RunTime:0.000210s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000672s ]
  8. SELECT * FROM `article` WHERE `id` = 694781 LIMIT 1 [ RunTime:0.000521s ]
  9. UPDATE `article` SET `lasttime` = 1780350966 WHERE `id` = 694781 [ RunTime:0.007470s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000288s ]
  11. SELECT * FROM `article` WHERE `id` < 694781 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000500s ]
  12. SELECT * FROM `article` WHERE `id` > 694781 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001483s ]
  13. SELECT * FROM `article` WHERE `id` < 694781 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000774s ]
  14. SELECT * FROM `article` WHERE `id` < 694781 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000838s ]
  15. SELECT * FROM `article` WHERE `id` < 694781 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.009942s ]
0.105136s