A dependency-free PHP engine for building SEO tools: a shared analyzer that scores a page /100 across four metrics, plus protected AI features on top.
No framework, no composer packages — pure PHP 8 + cURL + SQLite. The engine powers three reference endpoints out of the box:
analyze.php— SEO page analysis (score, issues, recommendations).meta.php— AI meta tag generator (title / description / keywords).ai-audit.php— AI audit (analyzer facts → DeepSeek recommendations).
Русская версия: README.ru.md
Most "SEO checker" projects are one big copy-paste of HTML parsing and scoring. This engine extracts the common core once and reuses it across tools:
URL → Analyzer (SSRF + curl) → Checks (~20 signals) → Scorer (4 metrics) → score /100
│
└──→ optional DeepSeek step (facts → prompt → report)
It was built for a real catalog of 100 SEO tools running on a PHP-only hosting (no Node services, no queues, no external libraries on the backend). The same engine drives the page analyzer, the AI audit and the meta tag generator — a new tool is an endpoint, not a copy of the code.
The engine runs alongside a CMS like Joomla, not inside it: the CMS serves
the page shells (HTML + JS), the engine serves the JSON. The analysis logic
has zero CMS dependencies — you can run it standalone with php -S.
- One analysis engine — ~20 signals grouped into 4 metrics (technical, content, indexing, links), collapsed into a score /100 with weights.
- SSRF protection — blocks localhost, metadata and private subnets before any outbound request.
- Protected LLM calls — server-side cache (0 tokens on repeats), daily
quota (cookie fingerprint → IP), token cap and
temperature 0.4. - API key stays server-side — the frontend never talks to the LLM provider directly.
- Zero backend dependencies — cURL for HTTP, SQLite for cache/quota,
native
json_encodefor responses.
- PHP 8.1+ with
curl,mbstringandsqlite3(PDO) extensions. - A DeepSeek API key (or any OpenAI-compatible endpoint) — only for the two AI endpoints.
git clone https://github.com/YanChi-pixel/php-seo-engine.git
cd php-seo-engine
# 1. Configure
cp .env.example .env
# …then set DEEPSEEK_API_KEY in .env
# 2. Serve the folder (any PHP server)
php -S localhost:8080
# 3. Try the analyzer
curl "http://localhost:8080/analyze.php?url=https://example.com"The SQLite cache is created automatically in ./data on first run.
| Layer | File | Role |
|---|---|---|
| Bootstrap | lib/bootstrap.php |
env loading, CORS, JSON output, autoloading |
| HTTP | lib/HttpClient.php |
cURL GET/HEAD with redirects, UA, timeouts |
| Orchestrator | lib/Analyzer.php |
URL validation, SSRF, runs checks, builds issues/recs |
| Checks | lib/checks/Checks.php |
HTML parsing + HTTP/technical + link signals |
| Scorer | lib/Scorer.php |
4 metrics → weighted score /100 |
| Cache | lib/Cache.php |
SQLite result cache + rate limit |
| Quota | lib/AiQuota.php |
daily AI limit (default 3) |
| LLM | lib/DeepSeek.php |
DeepSeek API wrapper (key from env) |
| History | lib/History.php |
optional per-user history |
All settings live in .env (see .env.example):
| Variable | Default | Meaning |
|---|---|---|
DEEPSEEK_API_KEY |
— | API key for meta.php / ai-audit.php |
ALLOWED_ORIGIN |
* |
CORS origin (set one origin to restrict) |
AI_DAILY_LIMIT |
3 |
daily free quota for AI endpoints |
DATA_DIR |
./data |
where the SQLite cache lives |
All endpoints accept GET ?url= or POST {"url": ...} and return JSON.
analyze.php— returnsscore,metrics,issues,recommendations.meta.php— returnsgenerated(title/description/keywords) andquota_remaining.ai-audit.php— returnsbase_scoreand a Markdownreport.
Errors are returned as {"status":"error","error":{"code":...,"message":...}}.
- No response from AI — check
DEEPSEEK_API_KEYin.env. - SQLite errors — make sure the
DATA_DIRfolder is writable. - 429 quota_exceeded — the daily AI limit is reached; raise
AI_DAILY_LIMITin.env. - Forbidden address — the URL points to a private/local host (SSRF block).
php-seo-engine/
├── lib/
│ ├── bootstrap.php
│ ├── HttpClient.php
│ ├── Analyzer.php
│ ├── Scorer.php
│ ├── Cache.php
│ ├── AiQuota.php
│ ├── DeepSeek.php
│ ├── History.php
│ └── checks/
│ └── Checks.php
├── analyze.php
├── meta.php
├── ai-audit.php
├── .env.example
├── .github/workflows/ci.yml
├── CHANGELOG.md
└── LICENSE
- SSRF protection blocks private/local/metadata addresses before fetching.
- The DeepSeek key is read from the server env, never exposed to the client.
- Cache + quota protect the paid API budget from abuse.
- The engine performs outbound requests to arbitrary URLs — run it on a server you control and consider rate limits per IP.
MIT — see LICENSE.
This is a general-purpose SEO analysis engine. You are responsible for how you deploy it and for any outbound requests it makes. Review AI-generated content before publishing it.