laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.33k stars 10.96k forks source link

Laravel .env conflicts and overwrites between 2 laravel projects #19454

Closed faiwiz closed 7 years ago

faiwiz commented 7 years ago

I have two laravel projects Project-A for MSSQL database and Project-B for MSSQL Database A-Porject laravel version 5.4.24 B-Porject laravel version 5.4.23

A-Porject is working for frontend ui and B-Porject some more tables are available mssql(client requirements) so I have to get Order from Project-A and Get Detail of Order History from Project-B

Database config in A-Porject

DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=mysql_database DB_USERNAME=root DB_PASSWORD= DBPREFIX=prefix

Database config in B-Porject

DB_CONNECTION=sqlsrv DB_HOST=mssqldatabase.sqlurl.compute.amazonaws.com DB_PORT=1433 DB_DATABASE=DYNAX09_DATABASE DB_USERNAME=USERNAME DB_PASSWORD=PASSWORD DB_PREFIX=db.

Code for get/orderDetails/ in Project-B

Routes/Api.php

Route::get('/get/orderDetails/{orderID}','Orders\OrderController@getOrderDetails');

so I am calling it from Model of Project-A using library //ixudra/curl $response = Curl::to(env('MSSQLAPILINK').'get/orderDetails/'.$orderID)->get(); This url works fine when I open it in browser but when getting records in Project-A and using Curl::to(env('MSSQLAPILINK').'get/orderDetails/'.$orderID)->get() Project-B will configured with Project-A's env configuration.

Note: when open in browser env('MSSQLAPILINK').'get/orderDetails/1' and print $_SERVER Project-B its showing correct configured information in

[DB_CONNECTION] => sqlsrv [DB_HOST] => mssqldatabase.sqlurl.compute.amazonaws.com [DB_PORT] => 1433 [DB_DATABASE] => DYNAX09_DATABASE [DB_USERNAME] => USERNAME [DB_PASSWORD] => PASSWORD [DB_PREFIX] => db.

when I hit api service of orders (Project-A.local/api/getOrders) using POSTMAN and called Curl::to(env('MSSQLAPILINK').'get/orderDetails/'.$orderID)->get() from curl responses it loses [DB_*] in $_SERVER and using Project-A database and thrown following error

QueryException in Connection.php line 647:\n SQLSTATE[42S02]: Base table or view not found: 1146 Table 'mysql_database.orderDetails' doesn't exist (SQL: select * from ORDER_DETAILS where order_id = 1 limit 1)\n (I am wondering why its using mysql query format )

themsaid commented 7 years ago

Sorry but this kind of questions should be asked on the forums, we keep this repo for bug reporting only. I suggest that you try to brief the issue a little bit and include only the details one might need to understand what might be wrong.

faiwiz commented 7 years ago

This is core bug, i don't know where I post it $_SERVER variables conflicts

I have just make a hack in core file vendor/laravel/framework/src/Illuminate/Foundation/helpers.php function env($key, $default = null) {

    switch($key){
        case "DB_CONNECTION":
            return "mssqldatabase.sqlurl.compute.amazonaws.com";
        break;
        case "DB_HOST":
            return "sqlsrv";
        break;
        case "DB_PORT":
            return 1433;
        break;
        case "DB_DATABASE":
            return "DYNAX09_DATABASE";
        break;
        case "DB_USERNAME":
            return "USERNAME";
        break;
        case "DB_PASSWORD":
            return "PASSWORD";
        break;
        case "DB_PREFIX":
            return "db.";
        break;
    }
themsaid commented 7 years ago

How is it a core bug? Can you share more details about your findings?

themsaid commented 7 years ago

One thing I'd like to share, don't use env() in your code because it might return cached results, always use configuration options.

sisve commented 7 years ago

To clear things up; this is a known issue. It's just not documented.

You must run php artisan config:cache in both Laravel projects to generate a cached configuration. This is a requirement for Apache on Windows (and many other setups).

Dotenv will set process-wide environment variables, and only if they don't already exists. This means that the first Laravel app is executed, sets the first environment variables, then it calls the same webserver (in your case) where the second Laravel app sees that the environment variables are already set, and wont set the correct ones.

This often shows up when you have an application calling an api at the same machine, or during load tests. You should be able to open two browsers, point them to /projectA and /projectB, and reproduce this by just refreshing the page. A sleep(...) helps to slow things down.

Also, env() never returns cached results. It returns the currently set environment variable. When you use php artisan config:cache dotenv isn't loaded (Laravel 5.2+) and the environment variables aren't set. That's why you should use config() instead.

Ref: https://github.com/vlucas/phpdotenv/issues/76#issuecomment-224899197 Ref: https://github.com/laravel/framework/issues/13906

marwan2 commented 6 years ago

This is a bug sir, not a forum discussion

neoplomero commented 6 years ago

This is BIG BUG, But thanks a lot @sisve !!! you saved my day very bad.

walrt commented 6 years ago

I had this error in lumen, and i could not find how to run php artisan config:cache like explained by @sisve. Anybody know how to fix it in lumen? Thank's a lot!

sisve commented 6 years ago

@walber-teixeira For Lumen, use another webserver configuration (avoid Apache on Windows, for example), or write your configuration values directly in the config files (and stop using the .env file).

vishal-adhikari commented 4 years ago

I was having this same error and tried to clear each and everything to clear cache & config but nothing worked for me but php artisan config:cache worked. Thanks sisve.

qwertynik commented 4 years ago

@sisve Thanks for adding clarity. It's 2020 and this 'bug' (or undesirable feature) still sucked a good amount of time 😂. Any idea which setup on Windows is not prone to this?

qwertynik commented 4 years ago

Thanks for asking @faiwiz

mauriciomueller commented 2 years ago

Laravel is getting the same .env file of the main project, so it overwrites the variables of the second one. To fix you can run the project in another port or use prefix in your variables.