As many of you know when someone creates a StackOverflow question a new page is generated and it is visible in the various search engines as well. I was wondering how PHP code created these pages. It turns out that most websites like this have one page, something like profile.php and it loads the data from a MySQL database. My question is as follows: If there is only one physical file how can the URL change and how does google list all of the pages/profiles/question from sites like StackOverflow or Facebook if there is only one actual page?
You tell search engines 'Google, Bing, ..etc' for example to see your website by giving them sitemap.xml
listing your pages, allow their web-bots (spider) access too the site and crawl the data and links, you may have one page like posts.php
and it is different with parameters posts.php?id=123
or posts.php?name=mypost
Edited: If you want use one file posts.php
and make site http://domain.com/posts/posttitle
you need to apply Front Controller Pattern site point link and this implies setting you server Apache/Nginx to redirect the requests to one file (URL rewrite) and this file contain the logic for handle the request or use MVC framework
Apache (and therefore PHP) uses Mod_Rewrite to rewrite the URLs to more readable directory-like names. For example, you can use it to turn
www.example.com/index.php?area=blog&which=entry
into
www.example.com/blog/entry
The HTTP headers do not have to match the actual filesystem, so Apache 'spoofs' them into whatever it wants.
It's probably possible to do without mod_rewrite, but I don't know enough to say
Look at the URL for the page this very question is on:
http://stackoverflow.com/questions/39457314/how-does-php-create-new-html-pages
There isn't a physical file on the server's harddrive for it. There's just one master script called "show a question page". What will happen, in general, for a dynamically generated page:
url gets changed from a "friendly" URL to an "ugly" internal one. While Stackoverflow isn't written in PHP, if it was, you'd end up with something like this internally:
http://stackoverflow.com/showquestion.php?id=39457314
Webserver executes the showquestion.php
script
As comments have implied, this is handled by URL rewrites in the HTTP server.
It may help to know that an URL corresponds to a physical PHP file of the same pathname by default, but this can be overridden. You can create Apache rewrite rules so that an URL request is handled by any PHP script.
An example is shown in https://framework.zend.com/manual/1.12/en/project-structure.rewrite.html:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
So all URLs are really handled by index.php
, regardless of what the URL says. In that script, the code can read the original request, and then code can decide what the components of that request mean to the application.
The answer is routing.
Take an example url... httml://www.mysite.com/users/profile/jimmy
If you are using a routing system (most frameworks have one) then whatever comes after the .com/ (called the 'path') is treated like a map. The routing system uses this map to find the data.
Many routing systems break this 'path' up into segments. The example above would be broken into the following segments.
For most frameworks the routing system would interpret the map like this...
controller/action/param-1/param-2/param-3
'Controller' refers to a 'class' in object oriented PHP
'Action' is another word for a 'function', and is also called a 'method'
finally the parameters refer to the data we want to pass around, perhaps it is a name, usually it is an id.
The router will take the example 'path' above and go searching like this...
Takes segment one. Looks for a 'class' called users. Finds class called users. Looks for function called profile inside class called users. Finds profile function. Passes the data into the function. Executes function with the passed data.
Here is a basic code structure that the router would search
<?php
class Users // the controller
{
function profile($name) // the action
{
'Profile for ' . $name; // the passed data 'jimmy'
}
}