Precautions after Removing 'public' from URL in Laravel 5 - php

I tried to find a solution to remove the 'public' from the url in a laravel 5 application. (localhost/laravelapp/public)
This SO answer was very useful but since i have used the asset helper, css, js and custom folder for uploading documents couldn't be found. So i had to try different answers to find the one that worked for me. While some answers suggest it's not good to remove the public folder at all, other suggest it's better to rename it instead of removing it.
I'm just wondering if there are any dangers or if there is anything i missed while removing the 'public' folder as per the answer i found in SO.
Here is what i did
Just like KA_lin's suggestion
Renamed the server.php to index.php (no modifications)
Copied the .htaccess from public to root
Changed .htaccess to the following
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.gif|robots\.txt)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(css|js|images)/(.*)$ public/$1/$2 [L,NC]
</IfModule>
Now, the css and js files were not loading properly and as per Sean Perkins answer, i opened vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php and changed
public function asset($path, $secure = null)
{
if ($this->isValidUrl($path)) {
return $path;
}
$root = $this->getRootUrl($this->getScheme($secure));
return $this->removeIndex($root).'/'.trim($path, '/');
}
to
public function asset($path, $secure = null)
{
if ($this->isValidUrl($path)) {
return $path;
}
$root = $this->getRootUrl($this->getScheme($secure));
return $this->removeIndex($root).'/public/'.trim($path, '/');
}
Now everything seems to work fine.
After that, i also added the following line in .htaccess since the .env file was being viewed when i requested localhost/laravelapp/.env
RewriteRule ^.env - [F,L,NC]
Now everything seems ready but i was wondering if there are any other precautions i should take before i upload the website to a live server.
i also noticed that the website will load all the content without css or js when i navigate to localhost/laravelapp/public.
Should i be worried about it.
I also didn't delete the .htaccess inside the public folder. I'm assuming its not a problem since i have a new one inside the root folder. Is it ok to delete it.

Related

Laravel - unable to find new page (404 error - not found)

I´m looking for solution for my laravel project problem (laravel version: 6.5.2). I found a lot of similar questions, but no solution.
So, I have created new laravel project and then i put it on my hosting.
My FTP structure is:
- www
- AutsokolaIS
In www folder, I copied content of Public folder and in the AutoskolaIS other folders and files (app, bootstrap, config, etc.)
Everything was good, until I tried to create a new page linked to welcome page.
Link is mydomain.com/page. After click on this link, I get 404 error page. When I directly open the URL mydomain.com/index.php/page everything works.
I know it´s problem with .htaccess file, but I´m not able to edit .htaccess file in correct form.
Can anyone please help me?
Thank you
By default the website will be load from public folder. If you want to remove public from your url,copy .htaccess file from public folder to root and replace the code with the following..
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ ^$1 [N]
RewriteCond %{REQUEST_URI} (\.\w+$) [NC]
RewriteRule ^(.*)$ public/$1
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ server.php

Why am I getting this laravel url routing error in .htaccess?

I have recently installed Laravel into my public_html folder. I want it so when I log into www.malhub.com it gets the contents of the public folder (public_html/public).
After trial and error, I was able to get it working somewhat. Now I have a 404 error, which is caused because the site (www.malhub.com) resolves to :
http://malhub.com/public/public_html
But my .htaccess code states:
RewriteRule ^(.*)$ public_html/public/$1 [L]
In other words, it looks for a public_html folder within the public folder (should just be the public folder)
I added some folders (test) just to make sense of how this works and am befuddled. It is going into the public folder and looking for another folder.
When I just try writing:
RewriteRule ^(.*)$ public/$1 [L]
or "public_html" or any combination of /../../ I keep getting 500 errors (that don't show the url).
How does this line of code work, and what is the optimum way?
By default the website will be load from public folder.
If you want to remove public from your url,copy .htaccess file from public folder to root and replace the code with the following..
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ ^$1 [N]
RewriteCond %{REQUEST_URI} (\.\w+$) [NC]
RewriteRule ^(.*)$ public/$1
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ server.php
If you don't want to remove all files and folder from the public folder, then just copy .htaccess to your root directory and rename server.php to index.php and last one step is if all resource files in /public directory couldn't find and request URLs didn't work for using asset() helper. Then, you need to add public to your helpers.php file.
function asset($path, $secure = null)
{
return app('url')->asset($path, $secure);
}
To
function asset($path, $secure = null)
{
return app('url')->asset("public/".$path, $secure);
}
You will fine the helpers.php in vendor/laravel/framework/src/Illuminate/Foundation/helpers.php.

Creating SEF urls using .htaccess

How can I change a url of the following format
example.com/page/1
To
example.com/index.php?page=1
?
When I enter
example.com/page/1
it should redirect to
example.com/index.php?page=1
What changes do I need to do in my .htaccess file?
folder structure is as follows
-Public_html
.htaccess
index.php
Thanks.
Use this in your public_html/.htaccess file
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^page/([0-9])/?$ /index.php?page=$1 [QSA,NC,L]
RewriteCond checks if the requested filename or directory already exist, RewriteRule will be skipped.
You can put this code in your htaccess
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^page/([0-9]+)$ index.php?page=$1 [NC,L]
With only this code, you can now access http://example.com/page/55 and see the content of /index.php?page=55 for instance.
But... the thing is, you're still able to access http://example.com/index.php?page=55 and it creates a duplicate content: very bad for referencing (Google, and others).
More info about duplicate content: here.
Solution: you can add another rule to redirect http://example.com/index.php?page=55 to http://example.com/page/55 (without any infinite loop)
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \s/index\.php\?page=([0-9]+)\s [NC]
RewriteRule ^ page/%1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^page/([0-9]+)$ index.php?page=$1 [NC,L]
Note 1: make sure (in Apache configuration file) that you've enabled mod_rewrite and allowed htaccess files.
Note 2: since your rule creates a virtual directory (/page/) you'll have some problem if you're using relative paths for your html resources. Make sure all your links (js, css, images, href, etc) begins with a leading slash (/) or instead, add a base right after <head> html tag: <base href="/">
in my answer I assume you are using linux,
I also assume you will have more complicated cases such as more than
one parameters you will want to catch
example.com/page/1/3
in this case I think you will have to use parsing the url in your index.php
first you will have to setup the .htaccess file in your site root, also you will have to make sure mod_rewrite is enabled in your apache configuration
in case you are running debian you can run this command in terminal
to make sure this mod is enabled:
sudo a2enmod rewrite
add htaccess file to the root of where your index php file is located example:
/var/www/html/.htaccess
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.php
</IfModule>
according to my solution in your index.php you must have function that can parse the url request
/*
$base path is used only if you running your site under folder
example.com/mysitefolde/index.php
*/
function getUrlParams($basePath = ''){
$request = str_replace($basePath, "", $_SERVER['REQUEST_URI']);
return explode('/', $request);
}
index.php request to example.com/page/1/2
$request = getUrlParams($rootPath);
$module = $request[0]; // page
$moduleValue = $request[1]; // 1
$moduleValue2 = $request[2]; // 2

CI not working locally

Instead of working live on my site I've decided to try and work locally and install new version later on my live site.
So I'm working with Codeigniter and have the following struture.
/htdocs/kow(site)/kowmanager(cms)
When I load https:localhost/kow it loads the correct controller however for some reason its not reconizing that kowmanager is a sub directory of kow with its own application folder and it should be loading the default controller that is set in its routes file. When I load https://localhost.com/kow/kowmanager it loads a page that says index of /kow/kowmanager and then a link to the parent directory. Which isn't anything CI related.
Inside the kow directory this is my .htaccess file. Is this the problem?
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
RewriteEngine On
RewriteBase /kowmanager
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
I'm using xxamp.
You need an index.php-page for each application as stated by the manual.
So I think you should copy your index.php to indexManager.php and in it change the application folder.
$application_folder = "kowmanager";
About the rewrite I am not sure but I think it is in line with:
RewriteEngine On
RewriteBase /kowmanager
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ indexManager.php?/$1 [L]
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
are you using a .htaccess to remove index.php from urls ?
is /htdocs/kow the base directory of your project where CI is installed ?
you need to put kowmanagers in the controllers directory, and specify which controller to call, I'm not sure CI supports calling default controllers from directories unless you specify it in the routes.php config file.
Anyway, please give further information if you want a precise answer.
What is in kowmanager and why do you have two rewrites? If your directory structure is how I assume it is, you might get away with just removing the second kowmanager directive from your .htaccess file.
Which folder is codeigniter in? All you want to do is rewrite the url to remove index.php, but unless you're mapping the url to codeigniter's index.php, it will never be able to load controllers.
Apache has a lot of info on url rewrite. Its a lot of reading and the behavior is always pretty finicky, but maybe it will help you:
Otherwise, more info will help us help you. P.S. I'd also tag this with apache, as that is where the problem is, and you're more likely to get people who know a lot about apache to view your question.

Help with bootstrap and regex for PHP

I am working on a new PHP framework for personal use in future projects, and
below is my planned file structure so far. I just need some help with some regex for my .htaccess file and some help for how I can load the files I want.
Basically, any "folder" after the domain should load from my "module" folder.
I would like to have it load www.domain.com/account/ from www.domain.com/module/account/. I also want it in that format for any other folder I have under modules. All folders/files under "module" should load as if it were in the top level.
In this example though in my module/account/ folder, if I have a file called home.php then I should be able to access it with www.domain.com/account/home instead of www.domain.com/module/account/home.php, and www.domain.com/module/user/register.php would actually be accessed by www.domain.com/user/register
I hope this makes sense and appreciate any help and any advice. I mainly need help with the .htaccess file to make this folder structure work. I have not decided if all files should be accessed though a single index file or if I should just include a bootstrap type file into every page. The bootstrap file would set up all variables, config options, as well as auto load all class files and create objects needed.
myFramework/
--/assets/
--------/css/
--------/images/
--------/javascript/
--/includes/
---------/classes/
---------/config/
---------/language/
---------/header.php
---------/footer.php
--/module/
--------/account/
----------------/create.php
----------------/login.php
----------------/logout.php
----------------/settings.php
----------------/editprofile.php
--------/admin/
--------/blog/
--------/forums/
--------/messages/
--------/users/
--index.php
The answer from jasonbar is actually almost there. All it lacks is dealing with the .php extension as you described:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/module
RewriteCond %{REQUEST_URI} [.]php$
RewriteRule (.*)[.]php$ /module/$1
That being said, I'd strongly encourage you to consider a front controller paradigm (as you eluded to in your problem description) as doing so allows for much greater control, encourages an MVC approach, etc. =o)
EDIT:
I corrected a few neglected points and added proper processing of the PHP extension. Note that the [L] argument at the end causes further processing to cease, making these code blocks useful as logical structures within your .htaccess file (i.e. by preventing any processing that follows); remove that argument if such functionality is not desired.
I've also added a line to specifically check that the php file being requested actually exists.
RewriteEngine On
# if the uri matches a directory in the module dir, redirect to that. Disable
# this block if you don't wish to have either directory browsing or to have the
# default apache file load.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/module%{REQUEST_URI} -d
RewriteCond %{REQUEST_URI} !^/includes
RewriteCond %{REQUEST_URI} !^/assets
RewriteCond %{REQUEST_URI} !^/module
RewriteRule (.*) /module/$1 [L]
# if the uri matches a file sans the .php extension in the module directory,
# then redirect to that.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/module%{REQUEST_URI}.php -f
RewriteCond %{REQUEST_URI} !^/includes
RewriteCond %{REQUEST_URI} !^/assets
RewriteCond %{REQUEST_URI} !^/module
RewriteRule (.*) /module/$1.php [L]
EDIT:
To also allow files that end in ".php" to be served from the module directory, add the following to your .htaccess file:
# if the uri matches a file with the .php extension in the module directory,
# then redirect to that.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/module%{REQUEST_URI} -f
RewriteCond %{REQUEST_URI} !^/includes
RewriteCond %{REQUEST_URI} !^/assets
RewriteCond %{REQUEST_URI} !^/module
# note that the following line restricts access to php files only. comment out
# the following line to allow any existing file under module director to be
# accessed (or modify the following to allow other file extensions to be read)
RewriteCond %{REQUEST_URI} [.]php$
RewriteRule (.*) /module/$1 [L]
I'd try to solve this in PHP itself, if it were up to me. Just create a .htaccess file that maps every possible request to a single file (probably index.php), and determine what to do from there. That gives you an opportunity to do all kinds of bootstrapping and logging before delegating the request to whatever piece of code should handle that request. You could even include and use a micro framework such as Limonade to accomplish what you want. Here's an example:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d # if the requested directory does not exist,
RewriteCond %{REQUEST_FILENAME} !-f # and the requested file does not exist,
RewriteRule ^ index.php # map everything to index.php.
Then, in index.php, you can do a wide variety of things to make sure you get the correct response. The simplest way to use a "controller like structure", would be to include a framework such as Limonade, and use it. An example:
<?php
require_once 'vendor/limonade.php';
dispatch( 'account/home', 'accountHome' );
function accountHome( ) {
require_once 'modules/account/home.php';
}
run( );
Obviously, that is just a suggestion. Alternatively, you could just make use of an even simpler system, although I guess you'd have to write that yourself. That way you can say, if the file exists in the modules directory, just include this file, and that's that.
<?php
$path = isset( $_SERVER['PATH_INFO'] ) ? trim( $_SERVER['PATH_INFO'], '/' ) : null;
if( $path !== null ) {
$filename = 'module/' . $path . '.php'; /** $path could be account/home */
if( file_exists( $filename ) ) {
require_once $filename;
}
else {
require_once 'error.php';
}
}
else {
require_once 'home.php';
}
That's it. Fully functional and all. You could benefit from using a library that sorts this all out for you though.
After reading your requirements, I have come up with the following solution:
RewriteCond %{REQUEST_URI} !^/includes
RewriteCond %{REQUEST_URI} !^/assets
RewriteCond %{REQUEST_URI} !^/module
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteRule (.*)(\.php)?$ /module/$1
I have verified this works with the following URL patterns using Apache 2.2:
Redirects to module folder:
http://local.sandbox.com/account/home.php?t=t
http://local.sandbox.com/account/home.php
http://local.sandbox.com/account/home.php/?t=t
http://local.sandbox.com/account/home?t=t
http://local.sandbox.com/account/home/?t=t
http://local.sandbox.com/account/home/
http://local.sandbox.com/account/home
http://local.sandbox.com/user/register
http://local.sandbox.com/user/register.php
http://local.sandbox.com/user/register?t=t
http://local.sandbox.com/user/register.php?t=t
Doesn't redirect as these URI's are excluded:
http://local.sandbox.com/includes/header.php
http://local.sandbox.com/includes/header.php?t=t
http://local.sandbox.com/index.php?t=t
http://local.sandbox.com/?t=t
Note that the RewriteCondition is essentially an AND consisting of NOT conditions, so any folder or file that you want to exclude from the rewrite rule must be added as a NOT condition.
The module rule is inclusive, meaning that any new folders you place in the module folder will automatically be subject to your rewrite requirements.
If I understand you, this should work. The conditions will cause it to redirect only when the requested resource isn't a real file / directory and when it isn't already requested from the module directory.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/module
RewriteRule (.*) /module/$1
I'm developing a PHP framework with a collegue so this really caught my attention.
Our .htaccess makes a minimal amount of assumptions. It looks like this:
DirectoryIndex index.php
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} \.png$
RewriteRule ^(.*)$ $1 [QSA,L]
RewriteCond %{REQUEST_URI} \.gif$
RewriteRule ^(.*)$ $1 [QSA,L]
RewriteCond %{REQUEST_URI} \.jpg$
RewriteRule ^(.*)$ $1 [QSA,L]
RewriteCond %{REQUEST_URI} \.js$
RewriteRule ^(.*)$ $1 [QSA,L]
RewriteCond %{REQUEST_URI} \.pdf$
RewriteRule ^(.*)$ $1 [QSA,L]
RewriteCond %{REQUEST_URI} \.css$
RewriteRule ^(.*)$ $1 [QSA,L]
RewriteCond %{REQUEST_URI} ^/favicon*
RewriteRule ^(.*)$ favicon.ico [QSA,L]
#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [QSA,L]
index.php in turn, looks like this:
<?php
namespace System;
try
{
ob_start();
$Indium = include 'src/bootstrap/IndiumFactory.php';
$Indium->run();
}
catch (\Exception $e) // catch errors and display/log
{
Error::indium_exception_handler($e);
Error::render_error_page();
}
IndiumFactory is the bootstrapper which sets up the environment. Indium is the name of our framework. IndiumFactory is autogenerated from a set of config files.
Maybe I should clarify that Indium has a mechanism for loading and calling the correct controller class with the rest of REQUEST_URI as the arguments. Our forms rely on POST:ed data, so we can impose rather strict rules/filters on the URI.

Categories