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.
Related
I have seen some methods to determine if some value exists in php multidimensional array but I am stuck at simple problem.
I have a following array.
$data = [
['name' => 'sagar', 'address' => 'kathmandu'],
['name' => 'sagar', 'address' => null ]
];
I want to check if null value exists anywhere inside 2 dimensional array and keys can be anything. Is there any builtin function or we have made our own or some methodology to check ?
If you have any idea, it would be extremely helpful.
$hasNull = false;
foreach ($data as $set) {
if ($hasNull = in_array(null, $set, true)) {
break;
}
}
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 :)
Is there a function out there to make sure that any given array conforms to a particular structure? What I mean is that is has particular key names, perhaps particular types for values, and whatever nested structure.
Right now I have a place where I want to make sure that the array getting past has certain keys, a couple holding a certain data type, and one sub-array with particular key names. I've done a lot of run-around because I was passing malformed arrays to it, and finally I'm at the point where I have a bunch of
if ( ! isset($arr['key1']) ) { .... }
if ( ! isset($arr['key2']) ) { .... }
if ( ! isset($arr['key3']) ) { .... }
I would have saved a lot of time and consternation if I could have checked that the array conformed to a particular structure beforehand. Ideally something like
$arrModel = array(
'key1' => NULL ,
'key2' => int ,
'key3' => array(
'key1' => NULL ,
'key2' => NULL ,
),
);
if ( ! validate_array( $arrModel, $arrCandidate ) ) { ... }
So, the question I'm asking is, does this already exists, or do I write this myself?
Convert array to JSON:
http://us.php.net/manual/en/function.json-encode.php
Then check against a JSON Schema:
http://json-schema.org/
http://jsonschemaphpv.sourceforge.net/
It doesn't exist built in.
Maybe try something like (untested):
array_diff(array_merge_recursive($arrCandidate, $arrModel), $arrModel)
You can use the Symfony Validation component
Installation:
composer require symfony/validator doctrine/annotations
Usage:
$myArray = [
'name' => ['first_name' => 'foo', 'last_name' => 'bar'],
'email' => 'foo#email.com'
];
$constraints = new Assert\Collection([
'name' => new Assert\Collection([
'first_name' => new Assert\Length(['min' => 101]),
'last_name' => new Assert\Length(['min' => 1]),
]),
'email' => new Assert\Email(),
]);
$validator = Validation::createValidator();
$violations = $validator->validate($myArray, $constraints);
For more details, see How to Validate Raw Values (Scalar Values and Arrays)
accepted answer make diff based on values, since it's about array structure you dont want to diff values. Insted you should use [array_diff_key()][1]
Function alone is not recursive. It will not work out of box on sample array from question.
Edit after years: Got into similar trouble whit recursive array functions, so there is mine array_diff_recursive, this does not solve original question because it compare values as well, but i believe it can be easily modified and someone can find it useful .
function array_diff_recursive(array $array1, array $array2){
return array_replace_recursive(
array_diff_recursive_one_way($array1, $array2),
array_diff_recursive_one_way($array2, $array1)
);
}//end array_diff_recursive()
function array_diff_recursive_one_way(array $array1, array $array2)
{
$ret = array();
foreach ($array1 as $key => $value) {
if (array_key_exists($key, $array2) === TRUE) {
if (is_array($value) === TRUE) {
$recurse = array_diff_recursive_one_way($value, $array2[$key]);
if (count($recurse) > 0) {
$ret[$key] = $recurse;
}
} elseif (in_array($value, $array2) === FALSE) {
$ret[$key] = $value;
}
} elseif (in_array($value, $array2) === FALSE) {
$ret[$key] = $value;
}
}
return $ret;
}//end array_diff_recursive_one_way()```
[1]: http://php.net/manual/en/function.array-diff-key.php
I know this is sort of an old post, sorry if my answer is not approppriate.
I'm in the process of writing a php package that does exactly what you are asking for, it's called Structure.
What you can do with the package is something like:
$arrayCheck = new \Structure\ArrayS();
$arrayCheck->setFormat(array("profile"=>"array"));
if ($arrayCheck->check($myArray)) {
//...
}
You can check it out here: http://github.com/3nr1c/structure
I came across a tool called Matchmaker on GitHub, which looks very comprehensive and has composer support and unit tests:
https://github.com/ptrofimov/matchmaker
You can include it into your project with
composer require ptrofimov/matchmaker.
I need help with symfony validator. It is possible validate only specific values in array? For example I have array:
'0' => [
'interestidKey' => true,
'anotherInterestedKey' => 'foo'
],
'error' => [
'errorMsg => 'not interest for me'
]
I need to validate this array with validator mainly value 0. I need know if array contains '0' key and inside if is key interestidKey with boolean value. I always use Collection for array but it not work in this case because ofc shows me an error that error does not contain interestidKey.
How can I fix this?
I'm not sure you will be able to do what you want with the shipped out of the box constraints. But you should be able to do what you want by writing your own: https://symfony.com/doc/current/validation/custom_constraint.html have a look at that and see if it can help you.
if you're validate you could do:
if(array_key_exists(0, $array)) {
if(array_key_exists("interestid", $array[0])) {
return true;
}
} else {
// do the error stuffs
}
You could just build a loop over your array, check for the key and if it is a numeric key (or not the error key) apply your validation to the children. That would look like this:
use Symfony\Component\Validator\Constraints as Assert;
...
$constraint = new Assert\Collection([
'fields' => [
// put any constraints for your objects here, keyed by field name
'interestidKey' => new Assert\Type('bool')
],
'allowExtraFields' => true // remove if you don't want to allow other fields than specified above
]);
$violations = [];
foreach($data as $key => $item) {
if ($key != 'error') {
$violations[$key] = $validator->validate($item, $constraint);
}
}
Is there a function out there to make sure that any given array conforms to a particular structure? What I mean is that is has particular key names, perhaps particular types for values, and whatever nested structure.
Right now I have a place where I want to make sure that the array getting past has certain keys, a couple holding a certain data type, and one sub-array with particular key names. I've done a lot of run-around because I was passing malformed arrays to it, and finally I'm at the point where I have a bunch of
if ( ! isset($arr['key1']) ) { .... }
if ( ! isset($arr['key2']) ) { .... }
if ( ! isset($arr['key3']) ) { .... }
I would have saved a lot of time and consternation if I could have checked that the array conformed to a particular structure beforehand. Ideally something like
$arrModel = array(
'key1' => NULL ,
'key2' => int ,
'key3' => array(
'key1' => NULL ,
'key2' => NULL ,
),
);
if ( ! validate_array( $arrModel, $arrCandidate ) ) { ... }
So, the question I'm asking is, does this already exists, or do I write this myself?
Convert array to JSON:
http://us.php.net/manual/en/function.json-encode.php
Then check against a JSON Schema:
http://json-schema.org/
http://jsonschemaphpv.sourceforge.net/
It doesn't exist built in.
Maybe try something like (untested):
array_diff(array_merge_recursive($arrCandidate, $arrModel), $arrModel)
You can use the Symfony Validation component
Installation:
composer require symfony/validator doctrine/annotations
Usage:
$myArray = [
'name' => ['first_name' => 'foo', 'last_name' => 'bar'],
'email' => 'foo#email.com'
];
$constraints = new Assert\Collection([
'name' => new Assert\Collection([
'first_name' => new Assert\Length(['min' => 101]),
'last_name' => new Assert\Length(['min' => 1]),
]),
'email' => new Assert\Email(),
]);
$validator = Validation::createValidator();
$violations = $validator->validate($myArray, $constraints);
For more details, see How to Validate Raw Values (Scalar Values and Arrays)
accepted answer make diff based on values, since it's about array structure you dont want to diff values. Insted you should use [array_diff_key()][1]
Function alone is not recursive. It will not work out of box on sample array from question.
Edit after years: Got into similar trouble whit recursive array functions, so there is mine array_diff_recursive, this does not solve original question because it compare values as well, but i believe it can be easily modified and someone can find it useful .
function array_diff_recursive(array $array1, array $array2){
return array_replace_recursive(
array_diff_recursive_one_way($array1, $array2),
array_diff_recursive_one_way($array2, $array1)
);
}//end array_diff_recursive()
function array_diff_recursive_one_way(array $array1, array $array2)
{
$ret = array();
foreach ($array1 as $key => $value) {
if (array_key_exists($key, $array2) === TRUE) {
if (is_array($value) === TRUE) {
$recurse = array_diff_recursive_one_way($value, $array2[$key]);
if (count($recurse) > 0) {
$ret[$key] = $recurse;
}
} elseif (in_array($value, $array2) === FALSE) {
$ret[$key] = $value;
}
} elseif (in_array($value, $array2) === FALSE) {
$ret[$key] = $value;
}
}
return $ret;
}//end array_diff_recursive_one_way()```
[1]: http://php.net/manual/en/function.array-diff-key.php
I know this is sort of an old post, sorry if my answer is not approppriate.
I'm in the process of writing a php package that does exactly what you are asking for, it's called Structure.
What you can do with the package is something like:
$arrayCheck = new \Structure\ArrayS();
$arrayCheck->setFormat(array("profile"=>"array"));
if ($arrayCheck->check($myArray)) {
//...
}
You can check it out here: http://github.com/3nr1c/structure
I came across a tool called Matchmaker on GitHub, which looks very comprehensive and has composer support and unit tests:
https://github.com/ptrofimov/matchmaker
You can include it into your project with
composer require ptrofimov/matchmaker.