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.
Related
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.
I've been searching lot of related tutorials and so on from Google to solve this on my own, but with zero luck. Therefore I am here to ask. I am trying to 'prettify' my project URL by rewriting. I am not sure are these all achievable anyhow, because I am just starting to get my head around the subject.
I am working 'example' on localhost project folder localhost/example. File '.htaccess' is located in that folder. Where I have set the following:
RewriteEngine On
RewriteBase /example
So basically my application now generates a URL consisting at least 1 parameter all the time and another pointing current location.
Current URL: localhost/example/admin.php?e=2&p=frontpage
Fantasy: localhost/example/admin/2/frontpage
About the parameters:
p stands for selected page
e stands for event
Okay lets think this all is achievable easily, do I have to change all the attributes to match current shown url?
Now they are:
href="?e=2&p=settings"
Should they be:
href="2/settings" ?
I am checking what value GET parameter P has, then including that page into content area.
That is pretty much it, pretty too complex for me, but for education purposes I really want to understand this thru and thru. Thank you.
EDIT:
With the added
RewriteRule ^admin.php/(.*)$ /admin.php?e=$1 [L,QSA]
I am getting lot of pathing errors, whole site is without styling and js files.
EDIT 2:
RewriteEngine On
RewriteBase /example
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule /admin.php/e=?(.*)$/p=?(.*)$ /admin.php?e=$1?p=$2 [L,QSA]
Now urls are following:
http://localhost/example/admin.php/2/inc/vex/vex.css
http://localhost/example/admin.php/2/css/modestgrid.css
It is not showing the page in url and the paths are not correct.
They should be http://localhost/example/admin.php/css/modestgrid.css
Your question is a bit vague, contradictory and it is unclear how you actually want to handle (reference) your asset files. But in general I'd say this should be a starting point to get you going:
RewriteEngine On
RewriteBase /example
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/(.*)$ $1.php?e=$2&p=$3 [END]
For this to work you obviously need the apache rewriting module to be installed and loaded, you need to take care that the interpretation of dynamic configuration files is enabled at all (AllowOverride directive) and you have to place such file in the correct location with reading permission for the http server process.
In case you get an internal server error (http status 500) for that chances are that you operate a very old version of the apache http server. In that case you probably need to replace the [END] flag with the [L] flag which probably will work here too. You will find a hint on that in your http servers error log file in that case.
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only supported as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).
I have a problem with a project I'm doing with PHP and it's in the URLs.
When I load a script like index.php everything works fine, the problem is when I load a script that is located within two or more directories.
In the URL the scripts with the routes begin to be enmeshed
Here is an example of the problem I have
I need to load a script, even if it is in several levels of nesting, make its functionality and in the url is reflected as:
I need to have something like this
1:
I thank you in advance.
Regards
You can't use PHP to achieve this. PHP is not responsible for determining if PHP (let along a particular PHP script) will handle any given URL.
You have to configure your webserver to do it. Since you mention .htaccess but provide no further information about your server, I'm going to assume you are using Apache HTTPD.
For Apache, that means using mod_rewrite, Alias or something similar. You can put the configuration for those tools in .htaccess, but you don't want to and the documentation advises not to use them.
So put your mod_rewrite or Alias configuration in the main Apache configuration.
You're going to need an htaccess rule no matter what. However, it doesn't have to be a mod_rewrite rule. The reason you need this rule is because PHP is not responsible for the routing - it is merely responsible for the execution of your script.
The point of the rule is to direct apache and instruct it to execute the right script (in your case, script32.php) while keeping the request uri as intact as possible.
There are two ways around it, basically.
Way 1 (cleaner): mod_rewrite
This is pretty straightforward, the set of rules you need are as follows:
# If the requested file name is a valid file/inode
RewriteCond %{REQUEST_FILENAME} -f [OR]
# ...or a directory
RewriteCond %{REQUEST_FILENAME} -d
# ...then throw them straight on it
RewriteRule (.*) - [L]
# ...otherwise, redirect to script32.php with the full content of the request in query string
RewriteRule (.*) /welcome/script32.php?$1 [L]
The requested URL is now in $_SERVER['QUERY_STRING'] and you can now do whatever you like with it in PHP
Way 2: catchall
This does not rely on mod_rewrite and may therefore be slightly faster. However, technically, it's a cheap hack. The way around it is as follows:
ErrorDocument 404 /welcome/script32.php
The requested URL can now be found in $_SERVER['REQUEST_URI'] and is available for parsing in PHP. However, with this, you've also disabled "legit" 404 errors from being generated through apache - and should make sure to obey proper behaviour in PHP to compensate.
I am trying to setup simple url routing in a Perl web project without haveing to include a framework just for that purpose. I believe this can be accomplished with an .htaccess.
The plan is for any request to the server using example.com/anysubdirectory/... to be routed to a perl/php script that will parse whatever is contained in /anysubdirectory/... and the parameters following it and then determine where to send the user based on that info.
If example.com without any subdirectory is requested I need to still maintain the default behavior of searching for an index page here.
Since the /anysubdirectory/ will be dynamic i'm not able to predefine that /123/ -> option 1 or /abc/ -> option 2
I am not overly familiar with htaccess other than the typical www and base rewrites.
Any help is much appreciated.
I believe I answered my own question using the following in the root .htaccess:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ router.pl?action=$1 [L,NC,QSA]
This seems to be working with my initial testing.
I believe this is how it is working:
If the requested subdirectory is not found as a file
If the requested subdirectory is not found as a directory
Redirect this to the router.pl script along with any leftover parameters from the original url.
EDIT: The above is not working completely, this is still redirecting any file that is not found on the server to the router.pl script. Not really the functionality that I am looking for,i would like this to only happen if it is a subdirectory and not an invalid file
Not sure I want any bot thats guessing filenames to be pegging my script on a regular basis.
Please correct this response if any of the above is not accurate.
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.