如何在Laravel中将公共文件夹更改为public_html

81
我正在使用一个共享主机,它使用cPanel作为控制面板,在cPanel中,public_html是默认的根目录,因此我无法使我的Laravel应用程序正常工作。
有没有办法让Laravel使用public_html而不是public文件夹?
16个回答

104

通过简单的搜索就能轻松找到这个。

参见:https://laracasts.com/discuss/channels/general-discussion/where-do-you-set-public-directory-laravel-5

在您的index.php文件中添加以下3行代码。

/*
|--------------------------------------------------------------------------
| 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__;
});

编辑:


正如Burak Erdem所提到的,另一种选项(更可取的)是将此放置在\App\Providers\AppServiceProviderregister()方法中。

/**
 * Register any application services.
 *
 * @return void
 */
public function register()
{
    // ...

    $this->app->bind('path.public', function() {
        return base_path('public_html');
    });
}

无法运行:致命错误:在...上调用一个非对象的成员函数make() - Ravexina
只是添加那个?我可以在没有任何错误的情况下切换它。你能发布完整的错误消息吗?因为现在它并没有告诉我太多信息。 - Robert
1
@Robert 当我使用你的解决方案时,它会给我一个错误[ErrorException] chdir(): 没有这样的文件或目录(errno 2) - Faisal Ahsan
2
我知道这已经过去了一段时间,但是这个问题在谷歌上的排名仍然很高。因此我想指出,对于我来说,这些代码行应该在“Turn On The Lights”部分之后添加。然后你应该将path.public更新为path.public_html。至少对我来说是这样的。 :) - Carsten
1
这对于laravel-mix无效,它仍会将资产编译到“public”目录中。 - Lars Nyström
显示剩余3条评论

27
如果 Robert 的 index.php 解决方案对你不起作用,你也可以将下面的代码注册到应用服务提供商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';
    });
}

我更喜欢使用这种方法。它在Laravel 5.3中有效。 - Muhammad Zamroni
我更喜欢这个,因为在框架更新时 index.php 更有可能被更改。 - Mladen Janjetovic
1
这个答案是不是应该说 public_html 而不是 public_http - hannebaumsaway
我正在使用 Laravel 5.7,但它不起作用,我需要做些什么吗? - Hemant Kumar

16

服务器

主题中描述的方法运行良好,因此修改 App\Providers\AppServiceProvider.php 的 register 方法应该可以完成工作:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

public function register()
{
    $this->app->bind('path.public', function() {
        return base_path() . '/public_http';
    });
}

本地 PHP artisan serve 开发

然而,你可能会遇到另一个问题。如果你在本地机器上开发应用程序并使用 php artisan serve 命令来提供服务,那么你只使用以上语法是无法正常工作的。你还需要调整位于主目录中的 server.php 文件。编辑它的内容,并将每个出现的 /public 替换为 /public_html,使其看起来像这样:

<?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';

之后,停止您的服务器并使用php artisan serve重新加载它。

前端Laravel-mix开发

如果您正在使用webpack和laravel-mix生成您的css和js文件,则这也需要一些更新。如果不调整webpack.mix.js,则在npm run watchnpm run production上会出现以下结果:

.
..
public
  _html
    js
  public_html
    css
public_html

那么它会破坏你的代码。为了澄清这一点,您需要为webpack.mix.js文件提供公共路径。它可能看起来像这样:

所以它会破坏你的代码。为了澄清这一点,您需要为webpack.mix.js文件提供公共路径。它可能看起来像这样:

const mix = require('laravel-mix');

mix.setPublicPath('public_html/');
mix.js('resources/js/app.js', 'js')
mix.sass('resources/sass/app.scss', 'css');

这将更改公共目录的默认定义,从public更改为public_html,接下来的行提供了一个相对路径到您的setPublicPath值。

祝编码愉快!


谢谢你的回答!这很好用,除了对于vue。它会将css和js编译到正确的文件夹中(在我的情况下是/../public_html),但它们不起作用。当它编译app.js时,它不考虑.vue文件的路径:./resources/js/components/SetBgImg.vue?vue&type=script&lang=js&":,应该是 ./../projectname/resources/js/components/SetBgImg.vue?vue&type=script&lang=js&": 如何解决这个问题? - sharkyenergy
不要忘记重新启动 npm run 以使更改生效。 - Fer Toasted
我不使用Vue,但现在这个答案确实适用于本地主机,并且我摆脱了每次在云中将资产复制到同步项目的公共文件夹的麻烦。 - CodeToLife

9

请访问此网址:

/app/Providers/AppServiceProvider.php

并将此代码追加到文件末尾:

public function register()
{   $this->app->bind('path.public', function() {
    return realpath(base_path().'/../public_html');
  });
}

5

如果你的public_html不在laravel文件夹内,那么你需要使用以下代码进行更新:

$this->app->bind('path.public', function() {
   return realpath(base_path().'/../public_html');
});

5
我使用的是Laravel 10版本,并且尝试了所有建议的解决方案,但都没有起作用。所以在引导文件中添加以下代码。
$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

添加了以下代码行,运行良好。
$app->usePublicPath(__DIR__.'/../../public_html');

所有上述的解决方案对我都没有起作用,只有这个有效。谢谢。 - Noob Coder
跟我一起工作 - رضا رحمتی - Reza Rahmati
$app->usePublicPath(str_replace('bootstrap', '', __DIR__).'\mysite.com'); - undefined

4

在简单的根目录中创建 .htaccess 文件并添加以下代码:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

3

我花了两天时间才弄明白,但最终我通过以下步骤将我的Laravel项目部署到了我的cPanel Web主机:

  1. 按照以下方式更改server.php文件:
if ($uri !== '/' && file_exists(__DIR__ . '/public_html' .$uri)) {
    return false;
}

require_once __DIR__ . '/public_html/index.php';
  1. 将 webpack.mix.js 更改如下:
mix.js('resources/js/app.js', 'public_html/js')
    .postCss('resources/css/app.css', 'public_html/css', [
        //
    ]);
  1. 将 Laravel 项目中的 "public" 文件夹更名为 "public_html",并将代码上传到 cPanel 的根目录。确保您已备份当前的 public_html 目录。如果您的托管服务上有正确的 PHP 版本并编辑了 .env 文件,则一切应该正常工作。

3
我个人认为最简单的解决方案是创建符号链接。
1.备份您的public_html文件夹。 2.通过ssh连接到您的服务器。 3.在我的特定情况下,整个应用程序位于~/laravel文件夹中。 4.现在您必须在~/文件夹中: 5.运行rm -r public_html。此命令将删除public_html文件夹及其所有内容。 6.创建符号链接ln -s $(pwd)/laravel/public $(pwd)/public_html$(pwd)将被替换为从服务器根目录开始的绝对路径。 7.现在您应该能够看到所需的结果。

我不知道为什么这个解决方案没有得到更多的赞?它是一个非常好的解决方案,而不是对代码进行更改。谢谢你,善良的陌生人。 - Svetoslav Stefanov

3

如果需要更改公共路径以使其对Artisan也可用,请在最后一个singleton方法之后添加以下内容到bootstrap/app.php

$app->bind('path.public', function () {
    return base_path("<your public directory name>");
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接