What is the proper way to add a subdomain into your routes? I have a laravel/homestead project working on my local computer but when I move it to HostGator, a shared host server, it no longer works. Well the home page works but the links to the sub-pages don't.
For example, the following route works fine on my local version:
Route::get('/appointments', 'AppointmentController#index');
But if I use that route on the remote server, it takes it to tekknow.net/appointments instead of tekknow.net/medaverter/appointments.
So I followed instructions from here:
https://laravel.com/docs/5.6/routing#route-group-sub-domain-routing
and added a prefix like this:
Route::prefix('MedAverter')->group(function() {
Route::get('/appointments', 'AppointmentController#index');
});
But that doesn't work either. It also goes to /tekknow.net/appointments
I also tried changing the route to this:
Route::get('/MedAverter/appointments', 'AppointmentController#index');
But that also went to tekknow.net/appointments
Anybody know what I'm doing wrong?
EDIT: I went onto my HostGator cPanel and looked at all my subdomains and saw that my subdomain root was medaverter.tekknow.net which is linked to Document root of medaverter.tekknow.net/MedAverter which gets redirected to http://www.tekknow.net/MedAverter. So I renamed my folder from medaverter to MedAverter to match the subdomain redirection.
Here is a screenshot showing what I see in cPanel for columns Subdomains.Root Domain, Document Root, and Redirection
When you try php artisan route:list | grep appointments,
it prints:
[~/www/MedAverter]# php artisan route:list | grep appointments
| | GET|HEAD | MedAverter/appointments | | App\Http\Controllers\AppointmentController#index | web |
That means your route MedAverter/appointments is working for laravel.
Error 404 means route cannot be found.
So I think that's something wrong with your nginx configuration.
When I try http://tekknow.net/MedAverter/MedAverter/appointments.
It has really found the route with error 500.
So, I think you have defined this code in your nginx configuration:
location = / {
rewrite ^ https://tekknow.net/MedAverter;
}
Solution 1:
Change back to rewrite ^ https://tekknow.net/; in nginx configuration.
(I'm not familiar with hostGatar cPanel, but I think you can change medaverter.tekknow.net/MedAverter redirected to http://www.tekknow.net/`)
And in your laravel project, you need to keep prefix MedAverter to appointments.
Solution 2:
Keep the rewrite code. It means you don't need to change the cPanel redirect.
And remove prefix MedAverter in laravel routes. HostGatar(Nginx) will automatically redirect with this prefix MedAverter for appointments.
Clear all caches
The problem you're getting can be due to cache. So, make sure that's not the problem by running
php artisan route:clear && php artisan view:clear && php artisan config:clear && php artisan cache:clear && php artisan clear-compiled
Base URL
If you want to change the base URL of your Laravel app, that's something already asked.
Multiple Path Prefixes
In this case you have a more than one route with the same prefix in their path. If that's the case, you can use route groups to simplify the structure.
Route::prefix('medaverter')->group(function () {
Route::get('/', function () {
// Path /medaverter
});
Route::get('appointments', function () {
// Path /medaverter/appointments
});
});
This would go to, respectively, tekknow.net/medaverter and tekknow.net/medaverter/appointments. You could also create another prefix, like testing, configure in the same way and go to tekknow.net/testing or tekknow.net/testing/whatever.
Namespace prefixes
When you’re grouping routes by route prefix, it’s likely their controllers have a similar PHP namespace. In the medaverter example, all of the medaverter routes’ controllers might be under a Medaverter namespace.
Route::namespace('Medaverter')->group(function () {
// App\Http\Controllers\Medaverter\AppointmentController
Route::get('medaverter/appointments', 'AppointmentController#index');
});
u can use route groups for that here is a sample try this:
Route::group(['prefix' => 'medaverter'], function () {
Route::get('/appointments', [AppointmentController::class, 'index'])->name('index');
});
or
Route::group(['prefix' => 'medaverter'], function () {
Route::get('/appointments', 'AppointmentController#index');
});
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.
I just installed laravel following the instruction on Larvel docs. I chose to use install via composer create project command.
In the routes. php i created a dummy route
Route::get('/', function(){
return 'Front Page';
});
When i access http://localhost/mysite/ It shows directory listing of mysite folder. However when i use http://localhost/mysite/server.php It runs my route closure.
I also tried alternate .htaccess code provided at Laravel's docs but that doesn't work either.
I want to remove the server.php from url.
Thanks in advance for help.
This behavior is expected and this is how Laravel works. The public folder is meant for assets and is also (supposed to be) the webservers root directory.
If you are working on localhost that is not the case and the root directory contains multiple projects.
In order to get rid of public you would have to change virtual host settings.
As mentioned here in the site.
The problem with doing virtual hosts is that other projects in localhost will become inaccessible.
Quick question,
EDIT: I do not know how to access other routes besides '/'
Here are the routes I want to access
Route::get('/', 'HomeController#index');
Route::get('users', 'UserController#index');
Route::get('foo', function()
{
return 'Hello World';
});
Here is my routes. Via php artisan routes
I can successfully access localhost/cartraderlaravel/public
It takes me to HomeController#index
when I try to access foo or users I get
I have tried
localhost/cartraderlaravel/public/users
localhost/cartraderlaravel/users
localhost/cartraderlaravel/foo
localhost/cartraderlaravel/public/foo
All of these return a "Not Found" error. Help anyone?
You should point your root directory to cartraderlaravel/public in WAMP so that you need not to visit localhost/cartraderlaravel/public. To do that in WAMP follow :
Click on WampServer icon in taskbar
Select Apache > httpd.conf from the pullup
Search for the term “DocumentRoot”
Change the DocumentRoot path to your custom directory
Search again for “DocumentRoot” again same procedure
Save your changes and “Restart All Services”
Further research shows this is a common problem with WAMP. Something to do with Apache settings. I have moved to using a virtual network and everything works now
I'm too newbie to Laravel...I have written this route to echo "Hello World", but It errors NotFoundHttpException
This is my routes.php (no other code is in the file but the following):
Route::get('/', function(){
return "HELLO WORLD";
});
I have also enable mode_rewrite, and also set AlloOverride to 'all' in apache module.
This is also the URL is use to access the page:
http://localhost/laravel/public/mostafa
Do:
php artisan serve
Use that URL to visit your website.
You will see that you get some output like:
Laravel development server started on http://localhost:8000
When you have no clue what Artisan is take a look at this;
http://laravel.com/docs/artisan
Navigate into your project directory with your command prompt and run there the serve command from above.
Example:
Sometimes the default .htaccess file located in public folder doesn't work in apache. Try altering the .htacess as mentioned here. Alternatively renaming your laravel project folder would work especially in XAMPP.
Some other frameworks treat route definitions as relative to the project web root so a path defined as /foo/bar will match http://example.com/additional/levels/laravel/public/foo/bar and will work without changes even if you move the project tree somewhere else in your public web hierarchy. Laravel, however, considers routes as absolute paths so /foo/bar will only match http://example.com/foo/bar.
The simplest solution is probably to move your code into a separate virtual host and point its document root to laravel/public/. (In this case it seems that's actually the intended set-up.)
(I suppose there's a way to make the framework assume an implicit prefix but I've only been using Laravel for 10 minutes.)