Class instance variables becoming null in php - php

I have this PHP class, whose purpose is to fetch some configuration data from a database and store it for later use:
class GSConfig {
private $configurationData;
private $repository;
public function __construct($pRepository) {
$this->repository = $pRepository;
$this->configurationData = $this->InitializeConfiguration();
}
public function InitializeConfiguration() {
$result = $this->repository->configLoadAll();
if ( $result['data'] ) {
$conf_array = $result['data'];
foreach ( $conf_array as $row) {
$code = strtolower($row ['code']);
$value = strtolower($row ['value']);
//if ($value == "true") $value = (bool)true;
//if ($value == "false") $value = (bool)false;
$this->configurationData[$code] = $value;
}
} else {
$this->configurationData = null;
}
print_r($this->configurationData);
}
public function getConfigValue($key) {
$key = strtolower($key);
if ($this->configurationData != null) {
if( isset($this->configurationData[$key])) {
return $this->configurationData[$key];
}
} else if ($this->configurationData == null) {
// If we reach this code, something went wrong
// (TODO: throw Exception)
echo "<p>Tick</p>";
}
}
}
InitializeConfiguration gets the data and stores it as an array in the $configurationData property. This is working as expected as shown by the output of the print_r function.
However, after initializing, if i attempt to read any value from the $configurationData, i get Tick. Somehow the variable becomes null after the Initialization.
The output would be something like:
print_r output:
Array ( [show_cart] => true [order_mail] => order#shop.de [debug_mode] => true [branch_mode] => true [default_branch] => 1 [agb_file] => agb.txt [kat_order] => k_nr [show_rows] => 5 [product_order] => p_produktnr [cost_per_wu] => 0.66 [message_lang] => eng [free_shipping] => true [free_ship_amt] => 25 [special_price] => true [discounts] => true [cat_show_mode] => all [price_att] => ersatzpreis [mwst_att] => mehrwertsteuer [aktionsp_att] => aktionspreis [katalog_mode] => per_branch )
further output:
Tick
Tick
...
Tick
Anyone knows why this is happenning? Btw, my PHP version is 5.3.1

you're assigning the return value of InitializeConfiguration() but there's no return statement in this function (defaults to "return null").

I suspect it's because in your constructor, you assign $this->configurationData to the return value of InitializeConfiguration(). But it doesn't look like InitializeConfiguration() returns anything. I think the easiest way to fix this is to change:
$this->configurationData = $this->InitializeConfiguration();
to:
$this->InitializeConfiguration();

The problem is that you're assigning the return value of InitializeConfiguration to $this->configurationData inside your constructor, which will be null.
The following remains sound advice:
Strongly suspect your error is arising from your using the incorrect comparison operator.
Never, ever do this in PHP:
if ($this->configurationData == null)
When testing against null, false or 0, always use === which checks that both the values and types of each variable are the same. Simply using == will cast one side to the type of the other before the conversion.
The following are all true when using the == operator:
null == 0;
array() == null;
null == false;
false == 0;
You also shouldn't be using else if ($this->configurationData == null) in getConfigValue; use a simple else since your intent seems to be to cover all other cases.

Related

How to sanitize a [null] array input for my API program?

I am calling API through postman and passing following parameters.
reason: string
staff_ids[]:
When pass staff_ids blank then I got [null] in server-side.
so that the condition gets always true.
if(isset($request->staff_ids) && !empty($request->staff_ids)){
//
}
Is there any way to check if array has [null]?
Instead of checking, you may simply filter out all NULL values before other works
if (!isset($request->staff_ids) || $request->staff_ids === null) {
$request->staff_ids = array(); // default to empty array if is not set or is null
}
if (!empty($request->staff_ids)) {
$request->staff_ids = array_filter($request->staff_ids, function ($id) {
return ($id !== null);
});
if (!empty($request->staff_ids)) {
// ...
}
}
I have filtered array values before checking as #KoalaYeung Answered. It is working fine.
$request->staff_ids = array_filter($request->staff_ids, function ($id) {
return ($id !== null);
});
if(isset($request->staff_ids) && !empty($request->staff_ids)){
///
}
Is there any better approach?
you can check this with is_null function and sizeof() for array
if(!is_null($request->staff_ids) && sizeof($request->staff_ids)){
}

How can I convert an array into a php statement?

I have an array like this...
[Summary] => Array
(
[0] => yearManufactured
[1] => &&
[2] => make
[3] => ||
[4] => model
)
how can I convert this array into function calls and operators and then use it to make a comparision, for example turn it into this...
if( $this->yearManufactured() && $this->make() || $this->model() ) {
// do something
} else {
// do something else
}
Methods in class..
public function yearManufactured() {
return true;
}
public function make() {
return false;
}
public function model() {
return true;
}
This seems like something that could actually be a valid use for eval. You can verify that each array item is either an operator or a valid method name, and convert the result of the method call to a boolean string. Putting those things together should result in a string that you can safely eval without worrying about it doing something nasty, other than maybe causing a parse error, which can be caught in PHP 7.
If you find anything in the array that isn't supposed to be there, or the expression doesn't parse, you can return null, or throw an exception, however you want to handle it.
public function evaluateExpressionArray(array $expression) {
// build the expression
$expr = '$result =';
foreach ($expression as $part) {
if ($part == '||' || $part == '&&') {
$expr .= " $part ";
} elseif (method_exists($this, $part)) {
$expr .= $this->$part() ? 'true' : 'false';
} else {
return null;
}
}
// try to evaluate it
try {
eval("$expr;");
} catch (ParseError $e) {
return null;
}
return $result;
}
Be very careful with eval, though. Don't ever put anything into it unless you know exactly what it is.
Here's an example to mess with.

return boolean if any item in the array is empty/not empty

I have an array of objects. I need to loop over these objects (preferably without foreach(), and if a certain key in the objects is not empty, then return true, otherwise return false.
For example,
$items = array(
'0' => stdClass {
name => Ryan
suppliers => array()
}
'1' => stdClass {
name => Dave
suppliers => array(
'0' => stdClass {}
)
}
)
Essentially, I need to go through the array and check the "supplier" key of the object, and if any of them are not empty, return true for the entire thing, otherwise return false.
What's wrong with foreach?
$check = function($arr) {
foreach($arr as $o) {
if (!empty($o->suppliers)) return true;
}
return false;
};
If you want to use it only in one place, use anonymous function
I don't understand why you don't want to use foreach because thing is - foreach is only right way because you leave loop as soon as you find value
One other option, reduce the array to a boolean.
array_reduce($items, function($hasSupplier, $item) {
return !empty($item->suppliers) || $hasSupplier;
});
Still, I prefer the foreach solution since it won't continue to iterate unnecessarily.
You can filter and check for a result:
if(array_filter($items, function($v) { return !empty($v->suppliers); })) {
//at least one not empty
} else {
//all are empty
}
If you really want a boolean:
$result = (bool)array_filter($items, function($v) { return !empty($v->suppliers); })

PHP filter_var: How to make sure the user provides correct data types - true or false only

I want to compare two arrays, one is set by default and another by user input.
When I have set a boolean value only in the default so I want to make sure the user won't use string or number. for instance, 'truex' or '1' is not acceptable.
Below is my sample of code,
$default = array(
"randomise" => false,
"id" => null
);
$config = array(
"randomise" => truex
);
function process_array($default,$config)
{
# Loop the array.
foreach($default as $key => $value)
{
if ((filter_var($default[$key], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) === NULL) && (filter_var($config[$key], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) === NULL))
{
return 'true or false only';
}
}
# Return the result.
return $array;
}
print_r(process_array($default,$config));
but this code returns 'true or false only' even though the user provides the correct data type. how can I fix this?
Alright first up you need to check that $config contains the key in $default. [Asside: If $config is user supplied... they could never user-supply an object like that, perhaps you meant $config=array("randomize"=>"truex");.. unless by user supplied you mean some other developer as the user (not a web user)).
Second of all $config['id'] will always fail the test as you've written it (because it's not a boolean).
So, I'm trying to guess at what you're doing here but I think this is what you want...
$default = array("randomise"=>false,"id"=>null);
//Example input
$config = array("randomise"=>"truex");
function process_array($default,$config) {
foreach($default as $key => $value) {
if (is_bool($default[$key])
&& isset($config[$key])) {
//Update the array with the filtered value
$config[$key]=filter_var($config[$key],FILTER_VALIDATE_BOOLEAN,
FILTER_NULL_ON_FAILURE);
if ($config[$key]===null)
return '$key can be true or false only';
}
}
}
return $array;
}
print_r(process_array($default,$config));

Is there a better way to loop two associative arrays to match their values?

I'm parsing the HTTP_ACCEPT_LANGUAGE header to get users' language and I'm building a class to do that.
Actually I build an associative array ("$this->user_lang") where keys are the language (such as "en-us", "it-it", "it-ch" etc) and the value is the quality factor (so I can order languages).
Then I have another associative array named "$this->installed_langs" where I declare supported language and locales (in the form "en" => "en_US", "it" => "it_IT").
All I want to do is try to match one of the key of "$this->user_lang" with one of the "$this->installed_langs" (without care of the local zone after the "-") and return the first occurrence (with no care for other matching case).
I ended up with this method but it seems a bit too complex...
public function show() {
$g_locale = null;
foreach ($this->user_lang as $lang => $q) {
foreach($this->installed_langs as $valid => $locale) {
if (strpos($lang, $valid) !== false) {
if ($g_locale === null) $g_locale = $locale;
}
}
}
// debug:
echo $g_locale;
}
I hope I have explained it well, btw if you need more informations, please, ask me.
Try this
public function show() {
$g_locale = null;
foreach ($this->user_lang as $lang => $q) {
if ( array_key_exists( $lang, $this->installed_langs ) ) {
$g_locale = $this->installed_langs[$lang];
}
}
}
function show() {
$g_locale = null;
foreach ($this->user_lang as $lang => $q) {
$_key=explode($lang, '-'); // 'en-us' => 'array('en', 'us')
$key=$_key[0]; // 'en'
if ( array_key_exists( $key, $this->installed_langs ) ) {
$g_locale = $this->installed_langs[$key];
}
}
}

Categories