Laravel environment variables: Undefined Index for array - php

I have the following setup with Laravel 4.2:
bootstrap/start.php (hostname correct, environment is local)
$env = $app->detectEnvironment(array(
'production' => array('produrl'),
'local' => array('MBP-Ivo.local', 'iMac-Ivo.local'),
));
.env.local.php (in project root, .env.php is exactly the same except mysql info)
<?php
return [
// Code variables
'mysqlUsername' => 'user',
'mysqlPassword' => 'password',
'mysqlDatabase' => 'database',
'paymentIdeal' => false,
'shipmentCountries' => [
'Nederland' => 'Nederland',
'Belgie' => 'Belgie'
]
];
config/app.php (I don't overwrite with app/config/local/app.php)
<?php
return array(
'paymentIdeal' => $_ENV['paymentIdeal'],
'shipmentCountries' => $_ENV['shipmentCountries']
);
There are some more variables, but the problem is with shipmentCountries.
Undefined index: shipmentCountries
All variables declared are working (eg paymentIdeal), but shipmentCountries gives an error. I think because it's an array? The name is exactly the same everywhere, including capital letters.
Does anyone know why I can't get this working?
BTW: I'm choosing this option to prevent users having to change their application configs. I want to use only one *.env file to configure all important stuff. And yes, I know these values could be saved to the database, but that's for later :)
/edit:
When I dump the $_ENV, I get the following:
Array
(
[mysqlUsername] => ***
[mysqlPassword] => ***
[mysqlDatabase] => ***
[paymentIdeal] =>
[shipmentCountries.Nederland] => Nederland
[shipmentCountries.Belgie] => Belgie
);
Somehow it "flattens" the array shipmentCountries. Anyone knows how and why?

You're right, the file get's converted in a flat array using the dot notation (with array_dot)
I believe the reason behind this, is that environment variables are just not supposed to be arrays as they are normally passed in when using a CLI.
So, what can you do about it?
Convert the array from dot to non-dot
In your app/start/global.php use this code to convert the array back to it's original format:
$array = array();
foreach ($_ENV as $key => $value) {
array_set($array, $key, $value);
}
$_ENV = $array;
Use another file and load it yourself
Also inside app/start/global.php (this would be .my.env.local.php)
$config = require base_path().'/.my.env.'.app()->env.'.php';
$_ENV = array_merge($_ENV, $config);
Sidenotes
I'd think again if you really don't want to use config files. It is possible to have your own config file and maybe you can even place it in the root of the project.
Also I'd change the array to a numeric one:
'shipmentCountries' => [
'Nederland',
'Belgie'
]

With the tip of lukasgeiter, I went searching again, and found this:
https://github.com/laravel/framework/issues/5291 and https://github.com/laravel/framework/pull/4623
It looks like Laravel doesn't support this option.
What I do now is save it as a JSON string, and decode it when neccesary.

Another way is to json_encode your associative array in the env.local.php, then in your config
json_decode($_ENV['shipmentCountries'],true);
Don't forget the boolean argument there to make it convert into arrays.

Related

Is it possible to get returned data from a file in PHP? [duplicate]

This question already has answers here:
Creating a config file in PHP
(15 answers)
Closed 3 months ago.
I am creating a reusable app, which requires some configurations stored in config.php. This configuration file does not have any function, but the configuration are returned as an array, eg
<?php
return [
'db_name' => 'db_name',
'password' => 'password',
........
];
I was hoping to create a function which includes this config file, and get each config set. An example is laravel config() function which returns a configuration value. Is there any way to acheive this?
I have tried
$filename = 'config.php';
include $filename;
$contents[] = file_get_contents($filename);
but this just gets whatever is in the file as a string.
In a nutshell, this is possible if you assign the config array to a variable instead of return:
<?php
$config = [
'db_name' => 'db_name',
'password' => 'password',
........
];
Then, you can access the $config everywhere this file is included. You don't need file_get_contents in this case.
But please note that this solution adds a potential vulnerability to your application, literally allowing to execute an arbitrary code provided inside config.php.
Instead of storing the configuration in a php file, consider using the dotenv component, or if this too complex for your app, use a harmless format such as JSON or YAML:
config.json:
{
"db_name": "some_name",
"password": "some_password",
...
}
then, in your code:
$filename = 'config.json';
$parsed = json_decode(file_get_contents($filename), true);
echo $parsed['db_name']; // -> some_name
echo $parsed['password']; // -> some_password
Edit I have just followed the link from where your question was closed (Creating a config file in PHP) and was interested to find out that the approach you have taken (using return) does appear to be valid and is recommended there. So, don't let me put you off that. I always do it like I explain below:
In config.php get rid of return and assign the array to a variable.
<?php
$config = [
'db_name' => 'db_name',
'password' => 'password',
........
];
Then use require_once './config.php'; to get it into any .php script you like. You can then use $config in that script.
Note the path to config.php must be correct. I have assumed above that it is in the same directory as the file you are importing it into with require_once so the path used was ./config.php. If config.php was in the parent directory of the file using it then the path would have had two dots: ../config.php.

Returning Three Dimensional Associative Arrays with PHP

I suppose I am a noob with PHP so apologies if I sound dumb, but, I do have a troubling dilemma, I have spent the last six hours plus scouring Google for any hints and found none so here I am on the SO forum looking for some 'pointers' in the right direction.
I have an issue with returning 3DAA's from a function in a class to other parts of my code and no matter what I try I'm getting a null value back, according to the error log anyway, but when I run this code separately from the framework, in a single file using the same declarations it miraculously starts working and echos the specified part of the array to the screen wahey, but I don't know why it suddenly works nor why it won't work in the framework and supplies a null value.
I was wondering if anyone out there has experienced such weird errors with returning 3DAA's and if so, how they got around it. If you want to see the code ask and I'll post it.
<?php
class Core {
public function GetConfiguration() {
$configuration = array(
"cobalt" => array(
"name" => 'Cobalt',
"version" => '1.0.7',
"directory" => array(
"root" => 'application',
"modules" => 'application/modules',
"html" => 'application/html'
)
),
"application" => array(
"name" => 'Cardinal Technologies',
"version" => '1.0.2',
"server" => 'http://localhost',
"seo" => array(
"copyright" => 'Ida Boustead',
"description" => 'Welcome to Cardinal Technologies, here at Cardinal Technologies we pride ourselves in providing the best possible customer service whether you need a repair or upgrade for a computer, android phone or tablet, even alarms and CCTV',
"keywords" => 'computer repair,computer upgrade,computer upgrades,android phone repair,phone repair,android tablet repair,tablet repair,alarms,cctv,network installation,network install',
"robots" => 'index,follow'
)
)
);
return $configuration;
}
public function LoadModule($module) {
require_once 'application/modules/' . $module . '.class.php';
}
}
?>
Hope this helps.
I'm calling it like this.
require_once 'application/Core.class.php';
$core = new Core();
$configuration = $core->GetConfiguration();
and getting an array value like this.
$dir = $configuration['cobalt']['directory']['html'];
the prior is a snippet from a larger file but this is what relates to that function.
I get PHP Notice: Undefined variable: dir in the log which is what led me to believe the function was the problem.
If I echo $dir it echos application/html which is what it's supposed to, but it is not usable for anything other than echo which is pointless to me as I need that value to make other parts of the framework work.
Right it was me being a dumb dumb, I put the declarations in the wrong place, outside of the class and it did not like it.
I moved them to inside of each function that stalled the code and it fixed that issue. Thanks anyway.

laravel: config file name convention?

foo_constants.php or fooConstants.php?
It seems laravel would do some name conversion when you use Config::get('...'), which one do you use?
foo.php
Why specify constants at all? Convention I've generally seen is single word filenames. I think in general most 'config' type settings will be constant in an environment even if it is variable between environments.
Take a look at the aws/aws-sdk-php-laravel composer package as an example. That file is named config.php in the package, but gets published to aws.php.
rydurham/Sentinel is another popular package. It also only has a single-word filename.
Update
In the situation you describe in your comment, I would do something like this:
<?php // File: foo.php
return [
'sheep' => [
'clothing' => 'wool',
'chews_on' => 'cud',
],
'wolf' => [
'clothing' => 'fur',
'chews_on' => 'sheep',
],
];
And you can access both of those via Config::get('foo.sheep') and Config::get('foo.wolf'), respectively. When they're defined on the server, they're still 'on the server' so to speak. If you wish to release the values stored in foo.sheep to the public you can, and you can do so without also exposing foo.wolf.

Trying to connect to database

I'm working on a rewrite of a project from the ground up and figured I would try to learn MVC along the way. In this case, I've chosen Phalcon and am still working through the fundamentals of converting the tutorials to my own project.
I have two "configuration" settings that I need to account for. First, I need to read a configuration file that has the database credentials (this works properly).
require_once('../fileconfig.php'); // Read config file
$init = new Phalcon\Config\Adapter\Php("../fileconfig.php"); //Convert it to array
But once I have that, how do I actually connect to the database and add it to $di-> (which, if I understand correctly, is effectively the global class? Ultimately, I want to pull the contents of "select * from config" into an array and use that for the application configuration. In this case, var_dump($dbh) returns "null"
//Connect to database
$di->set('db', function() use ($init) {
$dbh = new \Phalcon\Db\Adapter\Pdo\Mysql([
"host" => $init->database->host,
"username" => $init->database->username,
"password" => $init->database->password,
"dbname" => $init->database->dbname
]);
return $dbh;
});
var_dump($dbh); //returns null
If I remove the $di-> section, the array returns the data that I need, but it still doesn't help me figure out how to connect to the database and have it available globally for other functions in the models:
$dbh = new \Phalcon\Db\Adapter\Pdo\Mysql([
"host" => $init->database->host,
"username" => $init->database->username,
"password" => $init->database->password,
"dbname" => $init->database->dbname
]);
Returns:
object(Phalcon\Db\Adapter\Pdo\Mysql)[28]
protected '_descriptor' =>
array (size=4)
'host' => string 'localhost' (length=9)
'username' => string 'testuser' (length=8)
'password' => string 'testpass' (length=8)
'dbname' => string 'testdb' (length=6)
This question seems to be close to what I'm asking, but was more about error handling than the actual connection and I didn't see an answer to my question there.
To resolve your database you need to resolve your di. You could resolve it the file you declared it in with
$di->getShared('db')
But note, you don't want to do that. You want your files seperated with their responsibilities.
Inside of a class that inherits \Phalcon\Mvc\Controller you can use
$this->db->
Please refer to http://docs.phalconphp.com/en/latest/reference/di.html in order to see why to use a DI, and all the nuances of accessing it
It really helps to go through other phalcon projects and look at how everything works together. Please refer to the source here and look at how projects are set up:
https://github.com/phalcon/invo
https://github.com/phalcon/vokuro
https://github.com/phalcon/forum
These are ranked by complexity so start with invo first and then move on

PHP: Certain elements missing from array

So I've got a bug somewhere in my code that stops certain elements from being included in an array, this is the best way that I can explain it.
I've got a static file (Config.php) that contains a large array full of data, within this array there is another array with a key of "PredefinedValues", this contains values that need to be referenced by other parts of the script.
The issue: I can reference everything in the array except for 5 values that I recently added, I var_dump the array and they're not there when they're clearly in the file. I've reuploaded the files to my web server around 5/6 times, restarted php, restarted the server and it's not fixed. The issue does not occur on my local machine (Windows) but it does occur on my Linux server (Ubuntu).
The array is structured like this:
<?php
global $Configuration;
$Configuration = array(
"PredefinedValues" => array(
"Example" => "example",
"123" => "test",
"abc" => "test2",
"asdf" => "value2",
"val2" => "value3",
),
And the values I wouldn't be able to access are abc/asdf - but all of the values above/below it are fine.
Init file:
require_once("config/Config.php");
Class Lib
{
Public $Root = __DIR__;
Public $DependencyRoot;
Public function __construct()
{
//error_reporting(E_ERROR | E_WARNING | E_PARSE);
error_reporting(E_ALL);
Global $Configuration;
var_dump($Configuration["PredefinedValues"]);
$this->DependencyRoot = __DIR__ . "/libs/Dependencies/";
}
}
?>
Var_dumping the array within the __construct doesn't work, but when I var_dump it straight after the require, it works fine.
Any ideas? Help would be greatly appreciated.

Categories