I have been reading the article to learn how to build a rest API:
http://www.gen-x-design.com/archives/create-a-rest-api-with-php/
At one point it says "Assuming you’ve routed your request to the correct controller for users"
How can I do this without a framework?
I am writing a REST API that I can interact with from a different application. I ready the tutorial above, and it makes sense mostly, but I don't exactly understand what it means to route my request to the correct controller for users.
Assuming you are using Apache, you can accomplish this easily using a combination of mod_rewrite and some PHP-based logic. For example, in your .htaccess or vhost definition, you could route all requests through a single handler, possibly index.php:
# Don't rewrite requests for e.g. assets
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*+)$ index.php?q=$1 [L]
...then in your index.php file do something like:
$target = $_REQUEST['q'];
/* parse the request and include the appropriate controller PHP */
For example, a request for /products/1234 might result in a controllers/products.php handler being included. That handler could then act on product 1234. Because you're using REST, you shouldn't need to be concerned with the original request having a query string parameter.
There are multiple ways to accomplish what it sounds like you're trying to do, this is just one of them. Ultimately what you go with will depend on what your specific requirements dictate. The above pattern is fairly common however, many frameworks use it or something like it.
I think this is a matter of terminology. Every code with some level of generalization can be called "framework". And since you're asking about "routing", which provides a starting level of generalization, every implementation becomes a framework.
If you don't want to use existing fully-fledged frameworks, you can elaborate your own light-weight-implementation. Here is some articles to start:
Write your own PHP MVC framework
PHP MVC framework in one hour
(the author has decided to remove this post because he thinks that using a modern fully-fledged framework is more appropriate way of programming such things, yet some people find such simple and stripped-down approache more suitable in many aspects: learning, efficiency, no huge dependencies, etc); the post is available on some other sites, for example, in the wayback machine or copies
The Model View Controller in PHP
All these intros include explanations of the routing mechanizm and demonstrate its implementation.
Basically, a router is a kind of internal "DNS" (in a figurative sense) inside your application. When a request arrives to your site, you need to dispatch it to appropriate worker class, according to that request properties. This is the router's task.
Related
Is it bad to use index.php as loader for other scripts or does it make a difference?
i.e. requesting index.php with different query strings and inside it, selecting and including the matching script.
e.g.
www.example.com/?sign-in insteade of www.example.com/sign-in.php
www.example.com/?new-post insteade of www.example.com/new-post.php
In this way you can use index.php to do the common inclusions and processes, like, setting timezone, mb encoding, DB connection, auth, etc..
Best practice is to let apache rewrite all urls to an index.php or some other file which you can use as bootstrap. This bootstrap runs all the basic code and then this bootstrap can figure out which other actions to take based on the url.
Every framework works like this.
several things you might want to do in the bootstrap:
setup, autoloading classes
setup mysql connection
check if user is authenticated for a certain action
There are many tutorials on rewriting urls with apache: http://www.workingwith.me.uk/articles/scripting/mod_rewrite
If you really want to learn about best practices i would suggest looking at existing frameworks, at how they implement certain things. eg: Zend or Symfony
Yes and No
The problem is that by doing it you will lose any SEO value, eg: domain.com/index.php?post=story will rank very poorly against domain.com/post/story . Also your index.php is going to get messy very quickly.
That being said MVC's usually use a index.php, so my url would be domain.com/users/edit/123 which is a very logical url, but what actually gets called is domain.com/index.php , it then looks at the first paramater, "users" and instantiates the user controller and then looks for the function edit inside that and passes the "123" (user id) as the first parameter in the function. If you are not familiar with MVC's I would advise codeigniter as a starting one, more on codeigniter.
In the end you will just be re-inventing the wheel by building it from scratch, rather use a MVC make development much easier.
This is the best approach. You can take control of your website.
Create index.php and include other files on demand.
(Define a constant and use it in included files and so on)
But keep in mind to minimize index.php as much as possible.
Also you can use Apache mod_rewrite to generate SEO friendly URL.
Instead of routing all your requests (through htaccess) to index.php you can also split the routes to map to other files:
/blog/hello-there mapping to blog.php?title=hello-there
/sign/in mapping to login.php?login
etc, thus you create your own simple routing based on the request URL; easy to read and easy to maintain.
This solution is suitable in small projects, for bigger project I advise to use a complete framework like Yii or Symfony.
I’m in the process of learning to use the Zend Framework, and I’m therefore trying to grasp the concept of MVC. Through the Zend manual, and a very helpful Youtube video tutorial I have sort of understood the concept – still there are some things I need to clarify.
The web project I’m currently working on is a web site for an organization I’m a part of. It consists of:
The public portion, mainly consisting of information about us, a calendar and some media – mostly static information, but a couple of pages, like the calendar, will need to retrieve some data from the DB.
The internal pages, which after a login will allow users to RSVP to events and comment them as well.
The administrative controls , allows the admins to add events and manage users etc.
So far it looks like Zend wants the URL to look like this:
http?://[domain]/[controller]/[action]
So here are my questions:
Do I always have to have an action in the url, or will the lack of an action use the index-action as default?
Can I have a subdirectory to distinguish between the internal and public portions of the site: http://[domain]/internal/[controller]/[action] ?
Can this be done simply by having a subfolder within the different MVC-folders somehow?
The latter question isn’t really that important, but I’d like to separate the two portions of the site somehow.
Do I always have to have an action in the url, or will the lack of an action use the index-action as default?
A controller can have a default action which is triggered when no action is specified in the URL. Look for default action or index action.
Can I have a subdirectory to distinguish between the internal and public portions of the site: http://[domain]/internal/[controller]/[action] ?
Yes you can have, but I assume subdirectory refers to your URL, not to the actual file-layout on the server. You can do so by just having a controller per "subdirectory".
Can this be done simply by having a subfolder within the different MVC-folders somehow? The latter question isn’t really that important, but I’d like to separate the two portions of the site somehow.
You can separate per controller and you can even separate with modules. As far as I know of modules in zend-framework, this will all be in it's own sudirectory per module.
I think you're especially looking for Using a Conventional Modular Directory Structure.
The questions you are asking are in the area of routing which generally means: Given a URL on which the HTTP request is being made:
Which controller should be instantiated?
Which action on that controller should be run?
What parameters should be passed to the action?
The routing docs in the ZF Manual explain how routing works by default and how you can specify your own routing. But looking at them now, I don't think they do a great job of introducing the subject matter for a first time user. This post might be better, though it is only a single, simple example.
I am a beginner with PHP but I know most of the basics. I currently have an API for my website, coded myself, of which I can call different methods with different parameters and they will scour my databases for the relevant information.
However I want to convert it to REST.
So instead of having requests like this http://mywebsite.com/api/?param=allPosts I would have something like http://mywebsite.com/api/posts/. I would do this for each of my 23 different params.
How could I do this?
One way would be to use a micro framework for routing. This would 'point' url request patterns to relevant php files (controllers) to manage those requests and serve content (or perform CRUD operations, or whatever it is your API does).
There's a good post here with some discussion and further links.
https://stackoverflow.com/questions/115629/simplest-php-routing-framework
I'm currently in the process of using the framework Silex for this exact purpose
http://silex-project.org/
It may be that you wish to convert your PHP application to use one of the many frameworks out there (which will handle routing amongst other things).
The usual suspects are
CakePHP
Codeigniter
Symfony
Lithium
and there are many more...
This is not strictly speaking RESTful that is just prettifying your URL's.
To "Prettify" your URL's you could implement something like this:
Trim your base URL of the start of the request
explode the remaining string by the "/" component
The first component (normally) is related to your controller
The next component is your action in this case equivalent to how your using ?param=allPosts
RESTful routing is based around the idea of using the different HTTP verbs (GET/POST/PUT/DELETE) to decide what actions to take on your resources on the server. Wikipedia has a good overview.
One way would be to use apache's mod_rewrite to effectively convert the second type of request to the first. It's not necessarily ideal, but it's a pretty straightforward solution to your problem.
I'm developing my first decent-sized PHP site, and I'm a bit confused about what the "right way" (assuming there ever is such a thing) to handle clean/friendly/pretty URLs in the application.
The way I see it, there are two main options (I'll use a simplified social news site as an example):
1. Use mod_rewrite to handle all potential URLs. This would look similar, but not identical, to the following:
RewriteRule ^article/?([^/]*)/?([^/]*)/?([^/]*) /content/articles.php?articleid=$1&slug=$2
RewriteRule ^users/?([^/]*)/?([^/]*) /content/users.php?userid=$1&username=$2
RewriteRule ^search/?([^/]*)/? /content/search.php?query=$1
2. Pass everything to some handler script and let it worry about the details:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) handler.php?content=$1
Clearly this is all untested "air code," but you get the point.
Is one of these two ways going to be seriously slower than the other? Presumably the mod_rewrite is slower, since I'll be forced to use .htaccess files for this.
Are there serious disadvantages to either of these approaches?
Is there a "best practice" for this sort of thing, or is it something that each developer tends to decide for themselves? I know WordPress uses option two (though it was more trouble than it was worth when I investigated exactly how they did it).
Option 1 (.htaccess and several .php files) was often used "in the past" ; now, I see option 2 (every request going through one .php file) used a lot more.
The main advantages I see with option 2 are :
you can add / modify any kind of URL without having to change any physical file like .htaccess
which means the format of the URLs can be configured in the admin section of your application, for example
you only have one entry point to your PHP code.
which means everything goes though index.php : if you need some code executed for all requests, put it there, and you're sure it'll always be executed.
That's used a lot with MVC frameworks, for instance.
A couple of years ago, I would have gone with option 1 ; now that I use MVC and Frameworks, I always go with option 2.
Really this is the "are frameworks worth using?" question in disguise.
Using mod_rewrite to define your URL routes is quick and easy (if you understand regular expressions...) but your application code is oblivious to the URLs unless you duplicate the information somewhere.
Usually, people duplicate this information many times without thinking about it, by hard-coding URLs in the links in their views, or in redirects. This is really messy, and will one day cause pain when you decide to change the URL structure of your site halfway through development. You're bound to miss one and end up with a 404 somewhere.
Using a routing component in your application (such as the one in Symfony) means you can attach names to your routes, allowing you to define your URLs once and re-use them many times:
# apps/frontend/config/routing.yml
homepage:
url: /
param: { module: default, action: index }
This makes it really easy to link to pages of your site without repeating yourself:
<?php echo url_for('#homepage') ?>
Use option #2 - why? RewriteRules in .htaccess are powerful tool, but they're some kind of static. I mean you cannot easily manage then using PHP (or whatever you're going to use). Also .htaccess doesn't provide so much flexibility, but has some advantages (for example: it's a bit faster).
Option #2 also need .htaccess as you noticed, but in most cases RewriteRule takes the following form:
RewriteRule (.\*) index.php
Where index.php is your front controller.
The biggest advantage (IMO) of this soultion is that each route is described in PHP (or whatever you use) so accessing these routes, modifying them is much easier. Furthermore these routes can be used then not only for changing URL into set of variables, but also in opposite way - to create URL from set of variables.
I think the following example (from Symfony framework) will explain what I am talking about:
// apps/.../config/routing.yml - Describes routing rules
post:
url: /read/:id/:slug
params: { module: blog, action: index }
requirements: { id: \d+, slug: \w+ }
// apps/.../modules/blog/templates/indexSuccess.php - template for index action
<?php echo link_to($post['title'], '#post?id=' . $post['id'] . '&slug=' . $post['slug']); ?>
//creates: My first blog post
Now whenever you change your rounting.yml file and change /read/:id/:slug into /:slug_:id all your links in application will turn into /my-first-blog-post_123.html.
Doing such and others things when you use option #2 is much easier.
As far as I can see, any possible performance differences between those methods are really minuscule and relevant only for really, really high-traffic sites.
I think there is no "best practice" as such, both methods are equally often used. If your project structure allows it, and you're more at home with parsing the URL in PHP (where the rest of your project is), put everything through one controller file, and let your application handle the rest.
If performance is really of the essence, I suspect that having Apache handle the addresses is faster, because there is no interpreted language in between. (I have no hard data for this, though). But as I said, you're probably best of choosing whichever is going to be most maintainable for you in the long term.
Clean pretty URLs appear to be provided by PHP-script-based popular content management system Drupal using a combination of modrewrite rules in .htaccess and plug-in PHP Drupal modules such as path and pathauto.
Given the success and popularity of this tool - and its ability to run on the most modest of shared hosting, I think this would be your answer.
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.