Alias Domain to Zend Directory - php

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.

Related

Generic way to rewrite external /api/entity/1 URL to internal /api/entity.php/1 (or /api/entity.php?id=1)

With a API I'm trying to make in PHP I currently have these rewrite rules setup in the .htaccess file for the root directory of the API:
# Remove the php extension from the filename
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
This is so that requests to the API appear more "RESTful" - so instead of api/entity.php?id=5 it would be api/entity?id=5 - I'd like to go a step further though, and allow a request URL like api/entity/5 to successfully rewrite to api/entity.php/5 or api/entity.php?id=5.
I was experimenting with an apache rewrite rule something like this, where it has regex to detect a path like entity/{any number here}
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC]
RewriteRule ^(.+)(\/\d+)$ $1.php$2 [NC,L]
Where it would match entity/5 in two captures with entity and /5 and would then internally direct that to entity.php/5 - at which point in the php file I could do an explode on the request URI or something similar to that to get the value from the path.
But I don't really know enough about apache rewrites to fully implement this, as this rule doesn't work for whichever reason. I'm aware I could write hardcoded rewrite rules for each directory I would like to behave like this, but I'd really rather keep this generic.
If there is no real way to achieve what I want to here, then I'd rather just stick to paths like api/entity?id=5 than need to write a whole bunch of rewrite rules.
I was thinking as well, if there is a way to detect when a request doesn't match a directory (which would be what happens by default with a path like api/entity/5?) - it runs a different rewrite in this case - without running the first and causing it to try and write the now internally pointed URL, but again, I'm not sure how to go about implementing this.
Can someone with more experience point me in the right direction?
As Chris Hass highlighted, in this case implementing a PHP router of some variation probably makes more sense and is just easier.
Here are links to some examples I found for anyone in the future who stumbles onto this:
https://medium.com/the-andela-way/how-to-build-a-basic-server-side-routing-system-in-php-e52e613cf241
https://www.taniarascia.com/the-simplest-php-router/
https://www.educative.io/edpresso/how-to-create-a-basic-php-router
Obviously, if you're not intentionally using just PHP on its own like me, there's no reason you couldn't use a library or do this with Laravel etc to make your life even easier, why reinvent the wheel after all?

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.

How to call a function in class/function format from localhost

I am using Yii2 framework for my PHP development. In my view files, If I want to call any of the functions, I just use Class/Function name
Eg : www.example.com/SiteController[class name]/index[function name]
And it is calling the function.
I like to know, How to do the same in a pure php script ?.
I searched in many places and I could get the suggestions for special_autoload_register();. But I could not understand the exact practical application.
Guidance is expected and Thanks is advance.
Its easy :).
It's all based on apache module mod_rewrite. This module allows you to modify path behavior in .htaccess file.
Using this .htaccess file
RewriteEngine On
# The following rule tells Apache that if the requested filename
# exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
# The following rewrites all other queries to index.php. The
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting, the base path will be prepended to
# allow proper resolution of the index.php file; it will work
# in non-aliased environments as well, providing a safe, one-size
# fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::$
RewriteRule ^(.*)$ - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
you will get following behavior:
If requested file exists (/styles/style.css - styles, javascripts, images, etc) serve it (dont change anything on current behavior)
If requested file doesn't exist, go to index.php.
If you are redirected to index.php, you can find full requested url in $_SERVER['REDIRECT_URL'] or $_SERVER['REQUEST_URI']. There you can take it, parse and based on requested uri, behave.
Please take this as explanation post, not a guide on how to get this going. Mostly it requires some apache configuration because mod_rewrite is mostly disabled by default.
If you want to get things going, I would recommend this post.
To fully answer your question, you can for example explode request uri by "/" sign, save first part into $firstPart and second into $secondPart and then have
$controllerName = $firstPart."Controller";
$controller = new $controllerName;
$actionName = $secondPart."Action"
$response = $controller->$actionName();
So if you call /help/me, helpController->meAction() will be called.
I hope I helped :)
To do this, Yii 2 (and other PHP frameworks) have routers. The router in Yii 2 is the UrlManager class.
I would not advice you write a router from scratch for a solution you want to deploy. There are routing packages in PHP which you could easily use in your solution. I like Klein. It's a pure router in PHP.
However, if for academic purposes, you want to know how routing works in PHP, get to understand the $_SERVER reserved variable. It has all the details of the HTTP request coming to your script. You can then use the details from this to call the specific function you want to call.

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.

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.

Categories