I'm getting an odd error when attemping to pass an array to a function which updates data in a MySQL table.
My trigger
$input_data = array(
'field0' => 'abc',
'field1' => '123'
);
// var dump #1
var_dump($input_data);
// gives expected result (2 element array)
$this->user->update_user_info($input_data);
User model
function update_user_info($new_data) {
// var dump #2
var_dump($new_data);
// this gives:
// array(2) {
// ["field0"] => string(3) "abc"
// ["field1"]=> string(3) "123"
// }
// NULL
}
Where is that ending NULL coming from?? I am trying to use this with Codeigniter's active Record Update class and it fails because of that NULL.
I've attempted to copy it to a new array by looping through a foreach, but the NULL value follows to the new array, even though it doesn't appear to be in the array.
Any help would be appreciated.
Apologies for the above 'Answer', I'm new to the site and couldn't see the comment button :p
I've since solved this problem in terms of my own circumstances and possibly this may apply to you.
As I said earlier my problem was identical, the cause was not correctly returning both functions - I returned the secondary function i.e the one that my array was passed to like so.
function update_user_info($new_data) {
// var dump #2
var_dump($new_data);
return;
}
but in the first function I was not returning after calling the second function, hope that makes sense and that this helps you too, it was frustrating as hell for me!
The NULL is obviously not in the array; It is printed on a second call to update_user_info() function. You should try to find out why the update_user_info() function is called twice.
Related
I have a returned string result from an API and it looks like this.. for the life of me, I cannot retried the WorkID value!
The returned string is a json string:
{"notes":"","RecordsStatus":"{\"0\":{\"WorkID\":\"0090210\",\"Message\":\"Record Created\"}}"}
It has two parts:
“notes” and “RecordStatus”.
If message is empty, means the batch is imported without error.
In RecordStatus, there are two parts too.
First is the index number of the record, and it has second part that the key for the record created(in my case it’s the WorkID) and a message tells the record is created or updated(in my case, it’s created).
Array
(
[notes] =>
[RecordsStatus] => {"0":{"WorkID":"0090210","Message":"Record Created"}}
)
Do a Var_dump() of decoded_json results in this:
array(2) {
["notes"]=>
string(0) ""
["RecordsStatus"]=>
string(52) "{"0":{"WorkID":"0090210","Message":"Record Created"}}"
}
I tried
foreach($decoded_json as $item) {
$uses = $item['RecordsStatus'][0]['WorkID']; //etc
}
but does not work
Here is the problem I have a session
session('products')
this is actually an array that contains id
session('products')
array:4 [▼
0 => "1"
1 => "2"
2 => "4"
3 => "1"
]
Now I want to delete lets say 4 How do I do that? I tried method
session()->pull($product, 'products');
But it didn't work!
Other solution
session()->forget('products', $product);
it also didn't work
You AFAIR have to firstly retrieve whole array, edit it and then set it again. If you want to delete by product ID, which is as I assume an array value, you can use this: PHP array delete by value (not key)
$products = session()->pull('products', []); // Second argument is a default value
if(($key = array_search($idToDelete, $products)) !== false) {
unset($products[$key]);
}
session()->put('products', $products);
Misunderstood question
Session::pull takes first parameter as the item do delete and second as the default value to return. You have mistaken the order of arguments. Try:
session()->pull('products'); // You can specify second argument if you need default value
As I can see in source, Session::forget expects string or array, so you should specify only the first parameter:
session()->forget('products');
This method isn't tested:
Session::forget('products.' . $i);
note the dot notation here, its worth the try. If that isnt working, you can always do this:
$products = Session::get('products'); // Get the array
unset($product[$index]); // Unset the index you want
Session::set('products', $products); // Set the array again
You can do it in the following way in case you have a function to delete an item from a cart
public function deleteProductoCart(Producto $producto) {
$cart = \Session::get('products');
unset($cart[$producto->id]);
\Session::put('products', $cart);
return redirect()->route('tu-ruta');
}
The goal is to get some precise values of $_GET in a property of a class while:
removing any key not desired
defaulting values when keys are not defined
With this code in a file /request.php:
$req = new request();
var_dump($req);
class request {
private $Get;
function __construct() {
$this->Get = filter_input_array(INPUT_GET,array (
'menu'=>array (
'filter'=>FILTER_VALIDATE_INT,
'options'=>array (
'default'=>30,
),
),
));
}
}
from php's man page for filter_input_array() about the third parameter (true by default):
Add missing keys as NULL to the return value.
I would expect that calling domain.com/request.php would yield a defaulted [sic] array with the integer 30 as menu's value. however when no $_GET are defined (that is, when there's no character after a question mark in the url) filter_input_array returns null therefore the var_dump is this:
object(request)#1 (1) { ["Get":"request":private]=> NULL }
however when $_GET is defined (that is, having at least one character after the question mark in the url) such as calling domain.com/request.php?a will yield:
object(request)#1 (1) { ["Get":"request":private]=> array(1) { ["menu"]=> NULL } }
How can I force filter_input_array() to return an array so that default values will be built even if I call an url with no $_GET value defined like index.php?
It seems possible to rewrite a request from .htaccess so that I could mimic a $_GET value being defined if there are not, but it feels weird.
Why not to use another simple way?
var_dump(filter_var_array($_GET, array(
'key' => FILTER_DEFAULT,
), true));
In the building process of an array I'm trying to call a function, checkIfNodeExists(). PHP executes this function and gives me the expected result but he still gives me a "Notice", and I don't want any kind of errors in my code.
function checkIfNodeExists($input) {
if (isset($input)) {
return (string) $input;
} else {
return 'null';
}
}
$array['sections'][] = array (
'ident' => $section->attributes()->ident,
'title' => $section->attributes()->title,
'objective' => checkIfNodeExists($section->objectives->material->mattext)
);
Notice: Trying to get property of non-object in /var/www/OLAT_Connection/QTI-XML-Parser.php on line xx
Now, if I check if "objective" exists OUTSIDE the array, PHP doesn't give me a notice. But this results in more lines of code because I have to work with an extra variabele and more IF-structures and so on...
Is there any other possibility without adding too much lines of extra code?
The problem is that when you call checkIfNodeExists you send it a value, and by sending it the value you also execute the value. So isset() will work on the result of the expression $section->objectives->material->mattext and not the expression itself.
This would work:
$array['sections'][] = array (
'ident' => $section->attributes()->ident,
'title' => $section->attributes()->title,
'objective' => isset($section->objectives->material->mattext) ? (string)$section->objectives->material->mattext : 'null'
);
It seems that $section->objectives->material->mattext is not properly defined. I would start looking there to see if you have errors in the initialisation of the object.
It would be better if you posted more code up so we can see what exactly is going on in this script.
The solution may require more code (albeit unlikely in this case), this is by no means a bad thing. Less code is not necessarily better or more efficient! Obviously it goes without saying that fewer lines of code will (most of the time) execute faster, but this does not make it more secure or efficient
UPDATE
You may be able to simply do this instead of calling another function:
'objective' => isset($section->objectives->material->mattext) ? (string)$section->objectives->material->mattext : null
I have not tested this and cannot remember whether you can place conditional statements inline, so cannot be sure whether it will work but if it does then this will be more efficient, and it is less code!
if you add "#" when you call the function the error aren't show
function checkIfNodeExists($input) {
if (isset($input)) {
return (string) $input;
} else {
return 'null';
}
}
$array['sections'][] = array (
'ident' => $section->attributes()->ident,
'title' => $section->attributes()->title,
'objective' => #checkIfNodeExists($section->objectives->material->mattext)
);
Define $section->objectives->material->mattext
I am trying to extract ONLY the PlanDetails where PlanDetail.company_id = Company.id AND PlanDetail.id' => $id.. ( you can see the conditions in my controller below)..
Controller:
function pd_list_by_company($id = null) {
$this->recursive = 2; // I am going to use containable to trim this.
return $this->PlanDetail->find('all',
array('conditions' =>
array('AND' =>
array('PlanDetail.company_id' => 'Company.id',
array('PlanDetail.id' => $id)))));
}
Test View:
$planDetailsByCompany = $this->requestAction('/planDetails/pd_list_by_company');
debug($planDetailsByCompany );
Output result of my debug??
Array()
If I remove the conditions and just have the find all, I get all PlanDetails as expected, so I know the data is being passed.. SQL debug dump even shows the query:
WHERE ((`PlanDetail`.`company_id` = 'Company.id') AND (`PlanDetail`.`id` IS NULL))
And yes, I did notice the $id is NULL, and I know the value needs to be there.. So maybe my question is why is the $id value not being passed to the controller even though I can see the PlanDetail.id value on a find('all') w/ out the conditions??
Thanks for any tips.
Since $id seems to be null, I would assume that you call the function without the parameter. And you don't get an error message, because as far as PHP is concerned the parameter is optional. In this case it's clearly required, so you should make it a required parameter in your function declaration:
function pd_list_by_company($id) {
Also you could simplify the return statement, you do not need the AND:
return $this->PlanDetail->find('all',
array('conditions' =>
array('PlanDetail.company_id' => 'Company.id','PlanDetail.id' => $id)
)
);
To answer the question why is the $id not being passed is because you're not passing it
To pass say $id of 2 you need to do the following in your requestAction
$this->requestAction('/planDetails/pd_list_by_company/2');
Seems to me that your code should just be
return $this->PlanDetail->find('array('PlanDetail.id' => $id));
Assuming you have the $this->PlanDetail->recursive flag set to > 0, your Model should already know about and return the associated data for any 'Company' table.....
I'm used to an old (1.3) version of CakePHP but the find() function is pretty basic and is designed to only return one row.
and yes, you definitely need to call the function with the id appended to the url, eg.
$planDetailsByCompany = $this->requestAction('/planDetails/pd_list_by_company/999');