Skip to main content

TiCore PHP Framework v1.24

Tuxxin Integrated Core

The only open-source PHP framework with a complete SEO suite built in — canonical URLs, Open Graph, Twitter/X cards, Schema.org JSON-LD, og:video, og:logo, fb:app_id, and Google Analytics 4, all auto-generated from the layout with zero extra packages. Secure, lightweight, PHP 8.4+ native, and WCAG-accessible out of the box.

What TiCore Includes

🔒 Security First

CSRF token generation and verification, output XSS escaping via e(), and cryptographic session handling built into the core. All sensitive files live outside the public web root.

🚀 Smart Router

Four-tier dispatch: manual routes → auto-discovered controllers → PageController fallback → 404. Add a view file and it becomes a live page instantly with zero configuration.

📝 Structured Logging

Six-level log system (CRITICAL → DEBUG) with daily log rotation stored outside the web root. Log verbosity is tunable per environment via LOG_LEVEL in .env.

📊 Database Ready

Optional PDO layer with prepared statements, utf8mb4 charset, and exception-mode error handling. Enable with one flag in config.php — no changes elsewhere required.

🔍 SEO & Open Graph

Full per-page SEO built into the layout: canonical URLs, Open Graph, Twitter/X cards, og:video, og:logo, fb:app_id, Schema.org JSON-LD, Google Tag Manager, and WCAG accessibility — all via controller variables.

⚙️ Zero-Config Pages

Drop a .php view file into templates/default/ and the PageController serves it automatically — ideal for static or mostly-static content without writing a dedicated controller.

What is TiCore?

TiCore is a minimal, security-first PHP framework that keeps your application logic entirely outside the public web root. The browser can only reach www/; everything else — controllers, templates, logs, credentials — lives in TiCore/ where the web server cannot serve it directly.

There are no magic globals, no auto-wiring surprises, and no framework lock-in beyond a handful of small core classes. Every piece of the stack is readable and replaceable.

Architecture — Four-Tier Router

Requests hit www/index.php, which bootstraps the framework and hands off to the Router. The Router resolves the URI using a four-tier cascade:

  1. Manual routes — explicit URI-to-controller mappings you define in code.
  2. Auto-discovered controllers — a URI of /login automatically maps to LoginController if the file exists.
  3. PageController fallback — if no dedicated controller exists but a matching view file does, PageController renders it directly.
  4. 404 — served cleanly if nothing matches.

⚙️ Zero-Config Pages with PageController

Most web projects have a handful of pages that are purely informational — an About, a Privacy Policy, a Terms of Service. Writing a dedicated controller for each is unnecessary boilerplate.

PageController solves this. The Router's Case D fallback checks whether a view file named after the URI exists in templates/default/. If it does, PageController::show() renders it automatically — no controller file needed.

# Add a new static page

touch TiCore/templates/default/privacy.php

# It’s now live at:

https://yoursite.com/privacy

# Set SEO meta inside the template

<?php
$meta_description = 'Our privacy policy.';
$meta_robots = 'noindex, follow';
?>
<?php include 'layouts/header.php'; ?>

You can still add business logic by creating a real controller later — the router will prefer it over the PageController fallback automatically.

Core Features

  • 🔒 CSRF token generation & verification
  • 📝 XSS output escaping (e() helper)
  • 🚀 Four-tier smart router
  • 📊 Optional PDO database layer
  • 📄 Six-level structured logger (0–5)
  • 📩 PHPMailer 7 included via Composer
  • 🔍 Automatic SEO sitemap (optional)
  • ⚙️ Zero-config static page rendering

SEO & Open Graph — No Other Framework Does This

Laravel, Symfony, CodeIgniter, and Slim all require third-party packages or manual tag management for SEO. TiCore builds the entire suite directly into the layout — nothing to install, nothing to configure, nothing to forget.

Every page automatically gets canonical URLs, full Open Graph, Twitter/X cards, and Schema.org JSON-LD structured data. Pass variables from any controller or static template — unset variables emit no tags at all, so your output is always clean.

✅ Always Generated — no setup required
Tag Value / Source
<title>$title + site name, or site name alone
meta description$meta_description or site-wide default
meta robots$meta_robots or index, follow
meta authorTuxxin — tuxxin.com
meta generatorTiCore + version from .v
meta theme-color#212529
link canonicalBASE_URL + REQUEST_URI (overridable via $canonical)
og:type$og_type or website
og:site_nameSITE_TITLE constant
og:titleSame as <title>
og:descriptionSame as meta description
og:urlSame as canonical
og:image$og_image or /assets/images/og-default.png
og:image:width / height$og_image_width / $og_image_height or 1200×630
og:logo$og_logo or SITE_LOGO constant (logo-v2.png)
twitter:card$twitter_card or summary_large_image
twitter:site$twitter_site or @tuxxin
twitter:title / description / imageMirrors OG values
JSON-LD (Schema.org)WebSite + Organization (logo + sameAs) + WebPage @graph
Google Analytics 4GA4_ID constant in config.php (gtag.js)
link preconnectcdn.jsdelivr.net always; googletagmanager.com + google-analytics.com when GA4_ID set
link sitemapWhen SITEMAP_ENABLED = true
📄 Conditional — only rendered when the variable is set
Variable Tags emitted
$og_videoog:video, og:video:type (default mp4), og:video:width, og:video:height
$fb_app_idfb:app_id + preconnect to connect.facebook.net
$google_fonts_urlpreconnect to fonts.googleapis.com + fonts.gstatic.com + <link> stylesheet
$gtm_idpreconnect to googletagmanager.com + full GTM head snippet + noscript fallback
📄 Controller Example — passing SEO variables to the layout
// In any controller:
view('product', [
    // Basic
    'title'            => 'Black Invicta 44mm Watch',
    'meta_description' => 'Invicta Prestige X: 44mm watch with Flame Fusion Crystal…',
    'meta_robots'      => 'index, follow',
    'canonical'        => 'https://example.com/products/invicta-44mm',

    // Open Graph
    'og_type'          => 'product',
    'og_image'         => 'https://example.com/imgs/og/product-1.webp',
    'og_image_width'   => 1200,
    'og_image_height'  => 630,
    'og_logo'          => 'https://example.com/assets/images/logo.webp',

    // Video (optional — omit if no video)
    'og_video'         => 'https://example.com/uploads/videos/product-1.mp4',
    'og_video_type'    => 'video/mp4',
    'og_video_width'   => 1080,
    'og_video_height'  => 1080,

    // Facebook
    'fb_app_id'        => '816733251417750',

    // Google (optional — omit if not using)
    'gtm_id'           => 'GTM-XXXXXXX',
    'google_fonts_url' => 'https://fonts.googleapis.com/css2?family=Inter&display=swap',
]);

// In a static template (PageController page), set variables before include:
// $meta_description = 'Our privacy policy.';
// $meta_robots = 'noindex, follow';
// Then: <?php include 'layouts/header.php'; ?>