PHP empty array deceleration throwing error - php

I am using the third party provided PHP binary for implementing chat server.
In that PHP binary, most of the PHP classes contain below code
$list = $list[0];
Just above the line $list=$list[0] there is one more line $db = Db::getInstance(); in my PHP class. I am not sure might be this getInstance code is trying to populate list array.
Whenever API is called the PHP classes its throwing below error
Undefined variable: list in /var/www/HeXXX/XXXX/city.php on line 53
I am new to PHP and not able to find the solution. Might be its duplicate question but I have already searched in StackOverflow and didn't get the similar post.
Full code :
public static function all() {
// $list = [0];
$db = Db::getInstance();
$list = $list[0];
$req = $db->query('SELECT * FROM users');
// we create a list of Post objects from the database results
foreach($req->fetchAll() as $user) {
$list[] = new User($user['userid'], $user['firstName'], $user['lastName'], $user['email'], $user['password'], $user['status'], $user['regTime'], $user['username'], $user['avata r'], $user['gender'], $user['dob'], $user['vCode'], $user['city_id'], $user['country'], $user['mobile'], $user['dating_status'], $user['interest_in'], $user['about_me'],$user['request_ limit']);
}
return $list;
}

The notice is telling you that something is accessing the $list variable before it has been set. This is caused by $list[0] having to be evaluated to give $list a value.
You (or the library author) probably wanted $list = array(); to initialize the $list variable to an empty array first.

Try replacing that line with:
if (!empty($list[0])){
$list = $list[0];
}

Related

How to fix "Uncaught Error: Call to a member function insertOne() on null" in php

I followed the solution introduced here https://stackoverflow.com/a/36041188/11295637 to create a new csv file and fetch specific columns of a large csv file to the new one.
But, I get this error: Uncaught Error: Call to a member function insertOne() on null.
The code is as follows:
php
$new= Writer::createFromPath('path\to\file', 'w+');
$filename= Reader::createFromPath($filename, 'r');
$filename->setOffset(1);
$filename->each(function ($row) use ($indexes) {
$new->insertOne($row);
return true;
});
The problem is that the new variable is undefined. I tried also
php
$new= Writer::createFromFileObject(new SplTempFileObject());
But I got the same error.
In PHP, if you want to reference a variable defined outside of a function, you must either (a) use a use qualifier in your anonymous function signature or (b) use a global statement inside your function.
In your case, you have a use qualifier but it references a variable $indexes. I don't see an $indexes variable in your code, so you either need to add $new to that list or replace $indexes with $new.
$new = Writer::createFromPath('path\to\file', 'w+');
$filename = Reader::createFromPath($filename, 'r');
$filename->setOffset(1);
$filename->each(function ($row) use ($new) {
$new->insertOne($row);
return true;
});
To select only the indexes specified in the $indexes variable, you should select certain keys from $row and then rebuild a new row. You can use array_flip and array_intersect_key to do that.
// convert [cat, dog] => [cat => 0, dog => 1]
$indexKeys = array_flip($indexes);
$filename->each(function ($row) use ($new, $indexKeys) {
$selectedCols = array_intersect_key($row, $indexKeys);
$new->insertOne($selectedCols);
return true;
});

"Cannot use a scalar value as an array" for undefined values

I have the following piece of code:
function Biz_GetAccountsPerMarket($site = "", $cache = true){
if($site == ""){
$site = $_SESSION["sitedirect_current_site"];
}
$aAccounts = Sys_OptionsGet("sys_site/".$site, "account", $cache);
$aAccountInfo = array();
$aVatAccount = Biz_GetVatAccounts($site, $cache);
$aSalesAccount = Biz_GetSalesAccounts($site, $cache);
foreach((array)$aAccounts as $code => $data){
foreach((array)$data["data"] as $market => $aItem){
$aAccountInfo[$market][$code] = $aItem;
$aAccountInfo[$market][$code]["vat"] = $aVatAccount[$aItem["vat_account_code"]]["value"];
$aAccountInfo[$market][$code]["vat_account"] = $aVatAccount[$aItem["vat_account_code"]]["account"];
$aAccountInfo[$market][$code]["sales_account"] = $aSalesAccount[$aItem["sales_account_code"]]["account"];
}
}
return $aAccountInfo;
}
The four innermost lines in the nested loop generates warnings: "Cannot use a scalar value as an array".
Adding lines that initialises $aAccountInfo[$market] and $aAccountInfo[$market][$code] to empty arrays first silences the errors, but this is far from the only place in our code where nested arrays are initialised in this way; and I can't figure out why it is a problem in the first place.
The following code should reproduce the problem; as far as I can tell; but doesn't:
<?php
ini_set('display_errors', '1');
error_reporting(E_ALL | E_STRICT);
$aTest = [];
$aTest['key']['key'] = 'sausage';
If $aItem was a string or false, or any scalar; I could understand what the problem is; but then the warning should only happen for the last three lines, not all four.
There are other weird things happening there, I hope they're all connected. This is the only one I've managed to isolate enough to ask a question about.
Is it possble to set the default value created by array access somehow?
edit:
I've noticed that many strings that are generates have an extraneous "0". This breaks things, like SQL. If empty array values somehow default to "0" or something, that would explain a lot. I have no idea how that could happen though. I'm currently grepping for "register_tick_function"...
You need to check if arrays have the expected keys. Something like this:
$aAccountInfo[$market][$code]["vat"] = isset($aItem["vat_account_code"]) ? (isset($aVatAccount[$aItem["vat_account_code"]]) ? $aVatAccount[$aItem["vat_account_code"]]["value"] : []) : [];
I am afraid your code is wrong
This line
$aAccountInfo[$market][$code] = $aItem;
creates the new occurance containing a SCALAR value and you then try and add a sub array onto that scalar value, hence the error
If you do this instead
$t = array();
$t['item'] = $aItem;
$t["vat"] = $aVatAccount[$aItem["vat_account_code"]]["value"];
$t["vat_account"] = $aVatAccount[$aItem["vat_account_code"]]["account"];
$t["sales_account"] = $aSalesAccount[$aItem["sales_account_code"]]["account"];
$aAccountInfo[$market][$code] = $t;
Then you will get a sub array created with all the values in it;

Errors when using array_push -- "First argument should be an array"

I have the following code:
<?php
function foo($bar)
{
global $products;
//$products = array();
$query = 'SELECT p_name FROM 0_products WHERE p_category IN (' . $bar . ')';
$results = mysql_query($query);
while($row = mysql_fetch_array($results, MYSQL_ASSOC))
{
array_push($products, $row);
echo 'name pushed, ';
}
}
require('mysql_ipb_connect.php'); // connect to ipb mysql database
$products = array();
foo(5);
?>
When I run it I get the following output:
Warning: array_push() [function.array-push]: First argument should be an array in /home/rgcpanel/public_html/category/category.php on line 14
name pushed,
Warning: array_push() [function.array-push]: First argument should be an array in /home/rgcpanel/public_html/category/category.php on line 14
name pushed,
Warning: array_push() [function.array-push]: First argument should be an array in /home/rgcpanel/public_html/category/category.php on line 14
name pushed,
If I uncomment "$products = array();" then the output is correct:
name pushed, name pushed, name pushed,
Why is this happening? I declare the $products array outside of a function (so it's global), and then specify it as being a global inside the function. Something is not right, but I'm not sure what that is?
Thanks for your advice.
Per the comments, $products was initialized by an included file which was included inside a function. That defines its scope to the function, rather than globally. So you'll need to use global $products; before calling the include.
function func_that_defined_products() {
global $products;
include('file_that_defines_products.php');
}
// Now when called globally later, it will be at the correct scope.
function foo($bar)
{
global $products;
$query = 'SELECT p_name FROM 0_products WHERE p_category IN (' . $bar . ')';
// etc...
}
In any case, I find it a little more readable to use $GLOBALS['products'] instead of the global keyword. And as always, wherever possible it is a preferred practice to pass the variable into a function rather than accessing it globally.
// If you can, do it this way
function foo($bar, $products) {
// $products was a param, and so global is unnecessary
}
However in your case, if the CMS defines it you may lose the flexibility to do it that way...
You haven't initialized the global variable as an array. To PHP, that variable is just null, which is NOT AN ARRAY.
Make sure you initialize variables before using them. Code like yours will result in side effects (working fine if there is a database result; failing if its empty).
Another point:
Why don't you return the result instead of using the global operator? This is really bad style.
Next one:
When creating SQL statements: escape your variables!
Uncomment this part
//$products = array();
Initialise the $products as an array

PHP Fatal Error: "Can't use method return value in write context in.... "

Trying to use a class that expects something like:
$client->firstname = 'bob';
$client->lastname = 'jones';
So I want to pass this data to the script in an array... where the keys and values are set elsewhere. I want to step through the array passing the key and value to the class. Trying to use this:
while($Val = current($CreateClientData)){
$client->key($CreateClientData) = $Val;
next($CreateClientData);
}
getting this:
Fatal error: Can't use method return value in write context in
blahblahpath on line 40.
Line 40 being: $client->key($CreateClientData) = $Val;
How can I do this?
If $client is already an instance of some class, and $CreateClientData is an array, then you probably wan to do something like this:
foreach($CreateClientData as $k => $v) {
$client->{$k} = $v;
}
This assumes of course that every key in the array is a valid member of the $client instance. If not, then you will have to do some additional checking before assigning the value, or you will have to wrap the assignment in a try / catch.
EDIT
The answer as to why your code doesn't work is because PHP doesn't allow for assignment of class properties to certain functions that return values. In your case, key($CreateClientData) returns a key. So you could alter your code and just add
$key = key($CreateClientData);
$client->$key = $Val;
But, the foreach loop is a lot cleaner anyway.
Why don't you use a foreach loop?
foreach($CreateClientData as $key => $val) {
$client->$key = $val;
}

How to Pass Class Variables in a Function Parameter

The main function of the example class uses the reusableFunction twice with different data and attempts to send that data to a different instance variable ($this->result1container and $this->result2container) in each case, but the data doesn't get into the instance variables.
I could get it to work by making reusableFunction into two different functions, one with array_push($this->result1container, $resultdata) and the other with array_push($this->result2container, $resultdata), but I am trying to find a solution that doesn't require me to duplicate the code.
My solution was to try to pass the name of the result container into the function, but no go. Does somebody know a way I could get this to work?
Example Code:
Class Example {
private $result1container = array();
private $result2container = array();
function __construct() {
;
}
function main($data1, $data2) {
$this->reusableFunction($data1, $this->result1container);
$this->reusableFunction($data2, $this->result2container);
}
function reusableFunction($data, $resultcontainer) {
$resultdata = $data + 17;
// PROBLEM HERE - $resultcontainer is apparently not equal to
// $this->result1container or $this->result2container when I
// try to pass them in through the parameter.
array_push($resultcontainer, $resultdata);
}
function getResults() {
return array(
"Container 1" => $this->result1container,
"Container 2" => $this->result2container);
}
}
(If this is a duplicate of a question, I apologize and will happily learn the answer from that question if somebody would be kind enough to point me there. My research didn't turn up any answers, but this might just be because I didn't know the right question to be searching for)
It looks to me like you want to be passing by reference:
function reusableFunction($data, &$resultcontainer) {
...
If you don't pass by reference with the & then you are just making a local copy of the variable inside reuseableFunction .
You are changing the copy, not the original. Alias the original Array by referenceDocs:
function reusableFunction($data, &$resultcontainer) {
# ^
And that should do the job. Alternatively, return the changed Array and assign it to the object member it belongs to (as for re-useability and to keep things apart if the real functionality is doing merely the push only).
Additionally
array_push($resultcontainer, $resultdata);
can be written as
$resultcontainer[] = $resultdata;
But that's just really FYI.
You may pass the attributes name as a String to the method like this:
function reusableFunction($data, $resultcontainer) {
$resultdata = $data + 17;
array_push($this->{$resultcontainer}, $resultdata);
}
//..somewhere else..
$this->reusableFunction($data, 'result2Container')
Some php experts wrote some texts about "why you shouldn't use byReference in php".
Another solution would be to define the containers as an array. Then you can pass an "key" to the method that is used to store the result in the array. Like this:
private $results = array();
function reusableFunction($data, $resIdx) {
$resultdata = $data + 17;
array_push($this->$results[$resIdx], $resultdata);
}
//..somewhere else..
$this->reusableFunction($data, 'result2Container');
//..or pass a number as index..
$this->reusableFunction($data, 1);

Categories