{"id":17662955,"url":"https://github.com/genebean/php-sub-site-demo","last_synced_at":"2025-08-13T01:09:37.775Z","repository":{"id":141759413,"uuid":"48217418","full_name":"genebean/php-sub-site-demo","owner":"genebean","description":"This is a demo of having a site inside a site and letting PHP figure out where each site's root is.","archived":false,"fork":false,"pushed_at":"2015-12-20T16:11:58.000Z","size":12,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T11:44:46.856Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/genebean.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-18T06:00:15.000Z","updated_at":"2015-12-18T06:03:47.000Z","dependencies_parsed_at":"2023-03-20T15:19:09.740Z","dependency_job_id":null,"html_url":"https://github.com/genebean/php-sub-site-demo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/genebean/php-sub-site-demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/genebean%2Fphp-sub-site-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/genebean%2Fphp-sub-site-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/genebean%2Fphp-sub-site-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/genebean%2Fphp-sub-site-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/genebean","download_url":"https://codeload.github.com/genebean/php-sub-site-demo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/genebean%2Fphp-sub-site-demo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270161401,"owners_count":24537645,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-23T18:42:23.617Z","updated_at":"2025-08-13T01:09:37.733Z","avatar_url":"https://github.com/genebean.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"This is a demo of having a site inside a site and letting PHP figure out where\neach site's root is. This can be handy when you do not know ahead of time\nwhether your files will be in the document root or in a subfolder. Once the\n\"real_root\" is found it is used to prefix any PHP or HTML includes. The\nstructure of the demo site looks like this:\n\n```bash\n$ tree -a\n.\n├── css\n│   └── style.css\n├── .docroot              # \u003c-- denotes a sites's root directory\n├── footer.php\n├── index.php\n├── README.md\n├── root-finder.php\n└── site2                 # \u003c-- this is the start of a nested site\n    ├── css\n    ├── .docroot          # \u003c-- denotes a sites's root directory\n    ├── footer.php\n    ├── index.php\n    ├── root-finder.php\n    └── sub3sub3\n        └── index.php\n```\n\nThe trick here is the placing of a `.docroot` in the root directory of each\nsite. PHP works up the tree until it finds this or it hits the web server's\ndocument root. Once the root has been found it creates two PHP variables:\n`$real_root` and `$url_prefix`. The first is the real file path to the site's\ndocument root while the second is what to prefix URL's on your site with. Full\nexamples of both being used are in the three `index.php pages`.\n\n\n### Use Case: Built-in PHP Webserver\n\nIn production your site is in the document root but while testing it is not.\nIf you use the webserver built into PHP your files are in the document root but\nthe URL is prefixed like\n[http://localhost:63342/php-sub-site-demo/index.php][demo-site] which would\nbreak a accessing CSS at `/css/style.css` because it would actually be at\n`/php-sub-site-demo/css/style.css`.\n\n\n### Use Case: Test server with each site in a sub directory\n\nIf you run your web sites with SSL then it is not practical to just make a\nsub-domain for each site on your test server like many people have traditionally\ndone because you would have to buy a cert for each one if you want to avoid SSL\nerrors in your browsers. An alternate setup is to create a single document root\nand place each site in a sub-folder. In this scenario you might end up with a\nstructure like the following in production:  \n\n```bash\n├── site1.example.com (this is a document root)\n├── site2.example.com (this is a document root)\n└── site3.example.com (this is a document root)\n```\n\nIn your test environment, these same sites might also have multiple branches\nas you work on new features and hotfixes. This might give you a structure like\nso:\n\n```bash\n└── test.example.com (this is a document root)\n    ├── test.example.com/index.php (provides links to all sub-sites)\n    ├── test.example.com/site1__master/index.php\n    ├── test.example.com/site1__develop/index.php\n    ├── test.example.com/site1__feature__cool_new_thing/index.php\n    ├── test.example.com/site1__feature__new_form/index.php\n    ├── test.example.com/site1__hotfix__1.0.1/index.php\n    |\n    ├── test.example.com/site2__master/index.php\n    ├── test.example.com/site2__develop/index.php\n    |\n    ├── test.example.com/site3__master/index.php\n    └── test.example.com/site3__develop/index.php\n```\n\n\n### How using `root-finder.php` helps\n\nThe code in `root-finder.php` allows you to solve both of these issues. The\nfirst can be solved by using the include on the first line in the code below and\ncombining that with the css reference shown. The pathing for additional includes\nis demonstrated with the footer in the code samples. Sample 1 is in your root\ndirectory while sample 2 is in a sub-folder. Take note that the only difference\nbetween the two is on the first line.\n\n\n#### Sample 1 (site index page):\n\n```php\n\u003c?php require 'root-finder.php' ?\u003e\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n    \u003clink rel=\"stylesheet\" type=\"text/css\" href=\"\u003c?php echo $url_prefix;?\u003ecss/style.css\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003cp\u003e Hello World\u003c/p\u003e\n    \u003c?php require $real_root . 'footer.php'; ?\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n\n#### Sample 2 (sub-folder index page):\n\n```php\n\u003c?php require '../root-finder.php' ?\u003e\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n    \u003clink rel=\"stylesheet\" type=\"text/css\" href=\"\u003c?php echo $url_prefix;?\u003ecss/style.css\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003cp\u003e Hello World\u003c/p\u003e\n    \u003c?php require $real_root . 'footer.php'; ?\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n[demo-site]: http://localhost:63342/php-sub-site-demo/index.php\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgenebean%2Fphp-sub-site-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgenebean%2Fphp-sub-site-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgenebean%2Fphp-sub-site-demo/lists"}