Documentation

How to use Oash Mini-PHP

Read this once. Then copy the pattern for every page. PHP 8+, no Composer, no database. New to the web? Start with Aim, Vision, and client–server diagrams. Need a human? contact@oashsocial.in.

The flow (always this order)

  1. Config — identity and menu in app/config.php.
  2. Routecase in app/routes.php for the URL path.
  3. Page — body HTML in app/views/pages/…php.
  4. Renderindex.php asks the route, View wraps the page in the layout.
  5. SEO — pass title and description from the route; the layout prints tags.
  6. Sitemap — add the path to app/data/sitemap.php, then generate.
  7. Broken links — crawl the site and fix anything that 404s.

1. Config — app/config.php

This file is the site. Set name, tagline, site_url (live domain, no trailing slash), email, github, upi_id, and nav.

Do not put secrets in config if the file is public on GitHub. Mailbox passwords belong in includes/mail-config.php and should stay off the repo if they are real.

2. Route — app/routes.php

The first URL segment is $seg[0]. Home is an empty string. Extra segments you do not handle must return not_found() so /about/hacker is a 404.

case 'about':
    if (count($seg) > 1) {
        return not_found();
    }
    return page('about', [
        'title'       => 'About us',
        'description' => 'Who we are — one sentence for Google.',
    ]);

That page('about', …) name is the file app/views/pages/about.php. Arrays you pass become variables in the view ($title, $description).

Never header('Location: about.php'). Never link to about.php. Use url('about').

3. Page — content only

Create app/views/pages/services.php. Write the <h1> and sections. Do not paste the header or footer. Those live in partials.

Always:

Optional menu: add the path under nav in config so it appears in the header and footer can link it too.

4. Render — what the engine does

A request hits index.php (Apache rewrite or router.php locally). App reads the path, calls your route function, then View::render:

  1. Load the page view into a string.
  2. Load layouts/main.php.
  3. Print $content between header and footer.

You do not call the layout yourself. If the view file is missing, you get an error locally (debug) or a short 500 on live.

Real files still win: /assets/css/style.css and /includes/send-form.php are not routes. Do not name a route assets or includes.

5. SEO setup

Every route should pass a unique title and description. The layout then emits:

404 pages should set 'robots' => 'noindex' if you pass it; the default is index, follow.

After go-live, Search Console should fetch /sitemap.xml and /robots.txt. llms.txt is a short map for AI crawlers.

6. Sitemap — and auto-generate

Do not hand-edit sitemap.xml if you can avoid it. The list of public pages lives in app/data/sitemap.php.

  1. Add a row: path, changefreq, priority, title.
  2. Set site_url in config to the live domain.
  3. Run:
php tools/generate-sitemap.php

That command writes sitemap.xml, updates the Sitemap: line in robots.txt, and refreshes the page list in llms.txt. Run it whenever you add or remove a public URL.

robots.txt already allows /, /assets/, sitemap and llms, and disallows /app/, /core/, /includes/.

Broken internal links are usually a typo in url('…'), a missing route, or a sitemap path you never routed. After the local server is running:

php -S localhost:8000 router.php
php tools/check-links.php http://localhost:8000

The checker starts from every sitemap URL, follows internal hrefs, and prints anything that is not a 2xx/3xx. Fix by:

Also click every new nav item once. Trailing slashes are fine (/about/ = /about). /about.php must 404. Extra segments must 404.

Install

git clone https://github.com/codingtodecoding/oash-mini-php.git
cd oash-mini-php
php -S localhost:8000 router.php

Open http://localhost:8000. On Apache, upload the folder. .htaccess rewrites internally to index.php.

Do not edit core/, index.php, router.php, or .htaccess unless you are changing the engine. Work in app/ and assets/.

Lists without a database: arrays in app/data/, load with data('name'), unknown slugs → not_found().

Email (contact form)

The page URL stays clean (/contact). The browser posts JSON to includes/send-form.php — a real file, not a route. Recipients, From address, and the live site link are in includes/mail-config.php. Mail is sent as a plain-text template that includes https://mini.oashsocial.in. This project inbox is contact@oashsocial.in. Include the honeypot partial. Hosting must allow PHP mail().

Logs

There is no application log database. Use the host:

If you need an audit trail, append a line to a file outside the web root. Do not put logs in assets/.

Hosting

Any PHP 8 shared host with mod_rewrite. Upload, confirm AllowOverride All, set debug false, set mail, set site_url, run the sitemap generator. That is the deploy.

Security short version: no SQL, escaped views, private app/ and core/, honeypot on forms. Full notes on Security.