codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.4k stars 1.9k forks source link

Bug: site_url() ignores Config\App::$baseURL when not passing $config #7290

Closed c4user closed 1 year ago

c4user commented 1 year ago

PHP Version

7.4

CodeIgniter4 Version

4.3.2

CodeIgniter4 Installation Method

Manual (zip or tar.gz)

Which operating systems have you tested for this bug?

Windows

Which server did you use?

apache

Database

MariaDB 10.2

What happened?

site_url() function ignores App->baseURL

Steps to Reproduce

Change config("App")->baseURL and check site_url("test") output.

// default baseURL = "http://localhost:8080/";
$app = config("App");
$app->baseURL = "https://test.com/";

return site_url("/login"); // output: http://localhost:8080/login

Expected Output

Output containing the new baseURL (https://test.com/login).

Anything else?

No response

c4user commented 1 year ago

Another test:


// default baseURL = "http://localhost:8080/";
$app = config("App");
$app->baseURL = "https://xxx.test.com/";
$app->allowedHostnames = [
   "xxx.test.com",
];

return site_url("/login"); // output: http://localhost:8080/login
kenjis commented 1 year ago

Thank you for reporting!

But unfortunately, this is not a bug, or we probably cannot fix it. Because since v4.3.0, Multiple Domain Support is added. https://codeigniter4.github.io/CodeIgniter4/changelogs/v4.3.0.html#multiple-domain-support

The current URL is determined when a Request object is created. And you cannot change it later. Because the current URL is never changed in a request.

If you want to change the baseURL, please pass the Config object to site_url().

        $app = config("App");
        $app->baseURL = "https://test.com/";

        return site_url("/login", null, $app);

Why do you need to change the baseURL? Can you explain your use case?

c4user commented 1 year ago

Actually my problem was related to form_open. When I examined form_open function, found site_url. The form_open/site_url functions related to the baseurl cause problems when using dynamic subdomains.


$app = config("App");
$app->baseURL = "https://xxx.test.com/";
$app->allowedHostnames = [
   "xxx.test.com",
];

I actually do this definition with filters/pre. At least if it is possible to change it with the filter pre, there will be no problem.

kenjis commented 1 year ago

I think if you set $allowedHostnames in Config\App, you don't need it in the filter.

c4user commented 1 year ago

How can I use code for domain names such as userX.test.com, random-chars.test.com, can you show an example? Subdomains are set by the user.

I think changes need to be made with filters/pre.

It also doesn't support regex even. At least that could have been.

I cannot upgrade version for this reason.

kenjis commented 1 year ago

How do you know the domain names now?

c4user commented 1 year ago

I set baseURL in Filters/pre or controller. So I can use form_open, site_url etc. without problem.

c4user commented 1 year ago

I get it from session or database according to user's choice. Then I edit it with baseUrl. For example, if user chooses kenjis for subdomain, I read from session and edit baseURL to kenjis.test.com.

kenjis commented 1 year ago

Sorry, now the code round the current URI is very complicated.

Please try:

<?php

namespace App\Controllers;

class Home extends BaseController
{
    public function index()
    {
        $uri = $this->request->getUri();

        // Update the current URI object
        $uri->setBaseURL('https://test.com/');
        $uri->setScheme('https');
        $uri->setHost('test.com');

        helper('form');

        return form_open("login");
    }
}
c4user commented 1 year ago

thank you!

kenjis commented 1 year ago

Since the URI-related code is complicated, difficult to understand, and a bit buggy, I have sent PR #7282 with the code reorganized and rewritten.

However, since it brings breaking changes, I do not yet know when it will be merged or not.