Rewrite_Mod models and views to sub-domain using htaccess - php

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.

Related

How to create dynamic webpage with custom name?

I have looked around and attempted my own research on this topic but to no avail just yet.
I have a dynamic webpage set up to look for a ID from a database to retrieve elements required. This results in of course the web page looking like www.site.com/page?id=1
My desired outcome would be like a title for this page to be called.
Such as say I had a fruit product it and user went to my site and went to the address /fruit it would it would be the content of ?id=1 just as an example.
I have seen this used on many a site but not sure how this is programmed or works. Is this something to do with a htaccess document?
Thanks in advance. Appreciate all the help.
While this has been asked and answered many times, I know many people find it difficult to search for this since there are so many common "noise" words related to it. For that reason, I believe it's worth answering again.
If you're using Apache as your webserver (which I'm assuming you are since you mention .htaccess), what you're looking for to create those "clean URLs" is mod_rewrite, which takes a set of rules and rewrites the URL requested by the browser to another path or script.
You would typically enable this in your Apache config or in .htaccess, and in a simple form (a one-to-one mapping) at it would look something like this (provided mod_rewrite is installed):
RewriteEngine On
RewriteRule ^fruit$ index.php?type=1 [L]
Now obviously that doesn't scale well if you have a bunch of dynamic pages you want to create, so what you can do is tell all pages that aren't a really file or directory to be passed to a file for processing, like so:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]
In this case we're rewriting any request that doesn't resolve to a real file or directory to index.php, and then using the "last" flag [L] to stop processing other rules. Then in our PHP script, we can access the virtual path (in this case /fruit) by using $_SERVER['PATH_INFO'] and doing whatever conditional logic we want with that. If you don't get anything in that variable, ensure that the AcceptPathInfo On directive is set in your Apache config or .htaccess.
A way to test the basic concept/logic without having any rewrite rules would be to use a URL like https://example.com/index.php/fruit. You'll then see that in index.php $_SERVER['PATH_INFO'] will contain the string /fruit. You can rewrite URLs to files in other directories, chain rewrite rules, redirect the browser to other URLs, or even edit environment variables.
There are many good tutorials around using mod_rewrite for clean URLs, so I won't attempt to cover all the nuances here. Just know that it's a very powerful tool, but it's also pretty easy to break your rules if you aren't very comfortable with regular expressions or get lost in the many rules that are commonly in a configuration.
Note that if this is an existing site, you'll also want to use mod_rewrite or mod_redirect to redirect the old URLs to the new ones so they don't break (and for the benefit of having a single URL for search rankings).

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.

Rewriting url parameters using rewritemap and mysql

I realize this question has been beaten to death by a lot of people asking it, but most of the answers appear to be for a very specific case that only suits their needs, and so far I have not found a suitable solution (at least, as far as i can see).
My problem is that I am trying to make my website redirect URL parameters from an ID to an actual string.
For example:
www.example.com/?category=1
would display as:
www.example.com/software
while
www.example.com/?category=2
would be displayed as:
www.example.com/software/desktop
From what I've read up, I'm supposed to be looking into an apache rewritemap, and this is where my confusion comes in. I'd really rather not have to load from a flat txt file, as I'd like to make this as dynamic as possible, and I have read that I can make it read from a php file and read it from a MySQL database, which is what I'd like.
The problem with that is that I'm really not too sure what the proper way is of achieving this. The RewriteMap document only somewhat covers flat .txt files, and not achieving it with MySQL.
So basically what I'm asking is if someone can explain how to achieve what I'm looking for, or at least point me in the right direction. Most of the threads I've found so far have sadly not been too helpful as of yet, but it's possible I might have passed by useful ones.
If it helps, right now, my MySQL data is formatted in an inherited structure like so:
ID | Title | Link | Parent
1 | Software | /Software/ | NULL
2 | Desktop Software | /Software/Desktop/ | 1
2 | Mobile Software | /Software/Mobile/ | 2
PS:
I should add that most solutions I've found give this as the example:
RewriteMap examplemap prg:/path/to/file.php
RewriteRule (.*) ${examplemap:$1}
Yet it never gives information as to what is in that file.php, and how it queries and returns the value.
EDIT
I should mention that I am on a shared hosting server, not my own private one, and so I may not have access to all possible options
EDIT 2
Just for the sake of clarity:
What I'm trying to do is make it so that a user who accesses 'example.com/software' would be treated as though they are on 'example.com/?category=1'; basically prettying the link and making it more readable. The only thing is, I'm trying to read it from a database
If you don't have access to the server or vhost config, you can't use RewriteMap anyways. The map itself needs to be defined in either the server or vhost config, not in an htaccess file. But apache 2.4 has an option of using mod_dbd to use an SQL query to define a rewrite map.
If you need to access MySQL, you're probably better off doing all of this in PHP instead of using mod_rewrite. You'd use mod_rewrite to route to your php file, which would then redirect. Maybe something like this?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /file.php?link=$1 [L]
So when someone requests http://example.com/Software/Mobile/, the request gets rewritten to: /file.php?link=Software/Mobile/, and your file.php script would do the lookup.
Or if you actually mean the other way around:
RewriteCond %{QUERY_STRING} category=([0-9]+)
RewriteRule ^$ /file.php?ID=%1 [L]
So when someone requests http://example.com/?category=2, the request gets rewritten to: /file.php?ID=2 and the php script does the lookup.
My suggestion would be to look at utilizing a front controller pattern. I think that once you start getting into user friendly URL's or the concept of "routes", that the front controller can really simply things since you no longer have to worry about mapping specific URL's to specific controllers at the web server level.
If you have Apache mod_dir enabled (chances are you do), you could do something like this in your Apache config or .htaccess:
FallbackResource /index.php
This simple directive will direct any requests that would otherwise cause a 404 error to be directed to a front controller at /index.php.
This can also be done via mod_rewrite like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [L,QSA]
In the front controller, you could evaluate the URI and route the request to whatever logic need to handle the request. You could do this via lookup of routes from a database or a hard-coded array of routes or whatever. (I would suggest however that, if using a database, you have a cached version of the routes available for quick access).
There are a number of different PHP route controllers available such that you don't need to reinvent the wheel (most every modern framework has some sort of routing concept).

Avoid automatic PHP routing in a MVC

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.

Need single entry point like solution

I work on ready made framework (legacy framework).Its almost like any other MVC framwork you get in market, except that its not having single entry point.
So in every Controller file I have to include configs & Model classes.
Currently I manage with __autoload() , but still one include is left on every page.
If I add .htaccess for single entry point then I have to do lots of changes in my code.Because every controller file is different physical file.Its not even near to object oriented structure and for views smarty is used.
Is there any solution including .htaccess rules , instead of php.ini? It will be easier to maintain.
Please suggest best solutions for my dificulty.
The best suggestion I could give you is by using auto prepend files. Before any script runs, a piece of code is prepended to it.
In Apache you can set this per directory using the php_value auto_prepend_file xxx.php directive.
You could route all traffic to one PHP script, usually index.php like so:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]
Then index.php would handle all necessary library files and handle the routing for the controllers.

Categories