Most PHP shop scripts I've seen make one annoying assumption: they expect to live in exactly one folder, on exactly one domain, forever. Move them, and you're editing config constants by hand.
I wanted Shop CMS to just work — root domain or subfolder, no manual path config — so I spent time on the boring-but-critical plumbing before touching any storefront features.
The base-path problem
Most PHP scripts hardcode something like:
define('SH_BASE_PATH', '/shop');
That's fine until you install to a different folder, or straight to a domain root, and every asset/link breaks.
The fix is to detect it from the request itself:
function sh_resolve_base_path(): string
{
$script = str_replace('\\', '/', (string) ($_SERVER['SCRIPT_NAME'] ?? '/index.php'));
$dir = rtrim(dirname($script), '/');
// Strip known subfolders so admin/api requests resolve back to the site root
foreach (['/admin/api', '/admin', '/api'] as $suffix) {
if ($suffix !== '' && str_ends_with($dir, $suffix)) {
$dir = substr($dir, 0, -strlen($suffix));
break;
}
}
return ($dir === '' || $dir === '.') ? '' : $dir;
}
Every internal URL builder (sh_url(), asset paths, .htaccess rewrite rules) then goes through this instead of a hardcoded constant. Install to public_html/ or public_html/shop/ — same zip, zero edits.
Keeping the .htaccess portable too
The Apache side needed the same treatment. Dropping an explicit RewriteBase /shop/ breaks a root install; omitting it lets mod_rewrite infer the base from wherever the file actually sits:
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^product/([a-z][a-z0-9_-]*)/?$ product.php?id=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^$ index.php [L]
RewriteRule ^sitemap\.xml$ sitemap-index.php [L]
RewriteRule . 404.php [L]
</IfModule>
No absolute paths anywhere in the ruleset.
What else is in there
Beyond the install flexibility, the script ended up with:
-
6-language storefront (Norwegian default, English, Ukrainian, Russian, Swedish, Lithuanian) with a modular
lang/*.phpsystem - MySQL storage with a web installer that seeds demo products/categories so you're not staring at an empty catalog
- Optional AI content tools — bring your own Grok/OpenAI key for product copy, SEO meta and translations; works with local fallback templates if you don't
- Stripe / PayPal / Vipps / COD checkout, Schema.org markup, XML sitemap, GDPR cookie consent
It's PHP 8+, no framework — just organized enough to actually maintain.
Try it / grab it
Live preview: https://bilohash.com/shop/
Full source (one-time purchase, no trial, no subscription): https://bilohash.gumroad.com/l/shop_cms
Happy to answer questions about the base-path detection approach or anything else in the comments.
Top comments (0)