I am trying to access values in a nested array that I send to my API but when do something like $data['inputs']{0} it only gives me back the first letter of the key when what I want is the whole value of the value and not the key but if I try something like $data['inputs']['type'] it gives me an offset error I ament sure how to correctly access the values the way I need to
public function saveEdit(Request $request)
{
try {
$unsanitizedData = $request->all();
$data = [];
$fid = $unsanitizedData['formId'];
$data['form_name'] = json_encode($unsanitizedData['cred']['name']);
$data['org'] = json_encode($unsanitizedData['cred']['organization']);
$data['updated_by'] = json_encode($unsanitizedData['updatedBy']);
$data['user_id'] = json_encode($unsanitizedData['id']);
$data['activated'] = json_encode($unsanitizedData['cred']['activated']);
$data['inputs'] = json_encode($unsanitizedData['cred']['inputs']);
$pattren = array("[","]","'",'"',"/","\\");
$data = str_replace($pattren,'', $data);
foreach ($unsanitizedData as $st) {
admin_form::where('id', $fid)->update([
'form_name' => $data['form_name'],
'org' => $data['org'],
'updated_by' => $data['updated_by'],
'user_id' => $data['user_id'],
'activated' => $data['activated']
]);
foreach ($data['inputs'] as $input) {
admin_form_fields::where('form_id', $fid)->update([
'type' => $input,
'name' => $input
]);
}
}
$res['status'] = true;
$res['message'] = 'Success';
return response($res, 200);
} catch (\Illuminate\Database\QueryException $ex) {
$res['status'] = false;
$res['message'] = $ex->getMessage();
return response($res, 500);
}
}
I thought if I use a foreach loop inside another foreach loop it would work because its a nested array so loop through the main one and then through the nested one but that did also not work
Data Structure when I do a data dump:
array:6 [
"form_name" => "Testname",
"org" => "TestOrg",
"updated_by" => "test",
"user_id" => "29",
"activated" => "false",
"inputs" => "{type:number,name:Phone},{type:input,name:Name},{type:input,name:Address},{type:email,name:Email}"
]
In your case, $data['inputs'] is a JSON encoded string from which you have removed the [ and ] characters so when you try to access its first element it's the first char (since strings are kind of arrays of strings in PHP, they are really array of strings in C).
The problem is that you call json_encode() in the first place. If it's how you sanitize input, you're doing it wrong. Since you're using an ORM, there's no real need to manually sanitize the input. Just keep your input as sent by the client and perform all your operations then use them unsanitized in the QueryBuilder
As far as I can see, you just need to use json_decode($data['inputs']) since your array is in fact just a string :)
Related
Not sure if my question is clear, but here's what I'm trying to achieve. Let’s say I have a multidimensional array like so:
$arr['client1']**['dog']['Jack']**
$arr['client2']['cat']['Stacy']
How can I get the second portion of the array (between **), knowing it can be anything. For client 3, it could be a crocodile. For Client 4, it could be a car.
So I'm looking to "build" the structure of the array, dynamically. Something like so:
$arr['client1']{partBetweenThe**InTheExemple}
{partBetweenThe**InTheExemple} would be constructed "on the fly" (hence, the dynamically).
EDIT: Hopefully some clarifications...
The array changes every time. Basically, I'm building an addon to poll any API on the web. The data structure I'm getting can be anything. So what I need to do is build the key combination "on the fly", with variables.
In the exemple above, my variable would be something like $query = ['dog']['Jack'] and to get the value, I would poll it like so (from a logistic perspective, I know this doesn't work):
$arr['client1'][$query] or $arr['client1']$query or $arr['client1']{$query}
You can define the query as an array with each level as an element. Then we can iterate through that and check if we find a matching key in the response:
function findInArray(array $query, array $data)
{
foreach ($query as $key) {
if (!array_key_exists($key, $data)) {
// The key was not found, abort and return null
return null;
}
// Since the key was found, move to next level
$data =& $data[$key];
}
return $data;
}
// Example response
$response = [
'client1' => [
'dog' => [
'Jack' => 'Some value',
],
]
];
// Define the query as an array
$query = ['dog', 'Jack'];
$result = findInArray($query, $response['client1']);
Demo: https://3v4l.org/WjXTn
Edit:
So since the array's structure can't be changed this will return the client if the structure remains ['client']['animal']['name'].
$clients = [
'client1' => [
'dog' => [
'Jack' => []
]
],
'client2' => [
'cat' => [
'Stacy' => []
]
]
];
$animal = 'dog';
$name = 'Jack';
foreach ($clients as $client => $options) {
if (
array_key_exists($animal, $options) &&
array_key_exists($name, $options[$animal])
) {
echo $client;
break;
}
}
I am working on an API which receives a PHP object of $POST data. I am trying to check wether the 'smsPhoneNumber' inside customFields exists but not sure how to do this.
I am currently able to check for 'email' using:
if ( property_exists( $data, 'email' ) ) {
return true;
}
Question: How to check if 'smsPhoneNumber' exists?
--
var_dump:
object(stdClass)[1515]
public 'email' => string 'email#email.com'
public 'customFields' =>
array (size=2)
0 =>
object(stdClass)[1512]
public 'name' => string 'Firstname'
public 'value' => string 'james'
1 =>
object(stdClass)[1514]
public 'name' => string 'smsPhoneNumber'
public 'value' => string '077'
You could use an array_filter to get the custom field you want.
$phoneFields = array_filter($data->customFields, function($field) {
return $field->name === 'smsPhoneNumber';
});
This will only return objects in the array that have a name property equal to smsPhoneNumber.
if (!count($phoneFields)) {
// Phone not found
}
// or
if ($phone = current($phoneFields)) {
echo "The first phone number found is " . $phone->value;
}
The drawback of using array_filter() to search for the subarray values is:
array_filter() will not stop once it finds a match; it will keep iterating even after a match is found until it reaches the end of the array.
You should use a technique that allows an early break/return.
I recommend a simple foreach() with a break.
$foundIndex = null;
foreach ($data->customFields as $index => $customFields) {
if ($customFields->name === 'smsPhoneNumber') {
$foundIndex = $index;
// or $wasFound = true;
// or $smsNumber = $customFields->value;
break;
}
}
This will prove to be very efficient and easy to read/maintain.
I´m trying to check the data of my JSON file. It works for strings in the json file, but how to handle it with arrays in the array?
What i send:
{
"info" : "test",
"data" : [
{
"startdate": "2018-01-01T10:00:00+0100",
"enddate": "2018-01-01T17:00:00+0100"
}
]
}
What i´ve yet:
$dataReq = array(
'info' => $request->get('info'),
'date' => $request->get('date'), // my array
);
foreach ($dataReq as $a => $value) {
if(empty($value)) {
return new View('The field \''.$a.'\' is required!');
}
}
But the function empty doenst work for arrays so far. It will return false, cause the array is there. How can i check the "startdate" key?
btw: i´m using symfony3(FOSRestBundle), php 7.0
You can check if the value is an array and filter null values from it, then test if it's empty.
$dataReq = array(
'info' => $request->get('info'),
'data' => $request->get('data'), // my array
);
foreach ($dataReq as $a => $value) {
if(is_array($value)) $value = array_filter($value);
if(empty($value)) {
return new View('The field \''.$a.'\' is required!');
}
}
array_filter() function's default behavior is to remove from array all values equal to null, 0, '' or false if no callback is passed.
Note: I assume you wanted to retrieve data and not date.
As commented by LBA, I also suggest to check the Symfony Validation component to deal with that instead.
I want to get this as a single object because I work with a JObject on the frontend.
I got an array at the moment but I am unsure how i should modify it so it returns a single object instead.
This is the code:
$contacts = array();
while ($row = mysqli_fetch_array($stmt))
{
$contact = array("ID" => $row['ProduktID'],
"Name" => $row['ProduktNamn'],
"Number" => $row['ProduktPris']);
array_push($contacts, $contact);
}
echo json_encode($contacts, JSON_PRETTY_PRINT);
And the goal is for it to look something like this with "results" as well so I can reach the whole thing:
To wrap your array of contacts in an object with a single results property:
echo json_encode(array('results' => $contacts), JSON_PRETTY_PRINT);
You can use typecasting to convert an array to an object:
$object = (object) $array_name;
or manually convert it into an object
$object = object;
foreach($arr as $key => $value)
{
$object->$key = $value;
}
Like this? Keep in mind an object is different then an array and your question is rather confusing.
while ($row = mysqli_fetch_array($stmt)){
$contact[] = [
"ID" => $row['ProduktID'],
"Name" => $row['ProduktNamn'],
"Number" => $row['ProduktPris']
];
}
json_encode(['result' => $contact]); // Forget the JSON_PRETTY_PRINT.
Using this method [], it will use the first available numeric index starting with 0. This way you don't have to push an array.
I have a query that populates an array from the database. In some cases, this query returns a great amount of data, (let's say for purpose of an example, 100.000 records). Each row of the database has at least 6 or 7 columns.
$results = [
['id' => 1, 'name' => 'name', 'status' => true, 'date' => '10-01-2012'],
['id' => 2, 'name' => 'name 2', 'status' => false 'date' => '10-01-2013'],
...
]
I need to perform a substitution of some of the data inside the $results array, based on another one that give me some information about how i would change the values in the rows.
$model = [
'status' => ['function' => 'formatStatus', params => ['status']],
'date' => ['function' => 'formatDate', params => ['date']]
]
Now that i have all the data and what do i do with it i have the following routine.
foreach ($results as &$itemResult) {
$oldValues = $itemResult;
foreach ($itemResult as $attribute => &$value) {
if (isset($model[$attribute]['function'])) {
$function = $model[$attribute]['function'];
$params = $model[$attribute]['params'];
$paramsSize = count($params);
for ($i = 0; $i < $paramsSize; $i++) {
$newParams[] = $oldValues[$params[$i]];
}
$itemResult[$attribute] = call_user_func_array([$this, $function], $newParams);
$newParams = null;
}
}
}
So, for each attribute for each row of my data array, i run check for the existence of a function and params information. When the attribute in question needs to be replaced, i call the function via call_user_func_array and replace the value with the function return value.
Also notice that i am replacing the current array, not creating another, by passing the reference &$itemResult inside the loop, so in the end, i have the same array from the beginning but with all columns that needed to be replaced with its new values.
The thing is, for little arrays, this method is quite good. But for big ones, it becomes a pain.
Could you guys provide me some alternative to the problem?
Should i use another data structure instead of the PHP array?