REST-like URLs with PHP - php

According to what I've read about RESTful services, one is supposed to be able to get a "resource" (like a database record) using a request to a URL with the record id at the end, like this: localhost/my_records/1. Accessing such a URL would display a web page with the record information for id 1.
I need to implement something like this in PHP/Apache/MySQL but I am still relatively new to the language. The most I can manage to create is something like
localhost/my_records/index.php?id=1.
Creating a ["/id"] url seems to require creating that folder. Is there any way to achieve this?

You can have a RESTful service with any kind of URL, you don't need to do a URL with the id at the end, but this type of URL is better for convenience and good design principles.
Otherwise this type of URLs is also know as "friendly URL", most PHP frameworks provide this type of URL, for example, Symfony, Code Igniter, Laravel... provide this functionality.
If you want this type of URL without use any PHP framework, you can check this answer and responses: How to create friendly URL in php?
In my opinion, a good framework to implement a good REST Api is Code igniter + Phil Sturgeon Rest Client. More info:
http://ellislab.com/codeigniter
https://github.com/philsturgeon/codeigniter-restclient

Configure your webserver to route all requests through a single PHP script. This will allow you to parse the retrieved URL. Since you are using Apache mod_rewite is the way to go.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L]
This will route all requests for paths/files that do not exist (remove lines 2 and 3 if you want anything routed to that script) through index.php. In the script you can then access the accessed URL via $_SERVER['REQUEST_URL']

In essence what you are looking for is something commonly referred to as request routing. Typically this is implemented by a combination of configurations at both the server level and app level.
Some sort of server redirect (using RewriteRule or FallBackResource directives) which directs all requests (or requests of a certain format) to single application resource which is to handle it.
Application logic to parse the URI and HTTPS action (GET, POST, PUT, DELETE, HEAD, etc.) and determine how to route the request (i.e. which controller should handle it)
Oftentimes there is some sort of logic to format the response according to the format requested in the request headers (i.e. JSON/XML/HTML)
There are a number of PHP frameworks available which do this, that at least you could look to for guidance (if not to just use them altogether).

Related

RESTful web service using PHP

We have data in our database as book-id, title, year, price, author, category. We need to retrieve data from the database using php. We can retrieve data of a book with book-id=123 by giving the url: www.localhost/books/?book-id=123 through $_GET method. But my requirement is I want to see that information of book with book-id=123 when I give the url: www.localhost/books/123
I am using a Wamp server for this.
You will have to enable mod_rewrite for your Apache. After this you can use a rewrite rule like this:
RewriteEngine On
RewriteRule ^([^/]+)/([^/]+)$ /$1/?id=$2
in your .htaccess File. This rule would internally redirect books/123 to books/?id=123.
See also: http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
There are two approaches here.
The wrong approach:
One could be to use your webserver to provide the URL rewrite rules (like the other answer says for Apache Web Server). As the other answer suggests. But that is not the right thing to do for application portability because your application depends on your web server type to route URLs.
The right approach:
The right approach is to do application level routing and keep the routing overhead as minimum to the web server as possible. Just direct your web server to point to one entry point of your PHP application (like one index.php). It would mean a regex matching for the incoming URL paths. I would suggest using an existing framework which provides routing capabilities like Laravel to prevent any missing corner cases in regex.
For e.g, if you really want to implement yourself, what you could do is follow the following steps:
$booksRoute = /^(\/)?books(\/)?[0-9]+(\/)?$/;
route($booksRoute, function() {
// process in the closure function
});

Url representation in php

I am used to representing embedded url information like this:
http://test.com/reports/statement.php?company=ABC&q=1
how would I do it like this instead?
http://test.com/reports/ABC/Q1
You need to use Apache mod_rewrite to achieve this.
If your server has it enabled, you could do something like this in .htaccess:
RewriteEngine on
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ /statement.php?company=$1&q=$2 [L]
You can use $_SERVER['PATH_INFO'] to access anything in the URL docpath after the address of your script.
e.g.
http://test.com/reports/statement.php/ABC/Q1
...then in statement.php you would have the string "/ABC/Q1" in $_SERVER['PATH_INFO']
Of course, you'll need to setup your webserver to match the URL and target the correct script based on the HTTP request.
As stated by others, you have to use url rewriting.
Usually a php application that make use of it, it applies the pattern called Front Controller.
This means that almost every url is rewritten to point to a single file, where the $_SERVER['PATH_INFO'] is used to decide what to do, usually by matching with patterns you define for your actions, or return a 404 error if the url doesn't match any of the specified patterns.
This is called routing and every modern php framework has a component that helps doing this work.
A smart move would also be providing a tool to generate urls for your resources instead of handwriting them, so that if you change an url pattern you do not have to rewrite it everywhere.
If you need a complex routing system, check out the routing component of some major frameworks out there, e.g. Symfony2, Zend Framework 2, Auraphp.
For the simplest php router out there, check instead GluePHP. The codebase is tiny so you can make yourself an idea on how the stuff works, and even implement a small router that fits your needs if you want to.

How are personal pages on websites created using php?

When a user creates a wall on facebook for example, is there a whole new php file that is created containing the users infomation, or is their just one php file that uses mysql to gain and display the information about the user.
The reason I ask is because I notice that instead of the end directory in the url being one common php, it is always different.
Examples:
www.facebook.com/Engineering
www.facebook.com/lilwayne
Even youtube does it:
www.youtube.com/user/lonewolf456123
www.youtube.com/user/IGNentertainment
It's done with databases and URL rewriting.
They are using URI Rewriting combined with a URI router.
You can read about URI Rewriting in the Apache Docs and about routing online (each framework does it a little bit differently and some people roll out their own routers).
The big lines are:
Tell Apache to rewrite all requests pointed to non-existent resource to our router via a RewriteRule.
Let the router read $_SERVER['REQUEST_URI'] and handle the request appropriately. (In the case of MVC, you would call the proper controller depending of the REQUEST_URI).

passing GET parameters that look like URI directories

I've seen a lot of URIs that look something like this:
www.fakesite.net/stories/1234/man_invents_fire
and I was wondering if the /1234/man_invents_fire part of the URI are actually directories or if they are GET parameters (or something else). I've noticed that a lot of times the /man_invents_fire segment is unnecessary (can be removed with no consequences), which led me to believe that the /1234/ is the id number for the story in a database table (or something along those lines).
If those segments of the URI are GET parameters, is there an easy way of achieving this?
If they aren't, what is being done?
(also, I am aware that CodeIgnitor gives this kind of functionality, but I was curious to find out if it could be easily achieved without CodeIgnitor. I am, however, generally PHP, if that is relevant to an answer)
Thanks
Easiest thing to do is route everything into a main index.php file and figure out your routing from there by running $pieces = explode("/", $_SERVER['REQUEST_URI']);
After installing/enabling mod_rewrite, make sure allow override is not set to false in your apache config (to allow .htaccess to be read), then throw this in your docroot's .htaccess file.
<ifModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-s #Make sure the file doesn't actually exist (needed for not re-routing things like /images/header.jpg)
RewriteRule . /index.php [L,QSA] #re-route everything into index.php
</IfModule>
That is called url rewriting, google for it, you will find a lot of information about that.
Implementing this in PHP is typically done via an .htaccess file and using apache's mod_rewrite module.
They make the url like that so that people can easily bookmark it, and it can return safely in the search.
Depends on what language you're using to decode it. In this case, it appears "stories" is the main script, and "1234" is the id, and "man_invent_fires" is the title.
If you're using php, you can use the $_SERVER['PHP_SELF'] or $_SERVER['REQUEST_URI'] variable to decode it.
If you're planning to make a website like that, certain safety must be kept in mind. Look them up in google, but key one to look out for is sql injectors.
Just like permalinks in WordPress, this is done typically done via Apache's mod_rewrite (or an equivalent thereof if not using Apache); however, you can also use a 404 error page handler to achieve the same result (but this is not usually recommended).
Typically, all page requests are redirected to a gateway that parses the requested URI to determine if it fits the specified pattern (in your case likely to be /{category}/{article_id}/{article_title}). From there, the gateway can typically use just the article_id to retrieve the appropriate content.
Depending on the system, category and article_title can usually be thrown away/ignored and are typically for SEO value; however, in some cases category might be used to augment article_id in some way (e.g.: to determine what DB table to query, etc).
MVC's, like Zend, also use a similar technique to determine which controller and method therein to execute. An example format for this type of use is /{module}/{controller}/{method}; however, this is highly customizable.
Well, you are kind of right in assuming that the 1234 and main_invents_fire are parameters. They are not truly GET parameters in the sense that the HTTP protocol describes them but they accomplish the same task, while keeping the URL "friendly". The technique is called URL rewriting and the web is full of info on this these days..
Here's an article about friendly URLs in PHP but I'm sure googling for the topic will render more useful results.
As some background information in addition to the answers before me, a URL is just that - a 'Uniform Resource Locator'. Although in the old days, it often used to map 1:1 to a file/directory structure, all that is required in the HTTP spec is to identify a certain resource. Basically that means that, given a certain string, it should indicate a certain 'resource' on the server. In practice, in a HTTP environment this is usually implemented with a rewriting mechanism such as mod_rewrite. RFC's such as this one: http://www.ietf.org/rfc/rfc1738.txt give a nice, albeit abstract, overview. The concepts only come to life after designing and implementing some non-obvious uses, though.
If you are using Symfony, then you can use the routing feature to do this.

Creating a RESTful API and website with PHP

I've got a PHP application I wrote earlier that I'd like to add a RESTful API to. I'd also like to expand the site to behave more like a Rails application in terms of the URLs you call to get the items in the system.
Is there any way to call items in PHP in a Railsy way without creating all kinds of folders and index pages? How can I call information in PHP without using a GET query tag?
If you have some form of mod_rewrite going you can do this quite easily with a .htaccess file.
If you have something like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
It will check that the file you are trying to access doesn't exist already. (Say you had a file hello.html that you still needed people to access via http://yoursite.com/hello.html)
Then if the file doesn't already exist it will load your index.php file with the rest of the URL stored in the url variable.
This means you can call something like this http://yoursite.com/pages/edit/24 and it will load index.php with /pages/edit/24 inside the url variable.
That should get you started and you won't need all kinds of folders and index pages, just mod_rewrite, .htaccess file and an index.php that will be used to load whatever you need.
You also might consider to use one of the PHP frameworks with built-in REST support, for example CakePHP.
Quick note in respopnse to Pascal MARTIN: Zend_Rest_Server has absolutely nothing to do with REST. They just do RPC with slightly nicer URLs and call it REST so that it's more trendy.
If you want to do REST, you'll need to do a bit more work yourself as I have not found a good REST library for PHP yet. So inspect $_SERVER['REQUEST_METHOD'] to decide what to do with the called resource, etcetera.
Easiest way would probably using a framework that provides you with REST-oriented functionnalities. I know Zend Framework does that, with the class Zend_Rest_Server, that allows easy creation of a REST server.
I suppose many other frameworks do just the same.
But, if you already have an application that doesn't use a framework (or that is based on a Framework that doesn't embed that kind of class), a couple of URLrEwriting rules would do just fine ; you'd just have a bit more work to map URLS/parameters to classes/methods :-(
The design pattern you are looking for is called a front controller.
In its simplest form you use mod_rewrite to pass the incoming requests and pass it to a single php script. The url is then parsed with regular expressions and mapped to different response actions. However mapping an existing application may require extensive rewriting.
If you want to play around with this concept I recommend the Silex microframework.

Categories