How to change public folder to public_html in laravel 5 - php

I'm using a shared hosting which uses cPanel as its control panel and within the cPanel public_html is the default root directory, because of this I can't get my Laravel application work properly.
Is there any way to make Laravel use public_html instead of public folder?

Quite easy to find this with a simple search.
See: https://laracasts.com/discuss/channels/general-discussion/where-do-you-set-public-directory-laravel-5
In your index.php add the following 3 lines.
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
$app = require_once __DIR__.'/../bootstrap/app.php';
// set the public path to this directory
$app->bind('path.public', function() {
return __DIR__;
});
Edit:
As Burak Erdem mentioned, another option (and more preferable) is to put this in the \App\Providers\AppServiceProvider register() method.
/**
* Register any application services.
*
* #return void
*/
public function register()
{
// ...
$this->app->bind('path.public', function() {
return base_path('public_html');
});
}

If Robert's index.php solution is not working for you, you can also register the following code at Application Service Provider (App\Providers\AppServiceProvider.php).
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
public function register()
{
$this->app->bind('path.public', function() {
return base_path().'/public_html';
});
}

Server
Methods described in topic are working just fine, so modyfing App\Providers\AppServiceProvider.php register method should do the job:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
public function register()
{
$this->app->bind('path.public', function() {
return base_path() . '/public_http';
});
}
Local php artisan serve development
However, there is one more issue you can experience. If you're developing your app on local machine and you're using php artisan serve command to serve your app you're going to break it with above syntax only. You still need to adjust server.php file which exists in main directory. Edit the contents of it and replace each occurance of /public to /public_html, so it looks like this:
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* #package Laravel
* #author Taylor Otwell <taylor#laravel.com>
*/
$uri = urldecode(
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
);
// This file allows us to emulate Apache's "mod_rewrite" functionality from the
// built-in PHP web server. This provides a convenient way to test a Laravel
// application without having installed a "real" web server software here.
if ($uri !== '/' && file_exists(__DIR__.'/public_html'.$uri)) {
return false;
}
require_once __DIR__.'/public_html/index.php';
After that. Just stop your server and reload it with php artisan serve.
Front end laravel-mix development
If you're using webpack and laravel-mix to generate your css and js files then this also needs some update. Without tweaking webpack.mix.js you will end up with something like this on npm run watch or npm run production:
.
..
public
_html
js
public_html
css
public_html
So it's going to mess up your code. To clarify this you have to provide a public path to your webpack.mix.js file. It could look like this:
const mix = require('laravel-mix');
mix.setPublicPath('public_html/');
mix.js('resources/js/app.js', 'js')
mix.sass('resources/sass/app.scss', 'css');
This is going to change the default definition of public directory from public to public_html and next lines provides a relative path to your setPublicPath value.
Happy coding.

Go to this address:
/app/Providers/AppServiceProvider.php
and append this code to end of file:
public function register()
{ $this->app->bind('path.public', function() {
return realpath(base_path().'/../public_html');
});
}

Just want to update all previous answers, if your public_html is not inside laravel folder, then you need to use this code:
$this->app->bind('path.public', function() {
return realpath(base_path().'/../public_html');
});

Simple root directory create .htaccess file and add code:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

These answers did not work for laravel 5.5, but my own method can help you.
Step 1: Discard all files except the public file to the main directory on the server.
Step 2: Public file to the public_html file on the server.
Step 3: Pull index.php file from public_html and change it like this.
Step 3A:
Orginal -> require __DIR__.'/../vendor/autoload.php';
Changes -> require __DIR__.'/../**created_folder**/vendor/autoload.php';
Original -> $app = require_once __DIR__.'/../bootstrap/app.php';
Changes -> $app = require_once __DIR__.'/../**Created_folder**/bootstrap/app.php';
Step 4: Create symlinkcreate.php
Step 4A: <?php
symlink('/home/**server_directory**/**created_folder**/storage/app/public','/home/**server_directory**/public_html/storage');
Step 4B: yourwebsite.com/symlinkcreate.php visit
Step 4C: symlinkcreate.php delete your server.
Finally, the directory structure looks like this:
/etc
/logs
/lscache
/mail
/Your_Created_Folder
../LARAVEL_FOLDERS
/public_html
../css
../js
../.htaccess
../index.php
../web.config
/ssl
/tmp
Finish.
Laravel 5.5 public_html sorunu için bu cevabı gönül rahatlığıyla kullanabilirsiniz.

For those that need to change the public path so that it is also available to Artisan, add the following to bootstrap/app.php, just after the last singleton method:
$app->bind('path.public', function () {
return base_path("<your public directory name>");
});

It took two days for me to figure out but finally I deployed my Laravel-project to my cPanel webhosting by doing next steps:
Change the server.php file as following:
if ($uri !== '/' && file_exists(__DIR__ . '/public_html' .$uri)) {
return false;
}
require_once __DIR__ . '/public_html/index.php';
Change webpack.mix.js as following:
mix.js('resources/js/app.js', 'public_html/js')
.postCss('resources/css/app.css', 'public_html/css', [
//
]);
Change the name of "public" folder in Laravel-project to "public_html" and upload the code to the root directory cPanel. Make sure that you have a back-up from the current public_html directory. If you have the correct PHP version on your hosting and edited .env file then everything should work properly.
My cPanel root directory (from File Manager) looks like this:
And public_html (that originally was public directory) looks like this:
If you have questions feel free to contact me :)

In bootstrap/app.php:
Add
$app->bind('path.public', function() {
return __DIR__;
});
right after
$app = new Illuminate\Foundation\Application(
realpath(__DIR__)
);
Fixing server.php:
Change
if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
return false;
}
require_once __DIR__.'/public/index.php';
to
if ($uri !== '/' && file_exists(__DIR__.'/public_html'.$uri)) {
return false;
}
require_once __DIR__.'/public_html/index.php';
In .gitignore, change
/public/hot
/public/storage
to
/public_html/hot
/public_html/storage
In webpack.mix.js, change
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');
to
mix.js('resources/js/app.js', 'public_html/js')
.sass('resources/sass/app.scss', 'public_html/css');
I'm still looking for a fix for the asset() function, which remains broken...

It's not so easy like binding. The cleanest and more elaborated answer is provided by ferrolho here https://laracasts.com/discuss/channels/general-discussion/where-do-you-set-public-directory-laravel-5
But the fastest answer is creating a symbolic link named public pointing to public_html and put your index.php in the last one.

The simplest solution as for me is to create symbolic link.
Make backup of your public_html folder.
Connect to your server via ssh.
In my particular scenario, whole application is located in ~/laravel folder.
Now you have to be in the ~/ folder:
Run rm -r public_html. This command will delete public_html folder and all its contents.
Make symbolic link ln -s $(pwd)/laravel/public $(pwd)/public_html. $(pwd) will be substituted with absolute path from root of the server.
Now you should be able to see desired result.

For me none of this worked until I changed the root public folder in server settings. In production it is in /etc/nginx/sites-enabled/<your_site_name>. Edit it with a text editor and just scroll until you see root path pointing to /public folder. Change that to whatever is your new public folder and restart the server. On local, I had to change path in Homestead.yaml and /etc/nginx/sites-enabled/<your_site_name> after I SSHed into Vagrant. vagrant reload --provision to make sure it caught on. Then I also edited index.php and registered a new path in the service provider just in case, but it seems to work without it. I don't use any 3rd party dependencies with Laravel though so I don't know if this will work in that case.

Related

How to change public directory to public_html directory for Laravel Mix

I'm using Laravel 8 and I wanted to install Sweet Alert. So after downloading it and adding require('sweetalert'); to bootstrap.js, I ran the command npm run production.
Then I have included this in my master.blade.php:
<script src="{{ asset('/js/app.js') }}"></script>
#include('sweet::alert')
Now because I had changed my public directory from public to public_html, Laravel asset() function would call the public_html/js/app.js and this is wrong because Laravel Mix generated app.js and app.css in the public directory.
So the question is how can I change the default generation of Laravel Mix which is public to public_html ?
Here is my AppServiceProvider.php:
public function register()
{
$this->app->bind('path.public', function(){
return base_path() . '/public_html';
});
}
#Alfian has answered your question. But the solution you asked for, is not recommended when you are talking about renaming the public folder. You should not really rename your public folder while using Laravel.
But I can understand why you renamed it, to declare the default root folder. But there are better solutions instead of renaming it. And then there will be no such question too.
Best Solution: Upload the Laravel project as it is in the public_html folder. Go to your cPanel and enter Domains/Addon Domains/Subdomains (which type domain you are using) section and just change the Document Root as /public_html/public. You are done.
Update:
If it's a primary domain or addon domain there may not be an option directly to change the document root. Then we can just add a rule in the .htaccess file. Use this:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
You can change configuration compiled assets directory on webpack config files, by default laravel set webpack at webpack.config.js
Here more documentation about compiling assets laravel
Laravel 8 Compiling Assets
In .env change ASSET_URL=https://yourdomain.com/public_html. But its a bad practice to have index along with php code(app, vendor, etc..)
You can create symbolic link from public to act as public html like follows
ln -s /full/work/path/laravel-project/public /full/work/path/public_html
But you might need to remove public_html first
mv public_html tmp
I assume your structure would be
full/work/path/
- laravel-project
- public
- public_html
...
in the main root directory of laravel project one file server.php and another one index.php
first, delete the index.php file
after that rename the server.php file to index.php
after that, you can use it directly as yourdomainname.example
From,
dhayal info tech web solutions

How put Laravel site on shared hosting which has multiple other sites in subdirectories?

I have a Laravel site running locally on my machine, but I'd like to make it live. I already pay for shared hosting, and I have a number of sites running on the shared host in their own subdirectories. So for example, in the shared hosting, I have:
public_html/site1
public_html/site2
etc.
These are all personal sites. So I'd like to put my Laravel site on there too:
public_html/laravelsite
The issue is that I obviously don't want the majority of the files to actually be publicly accessible. If I split them up though and just put the public site files into public_html/laravelsite and put the rest of the files in a folder above public_html, nothing will be able to locate anything else and the site won't work.
Is there another work-around I can use to secure my files?
When users request your site, the starting point is always public/inde.php. So put the public folder where you want and the rest (Laravel) where you want. Then from public/index.php, try to link bootstrap/autoload.php.
For instance, in your case you would go to public/index.php and change lines 22 and 36 so they can still find the autload.php file like this:
22. require __DIR__.'/../bootstrap/autoload.php';
becomes
22. require __DIR__.'/../../laravel_folder/bootstrap/autoload.php';
And
36. $app = require_once __DIR__.'/../bootstrap/app.php';
becomes
35. $app = require_once __DIR__.'/../../laravel_folder/bootstrap/app.php';
There are other ways of doing the same. Just find the one that suits your needs.
For Elixir, "...you may begin any file path with ./. This instructs Elixir to begin at the project root, rather than using the default base directory". Source: https://laravel.com/docs/5.3/elixir. So you have do something like this to change the source
elixir(function(mix) {
mix.sass('./app/assets/sass/app.scss');
});
You can do the same to change the destination.
Now if you want to minimize the differences between your dev and prod, reorganize your folder in dev to have a similar structure.
Try opening AppServiceProvider.php and modify as following:
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind('path.public', function() {
return base_path().'/public_html/laravelsite';
});
}
}
And put the contents of public folder to laravelsite folder.
Most obvious solution - just tell your server to not serve files from /public_html/laravelsite?
For instance if your shared hosting is using apache, create an .htaccess file in /public_html/laravelsite with
Deny from all
Then go to your laravel's .htaccess file in the public directory and add
Allow from all

How to rewrite or remove public from laravel 5 urls in proper way?

I'm trying to remove the public/index from laravel url, since this is one of the common question so there are lot of tutorials and answer. I also searched about this and followed the #rimon.ekjon answer which is working fine for me it's pretty simple.
Rename the server.php in the your Laravel root folder to index.php and copy the .htaccess file from /public directory to your Laravel root folder. -- Thats it !! :)
I'm confuse why i should rename or move something from one place to another because there will be a reason why files exist in public folder. I want to show another good answer which is also following the almost same pattern.
I'm thinking that by following above answers' step may be create some issues in future if there will be a new requirement or new feature request in the project.
So can anyone guide me is there any best to rewrite or remove the public/index from laravel 5. I would like to appreciate if someone guide me.
You should configure your web server's document / web root to be the public directory. That way you don't have to copy/move/delete anything.
For apache you can look here.
For nginx you can read here.
I've visited your link and saw really terrible advices.
You do no need to move any Laravel files or modify them. What you need is to setup web server. You need to point it to a public directory which is inside Laravel project root folder.
Please look here for an example config directives for Apache and nginx.
One other option is to symlink the public folder to your server's root folder (e.g. /var/www/). This article is a great guide on how to do this.
On your dev environment however you can use php artisan serve.
In case, if you don't have access to you server config, this is a perfect solution https://stackoverflow.com/a/32580688/5015089 .
Remove public from url without htaccess. It will work on laravel latest versions also.
step 1. Copy all files from public and paste on root directory
step 2. Open index.php file remove ../ from path as given below
Laravel5:
require __DIR__.'/../bootstrap/autoload.php';
to
require __DIR__.'/bootstrap/autoload.php';
and
require_once __DIR__.'/../bootstrap/app.php';
to
$app = require_once __DIR__.'/bootstrap/app.php';
Laravel 7:
require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';

Laravel 5 directory structure on shared hosting

I am new to Laravel and started learning v5 few months back. I have created a sample application and want to deploy it over production (Shared hosting).
The easiest way for me is to put all content including app, vendor, config, tests etc folders directly to public_html but I don't want to do this. I want to keep laravel specific things outside the public_html and put only content from public folder to this directory.
What are the options available to do this?
Also, can I share same laravel installation for multiple applications?
on public/index.php add after
$app = require_once __DIR__.'/../bootstrap/app.php';
this:
$app->bind('path.public', function() {
return __DIR__;
});
Now You can change public directory to public_html
Keep your code outside of the public_html and create a symbolic link from public_html to the public directory in your laravel directory.

PHP ZF2 - multiple sites with separate public folders

I am trying to create a single ZF2 installation with multiple websites under it, with each site being a separate module. So far, with using Hostname routing, it works, except that all of the sites share the same public folder.
Is there a way to configure each module to have its own public folder?
I have seen some other questions about this, but they have mostly dealt with the routing itself or been ZF1 specific, which kept the public folder within the module.
You can quite easily do what you want:
site1.com document root: ~/project/site1/public
site2.com document root: ~/project/site2/public
~/project/site1/public/index.php and
~/project/site2/public/index.php both contain:
<?php
// Set time zone.
date_default_timezone_set('Europe/Paris');
/**
* This makes our life easier when dealing with paths. Everything is relative
* to the application root now.
*/
define('ROOT_PATH', dirname(__DIR__.'../'));
chdir(dirname(__DIR__.'../'));
// Decline static file requests back to the PHP built-in webserver
if (php_sapi_name() === 'cli-server' && is_file(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))) {
return false;
}
// Setup autoloading
require 'init_autoloader.php';
// Run the application!
Zend\Mvc\Application::init(require '../config/application.config.php')->run();
You can have as many public folder as you want. Just put in index.php valid include of zf2 core and everything should work without any special modifications (what module to display can be specified by domain path or via global configuration you will put inside index.php).
Still I think is perfectly fine to have one public folder and change active modul per domain, also use some asset manager with configuration and content encapsulated inside module. Best for this is rwoverdijk/AssetManager.

Categories