Avoid automatic PHP routing in a MVC - php

I am using a MVC and on my application file, I am routing this way :
# Routing
$routing = array(
'([a-zA-Z]+)\/?' => array('Post', 'view')
);
framework::routing($routing);
It means that all the URLs like "mysite.com/anything/" will be routed to the same template but with different content. Until then, everything is okay.
My problem is that I would like to make an exception for that,
because I want to access my page "mysite.com/uploads" directly into the browser, but I am redirected, due to the routing php stuff.
Is there a way to make an exception to this routing? Like route all names excepted "upload" ?
I can submit the routing file, but since it's almost the same than codeigniter maybe you won't need it really.
Thanks

Seeing that your urls don't contain the index.php part anymore, I guess that you added an .htaccess file to do that, probably one that looks like this (straight from the codeigniter docs):
RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
If this is that case and the uploads folder is in the same folder as the root index.php file of codeigniter, you should change the second line to:
RewriteCond $1 !^(index\.php|images|uploads|robots\.txt)
But this all depends on your specific configuration.
EDIT: Altough it seems that you aren't using CodeIgniter, the same applies to Zend Framework MVC. You should make an exception to the rewrite rules to allow direct access to your upload directory.

Related

Can Symfony 4 be configured to ignore code installed in subdirectories?

I'm currently converting an old website to use Symfony 4 and the site uses the LiveZilla live chat app.
LiveZilla lives in a subfolder of the site, and is accessed directly using URLs under somesite.com/livezilla. I can't currently access it of course, because I haven't configured a route for this folder. So Symfony decides that this will be a 404.
LiveZilla is essentially a completely separate app living in its own folder here. It isn't dependent on the website hosting it. Is there a way to tell Symfony to ignore certain paths so that code like this can be executed without interference?
I have a sneaking feeling that I need to adjust the way I am looking at this as I can't find anything obvious in the Symfony docs about this, and the framework is pretty well thought out. The best I have come up with so far is hacking public/.htaccess, but it feels wrong somehow...
Your .htaccess file should allow requests directly to existing files, but not directories. See this rule:
# If the requested filename exists, simply serve it.
# We only want to let Apache serve files and not directories.
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
This means you should be able to access somesite.com/livezilla/index.php but a request to somesite.com/livezilla will redirect to the symfony front controller. So try changing your links to point to actual files within the sub-directory.
There is also nothing wrong with editing the .htaccess file to suit your needs. You just need a condition that checks if the request is to the sub-directory and if so use the same RewriteRule ^ - [L] as above to allow that request to continue.
The following should work if placed after the above rule (reference):
RewriteCond %{REQUEST_URI} ^/livezilla/
RewriteRule ^ - [L]
Or this may be better, place this rule immediately after the line RewriteEngine On(reference)
RewriteRule ^(livezilla) - [L]
The [L] flag means the rule will be the last one used for the request.

Rewrite_Mod models and views to sub-domain using htaccess

Ok so I kind of understand that htaccess uses regular expressions and a series of conditions and rules, but am having trouble writing something that will work for what i'm looking for.
I have two domains in the same parent folder and want to be able to use some of the models and views from domain.com on sub-domain.com with codeinighter being used on both. Lately i've been creating a view in the sub-domain's directory and then using a "require_once" tag to import the models and views". However, as the project goes on, I find it very annoying to have to create each file separately.
Is there a way I can use htaccess to make it so codeignighter on the sub-domain knows to look in /domain.com/application/models/ and /domain.com/application/views/ if one cannot be found in the sub-domain, while also keeping the /index.php/test --> /test mapping in place.
RewriteEngine on
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
parent (not actual directory name, not sure if this even matters)
domain.com
application
models
views
api.domain.com
application
models
views
This .htaccess is getting too complicated for me to understand and any help on this topic is helpful. I'm not even sure if htaccess can tell php to do this or if it's even possible. Perhaps that's the problem? Thanks!
with htaccess your options are pretty limited. yes you can define some routing, and yes you could try defining variables in your htaccess that you can later access with php, but that wouldn't allow you to access models or views in the manner you want e.g. looking in 2 paths for one file.
to do that, you would have to modify the way codeigniter loads models and views. if you take a look under the hood in system/core/Loader.php you'll see a bunch of variables at the top. some of which, contain constants that are defined in index.php which indicate paths:
protected $_ci_model_paths = array(APPPATH);
you would either have to "hack" this file, or extend it and modify the corresponding variables to contain array('path1', 'path2') so CI would know where to look.
with regards to routing, I'm not sure how you plan on handling that, but it could get messy.
you might want to look in to an hmvc approach. maybe you don't want to use hmvc, but the way they modify loading paths would be useful to you.

PHP framework work flow

I am confused about how a php framework works with a web server like apache. Now if there wasn't a framework and if it was using classic php, then I understand how it works(if a php file is requested, the php parser executes it and returns the htm to the server).
When a framework like cakePHP is used, I have noticed that no matter which url the client requests, the index.php in the root folder gets executed first. How is this possible? if we were using pure php then, only the file we requested will get executed. So how does cakePHP make each and every request to go through the /index.php file?
CakePHP, and many other websites, leverage mod_rewrite which is an Apache module that "Provides a rule-based rewriting engine to rewrite requested URLs on the fly".
To do so, the web framework will use a .htaccess file with specific rules defined. These rules, in the case you're asking about, point any URL matching a specific pattern to to a real index.php file (this file can be named anything really, but index.php is a good "default" name).
Per CakePHP's URL Rewriting outline, a base rule is defined as:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/to/cake/app
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
What the above does is:
Turns on the rewrite module
Sets two conditions for rewriting the current URL
a. Only if the requested file is not a real directory (!-d)
b. Only if the requested file is not a real file (!-f)
Sends the full requested URL, (.*) to index.php
Sometimes, you'll see the RewriteRule line as:
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
This will set the requested url into the $_GET['url'] parameter instead of forcing the application to process the $_SERVER['REQUEST_URI']. Other times, there will be a lot of rewrite rules, some complicated, some basic.
There are a lot of good resources online, and in books, regarding mod_rewrite. Check out Introduction to URL Rewriting for one (it's one I have bookmarked, has a lot of good basic rules / formats).
That's a pretty simple one (https://github.com/gilbitron/PIP).
Read the files in the System folder.
Basically it goes like this:
All requests are sent to the index file (with mod_rewrite, or like a plain get parameter).
The index file includes configuration files and definitions of constants.
Then it loads the main class for the framerwork.
The main class does some configurations, initiates a database connection and so on.
Depending on how it is implemented, there might be a router but it's possible there isn't.If there is one the main class checks what controller should be loaded against the request in the router.
Then the main class loads the controller that should be loaded with that particular request.
PIP is not that good and the main class is actually not a class but you can get the point in it.
You can also read about the following things:
Object oriented programming: http://php.net/manual/en/language.oop5.php
Scopes: http://php.net/manual/en/language.variables.scope.php
Autoloading classes: http://php.net/manual/en/language.oop5.autoload.php
You mentioned
"I have noticed that no matter which url the client requests, the index.php in the root folder gets executed first."
This is what front controllers do. You can have a front controller with a framework or if coding from scratch using the .htaccess file. Front controllers enable rendering of pages using PHP functions/methods, such as $app->get($uri, $callback); in Lumen.

How to understand PHP's URL parsing/routing?

I just inherited a website built in PHP. The main page of www.mysite.com has a href to www.mysite.com/index/35.html somewhere in the page. In the site's root directory and its children there is no document 35.html.
The number 35 is actually an id found in a DB which also holds the html contents of the page.
If I load URL: www.mysite.com/index.php?id=35 the same page loads.
How does PHP know how to automatically convert
/index/35.html
to
/index.php?id=35
EDIT
Based on the answers, I have found a .htaccess file containing rewrite instructions that would explain the functionality.
However, IIS doesn't seem to (or is not configured) know how to use this. (probably because this is an Apache feature?)
So this begs the following question: Is there a way to configure IIS to work with this?
it will be done usign URL Rewriting using .htaccess - should be in the webroot.
It may look something like:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
May have other bits, but what this basically tells apache is to send anything that DOES NOT physically exist to index.php
It doesn't. There is a mod_rewrite rule that rewrites from /index/foo to /index.php?id=foo, either in a .htaccess file somewhere or in the httpd configuration itself.
RewriteEngine On
RewriteRule ^index/([\d]+)\.html /index.php?id=$1 [NC,L]
This is off the top of my head. Any browsers trying to load an address starting with index/ has any number ending in .html will be internally redirected to index.php?id= whatever the number is.
Edit: Just saw that your working on IIS. This probably won't work for you. Sorry.
I think you will be using .htaccess to redirect all requests to index.php. From there You can pass the query string a routing class, which will parse the url and identify the unique ids.
In this case we can say like, your routing class will parse the request /index/35.html to indexController, indexAction, id=35. now you can pass this id to the model to get corresponding page contents
NB : Here I a am assuming you are using mvc pattern. Anyway it can be treated in your own way, with the concept remaining the same. Hope this make sence.

Alias Domain to Zend Directory

I have a ZF website at domainA.com and I'd like to alias domainB.com to something like: domainA.com/photos/album so that album would be the root of domainB.
How might this be accomplished?
The first step here is to rewrite the URL to the correct route using mod_rewrite. Something like the following at the top of your exisitng .htaccess root should work:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} =domainB.com [NC]
RewriteCond %{REQUEST_URI} !^/photos/album
RewriteRule .* /photos/album/$0 [L]
This will redirect to /photos/album/ if no path is specified after domainB.com. If I remember correctly, Zend Framework isn't picky about whether your controllers/actions are terminated by a slash or not, so this should be fine. If it needs to be /photos/album for some reason, I have a solution for that as well, but it's overkill if it's not needed.
Later, your ruleset translates the URL to index.php, and Zend Framework does its routing. However, the default way Zend Framework does routing is to use REQUEST_URI, which happens to not be what we want in this case (It will be whatever was passed after domainB.com, instead of what we rewrote the request to). We actually need to use REDIRECT_URL, which is set by our new RewriteRule.
The controller request documentation describes this scenario (kind of), and explains that you can use Zend_Controller_Request_Apache404 as a drop-in request object to obtain the correct route information:
$request = new Zend_Controller_Request_Apache404();
$front->setRequest($request);
I'm fairly certain that you could also just get the current request object, and call
$request->setRequestUri($_SERVER['REDIRECT_URL']);
on it. Just condition this operation on the host, and hopefully it should all work out correctly.

Categories