[
{
"id" : 1,
"name" : "levin",
"description" : "some desc",
"size" : "100KG",
"actions" : {
"walking" : true,
"eating" : true
}
},
{
"id" : 2,
"name" : "clara",
"description" : "some desc",
"size" : "2000KG",
"actions" : {
"walking" : false,
"eating" : true
}
}
]
This is my person.json file. I like to update(overwrite) existing values. Am not found any useful questions regarding this.
i have a name "levin" i like to overwrite it to empty or "---". But its should only based through "id" .Following is my php code but its not working :(
public function api_put()
{
//print($this->put('id')); am getting here 2 value from other page
//print($this->put('action'));.
if($this->put('action') == "remove"){
$file = json_decode(file_get_contents("assets/json/person.json"));
$new_val = array();
$i = 0 ;
foreach ($file as $key => $value) {
if((string)$value->id == $this->put('id')) {
$data[] = (string)$value->name="--";(string)$value->description="--";
$new_val[$i] = $data;
$i++;
}
}
file_put_contents('assets/json/person.json', json_encode($new_val));
$message = array('id' => $this->put('id'), 'message' => 'Successfully updated!!');
$this->response($message, 200);
}
}
How can i overwrite a json value depend upon a particular id and with out change all other id data. am using codeigniter REST api. thanks in advance
A couple of things.
You don't need a $new_val array, you can just edit these resources in place.
PHP is weakly typed, so doing (string)$value->id == $this->put('id') is not necessary. The PHP engine will do this conversion for you.
Casting on the left side of the equal sign does nothing. (string)$value->description="--"; That statement has no effect.
This is poor form, in any programming language ... (string)$value->name="--";(string)$value->description="--"; Two statements doing two operations should be on two different lines.
General concept, your code should be easy to read. Space it out a little bit, let it breath. When you come back to your code years later you'll be glad that you did.
public function api_put()
{
if ($this->put('action') == 'remove')
{
$file = json_decode(file_get_contents('assets/json/person.json'));
foreach ($file as $key => $value)
{
if ($value->id == $this->put('id'))
{
$value->name = '--';
$value->description = '--';
}
}
file_put_contents('assets/json/person.json', json_encode($file));
$message = array('id' => $this->put('id'), 'message' => 'Successfully updated!!');
$this->response($message, 200);
}
}
There, isn't that much nicer?
I think you must need to loop like this to store all details
foreach ($file as $key => $value) {
if((string)$value->id == $this->put('id')) {
$value->name="--";(string)$value->description="--";
}
$new_val[$i] = $value;
$i++;
}
Related
I have a problem when I try to insert using one loop arrays into a specific place in the JSON. The app is designed to create a dictionary with main terms and their subterms (synonyms) . I succeeded to create the main terms but I can't add subterms. one entry contains main term and their translations and then subterms are encapsulated in "Subterms" sections with translations.
The final JSON file format I need is :
{
"glossary":{
"0":{
"id":4,
"English":{
"term":"accountability ",
"definition":"An obligation or willingness to use power"
}
},
"Subterms":[
{
"id":1,
"English":{
"term":"behavior change communication",
"definition":"The strategic use of communication approaches"
}
}
]
}
I want to insert multiple Arrays with a loop (in the example above is just English) into "Subterms" but no matter what I try is not letting me access that position.
PHP code:
<?PHP
$posts = array();
$subterms = array();
................
for($i = 0; $i < $val['maxentry']; $i++)
{
if ($i==1)
{
$dataheadenglish = $db->getRecFrmQry($queryheadenglish);
$headenglish = array (
'term'=> $dataheadenglish[0]['term'],
'definition'=> $dataheadenglish[0]['definition'],
)
$posts[] = array(
'id' => intval($dataheadenglish[0]['row']),
'English'=> $headenglish,
);
}
else
{
$dataenglish= $db->getRecFrmQry($queryenglish);
if(!empty($dataenglish))
{
$english= array (
'term'=> $dataenglish[0]['term'],
'definition'=> $dataenglish[0]['definition'],
);
}else $english=array();
// same for all languages to be inserted
$subterms[] = array(
'English'=> $english,
'Arabic'=> $arabic,
'Turkmen'=> $turk,
);
}
}
?>
I tried with :
$posts['Subterms'] = $subterms;
$posts['Subterms'][] = $subterms;
array_push($posts["Subterms"],$subterms);
but the subterms appears before posts(aka headterm)
{
"glossary": {
"Subterms": [
{
"English": [],
"Arabic": {
"term": "\u0627\u0644\u0645\u0633\u0627\u0621\u0644\u0629",
"definition": "",
"source": "",
}
},
"Kurdish_Badhini": [],
"Kurdish_Kurmanji": [],
"Kurdish_Sorani": [],
"Turkmen": []
}
],
"0": {
"English": {
"term": "accountability ",
"definition": "An obligation or willingness to use power responsibly and be held accountable for one's actions, both as individuals and as organizations.",
},
It should appear part of "0"
Thank you
In the beginning you showed a pattern of JSON you need, but at the end you said 'It should appear part of "0"'. Based on you example of JSON, I'll assume you wanted to say "past of".
If it got it right, the Subterms are being put before the "0" because it's exactly what you are telling it to do.
You are testing if $i is equal to 1, and because your for is starting with $i=0, your else will be happening before your if, so your subterms are being put in the array first.
if ($i==1) // because of this
{
// your code
}
else
{
// your code
}
My suggestion is to change this test from $i==1 to $i==0, so your if will happen first.
I have a JSON file which structure looks like this (very simplified):
[
{
"customerId": "M12345",
"houses": [
{
"id": "OBJ12345_1731321200",
"status": {
"id": "4",
"name": "Sold"
}
],
"plots": [
{
"id": "OBJ12345_1771637082",
"status": {
"id": "4",
"name": "Sold"
}
],
"projects": [],
"farms": [],
"commercialPropertys": [],
"condominiums": [],
"foreignProperties": [],
"premises": []
}
]
I have figured out how to count how many "houses" or "plots" there is:
$content = file_get_contents('estateList/estateList.json');
$GetEstateList = json_decode($content);
count($GetEstateList[0]["houses"]);
count($GetEstateList[0]["plots"]);
BUT Trying to figure out using php how to count how many objects which have a condition status(id:4)
I think you will need to use a loop in order to count the objects, i would use a foreach loop, bellow is an example :
$count = 0;
foreach ( $GetEstateList[0] as $key => $value){
if (isset($value['status']) && $value['status']['id'] === "4") {
$count++;
}
}
First, you need to enter the GetEstateList array, then you need to do a cycle for each type (for now types showed are plots and houses), then you need another cycle, because each type is an array of elements and can have more than one estate.
So, try this code:
// Counter variable for condition expressed after (status == 4)
$counter = 0;
// Enter the array and get `customerId`, `houses` and `plots`,
// but we only need the types of estate, so only `houses` and `plots`, in this case
foreach ( $GetEstateList as $estate_array => $array_attr ) {
// We only need `houses` and `plots` (increasing algorithm performance)
if ( $array_attr == "houses" || $array_attr == "plots" ) {
// We're checking all types of estates (all `houses` and all `plots`)
foreach ( $array_attr as $type => $parameter ) {
// So, we can get `status` of every estate
if ( $parameter == "status") {
// And finally we can get `id` for each estate `status`
if ( $parameter["id"] == "4" ) {
$counter++;
}
}
}
}
}
Notice: the code above cannot work if the written JSON structure is too different from the original.
I figured it out myself...
Maybe not the "correct" way but it works! :)
Feel free to comment on any improvement or modifications...
$StatusCount = 0;
foreach ($GetEstateList[0] as $GetEstateType) {
foreach ($GetEstateType as $GetEstate) {
if ($GetEstate["status"]["id"] == "4") {
$StatusCount++;
}
}
}
Is there any simpler format for the following if statement below?
if((!empty($_SESSION['email'])) && (!empty($_SESSION['serial'])) && (!empty($_SESSION['name'])) && (!empty($_SESSION['number'])) && (!empty($_SESSION['institution'])) && (!empty($_SESSION['address'])) && (!empty($_SESSION['item2']))){
echo "OK u can proceed";
} else {
echo "U didn't complete the requested info";
}
Sorry if this is too simple for you, but really appreciate any pro suggestion.
Because conditional statement will "short circuit" on the first failure, re-writing your process using an iterator will be less performant.
If you only want to provide generalized feedback to the user, use your current method without the surplus parentheticals.
if(!empty($_SESSION['email']) &&
!empty($_SESSION['serial']) &&
!empty($_SESSION['name']) &&
!empty($_SESSION['number']) &&
!empty($_SESSION['institution']) &&
!empty($_SESSION['address']) &&
!empty($_SESSION['item2'])){
// valid
}
Alternatively (same same):
if(empty($_SESSION['email']) ||
empty($_SESSION['serial']) ||
empty($_SESSION['name']) ||
empty($_SESSION['number']) |
empty($_SESSION['institution']) ||
empty($_SESSION['address']) ||
empty($_SESSION['item2'])){
// invalid
}
Only if you wish to specify the cause of the invalidation should you bother to set up an iterative process. Furthermore, if you are going to perform iterations to validate, you can take the opportunity to remove any unwanted elements from the $_SESSION array that evil-doers may have injected to take advantage of any future loops on the superglobal.
$valid_keys=['email','serial','name','number','institution','address','item2'];
$validated=true; // default value
foreach($valid_keys as $key){
if(!empty($_SESSION[$key])){
$session_data[$key]=$_SESSION[$key];
}else{
echo "Oops, there was missing data on $key";
$validated=false;
break;
}
}
if($validated){...
// from this point, you can confidently run loops on `$session_data` or slap it directly into a pdo call knowing that it has been validated and ordered.
All that said, if there is even the slightest chance that your $_SESSION elements could hold zero-ish/false-y/empty values, then isset() is the better call (only NULL will get caught). Another good thing about isset() is that it allows multiple variables to be written into the single call and maintains the same/intended performance.
if(isset($_SESSION['email'],$_SESSION['serial'],$_SESSION['name'],$_SESSION['number'],$_SESSION['institution'],$_SESSION['address'],$_SESSION['item2'])){
// valid
}
or
if(!isset($_SESSION['email'],$_SESSION['serial'],$_SESSION['name'],$_SESSION['number'],$_SESSION['institution'],$_SESSION['address'],$_SESSION['item2'])){
// invalid
}
You could build a function where you pass all the keys you want to check.
I've changed $_SESSION to $SESSION to cheat the array with some values ...
<?php
$SESSION = [
'email' => 'xx',
'serial' => 'xx',
'name' => 'xx',
'number' => 'xx',
'institution' => 'xx',
'address' => 'xx',
'item2' => 'xx'
];
$keys = [
'email',
'serial',
'name',
'number',
'institution',
'address',
'item2'
];
if(isNotEmpty($SESSION, $keys)) {
echo "OK u can proceed";
} else {
echo "U didn't complete the requested info";
}
function isNotEmpty($array, $keys) {
foreach($keys as $key) {
if(empty($array[$key])) {
return false;
}
}
return true;
}
PHP Fiddle
Just "mind games"
$arr = array_flip('email', 'serial', 'name','number'...);
if (count(array_filter(array_intersect_key($_SESSION, $arr))) == count($arr)) {
This is just my opinion, but I think your expression is fine. Maybe you could format it in another way to make it more readable:
if ( !empty($_SESSION['email']) &&
!empty($_SESSION['serial']) &&
!empty($_SESSION['name']) &&
!empty($_SESSION['number']) &&
!empty($_SESSION['institution']) &&
!empty($_SESSION['address']) &&
!empty($_SESSION['item2']) ) {
/* Proceed */
} else {
/* Don't proceed */
}
Or maybe use a custom validation function:
/* My original version */
function filled_required_fields($fields, $array) {
$valid = true;
foreach ($fields as $field) {
$valid = $valid && !empty($array[$field]);
if (!$valid) return false;
}
return $valid;
}
/* Cleaner solution based on #caramba's answer */
function filled_required_fields($fields, $array) {
foreach ($fields as $field) {
if (empty($array[$field])) return false;
}
return true;
}
if (filled_required_fields(['email', 'serial', 'name', 'number', 'institution', 'address', 'item2'], $_SESSION) {
/* Proceed */
} else {
/* Don't proceed */
}
I'd like some help please, if its possible.
I have created two functions in order to display some messages when is set a $_GET after a redirect.Here's the code:
function display(){
if(isset($_GET['cnf_upd']) && $_GET['cnf_upd'] == '1'){
$value = "The update was successful!";
$type = "confirm";
construct_the_div($value, $type);
}
if(isset($_GET['err_upd']) && $_GET['err_upd'] == '1'){
$value = "The Update failed.";
$type = "error";
construct_the_div($value, $type);
}
if(isset($_GET['cnf_del']) && $_GET['cnf_del'] == '1'){
$value = "Deleted completely.";
$type = "confirm";
construct_the_div($value, $type);
}
if(isset($_GET['err_del']) && $_GET['err_del'] == '1'){
$value = "Unable to delete.";
$type = "error";
construct_the_div($value, $type);
}
}
function construct_the_div($value, $type){
// creating a div to display the message results
$div = "<div class=\"{$type}Msg\">\n";
$div .= "<p>{$value}</p>\n";
$div .= "</div><!-- end of {$type}Msg -->\n";
echo $div;
}
What I'd like to make is to try to improve the display function, as it gets longer and longer, so that there whould be only one (or two at most) if statement(s) if possible. So the value of the GET will be dynamicly inside the if condition and also if it has the preffix 'cnf_' it wil be a 'confirmMsg' and if it has the preffix 'err_' it wil be a 'errorMsg'.
Is it possible to make something like this???
function display() {
$messages = array(
'cnf_upd' => 'The update was successful!',
'cnf_err' => 'The Update failed.!',
// ...
// add all error and confirm there
// ...
);
foreach($_GET as $key => $value) {
if(strpos($key, 'cnf_')===0) {
$type = 'confirm';
$value = isset($messages[$key])
? $messages[$key]
: $key;
construct_the_div($value, $type);
}
if(strpos($key, 'err_')===0) {
$type = 'error';
$value = isset($messages[$key])
? $messages[$key]
: $key;
construct_the_div($value, $type);
}
}
}
The approach is not correct, it seems that only one message should occur at once (there cannot be "deleted completely" and "unable to delete" at once).
Try construct the parameters this way: ?msg=upd&msgType=cnf
function display(){
if (isset($_GET['msg']) && isset($_GET['msgType']))
{
$messages = array('cnf_upd'=>'The update was successful!',
'err_upd'=>'The update failed!',
'cnf_del'=>'The deletion was successful!',
'cnf_upd'=>'The deletion failed!',
);
if (isset($messages[$_GET['msgType'].'_'.$_GET['msg']))
construct_the_div($messages[$_GET['msgType'].'_'.$_GET['msg']], htmlspecialchars($_GET['msgType']));
}
there is still much to improve, but for start this is cleaner and safer.
I'm going to propose a different solution. Instead of setting different parameters in $_GET based on the message to be sent, set one parameter and parse its value.
// Start by setting integer constants:
define(CNF_UPD, 1);
define(ERR_UPD, 2);
define(CNF_DEL, 3);
define(ERR_DEL, 4);
Then when you set the value un $_GET, use the constant:
// Build the URL with a deletion error...
header("Location: http://example.com/script.php?msg=" . ERR_DEL);
Finally, use a switch to parse them
if (isset($_GET['msg'])) {
switch ($_GET['msg']) {
case CNF_UPD:
// Updated...
break;
case ERR_UPD:
// failed...
break;
// etc...
default:
// invalid code.
}
}
If you use a pattern of confirm/error/confirm/error for your integer constants, you can determine which it is by taking $_GET['msg'] % 2. Odd numbers are confirmations, evens are errors. There are of course many other ways you could lay this out, I just happen to have typed them in the alternating order you used. You could also do positive integers for confirmations and negatives for errors, for example.
$type = $_GET['msg'] % 2 == 1 ? $confirm : $error;
This is easily expanded to use multiple messages as well. Since they are integer values, you can safely construct a comma-separated list and explode() them when received.
$messages = implode(array(ERR_DEL,CNF_UPD));
header("Location: http://example.com/script.php?msg=$messages");
Unless you can somehow generate $value and $type based on the $_GET parameter (which I can't see how you would do), you could do something like:
$messages = array();
$messages[] = array('id' => 'cnf_upd', 'value' => 'The update was successful!', 'type' => 'Confirm');
$messages[] = array('id' => 'err_upd', 'value' => 'The Update failed.', 'type' => 'error');
...
foreach ($messages as $message) {
if(isset($_GET[$message['id']]) && $_GET[$message['id']] == '1'){
construct_the_div($message['value'], $message['type']);
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
More concise way to check to see if an array contains only numbers (integers)
PHP checking if empty fields
I have form that submits 10 fields, and 7 of them should be filled, here is how i chek it now in PHP:
if (!$name || !$phone || !$email || !$mobile || !$email || !$state || !$street || ! $city) {
echo '<div class="empty_p">You have empty fields!!!</div>';}
else{
//process order or do something
}
My question is: is there more simple way to do this? Because sometimes I have even more strings to check (12-15)
Another possibility:
$elements = array($name, $email, $mobile);
$valid = true;
foreach ($elements as $element) {
if (empty($element)) {
$valid = false;
}
}
if ($valid) {
// complete
} else {
// alert! some element is empty
}
Something like this?
foreach($_POST as $key => $value)
{
if (empty($_POST[$key]))
{
echo '<div class="empty_p">'.$_POST[$key].' is empty.</div>';
}
}
It's good to be specific about where this data should be expected, e.g. $_POST:
if (!isset($_POST['name'], $_POST['phone'], $_POST['email'], $_POST['mobile'], $_POST['state'], $_POST['street'], $_POST['city'])) {
// something is up
}
You can shorten this code a little bit by creating an array with your required field names:
$required_fields = array('name', 'phone', 'email', 'mobile', 'state', 'street', 'city');
The 'check-for-existence' code can then be simplified to:
foreach ($required_fields as $f) {
if (!isset($_POST[$f])) {
// something is up
}
}
The better way ™
However, you should seriously consider combining both existence and validation / sanitization checks. PHP provides a family of filter functions functions that you can use to validate and/or sanitize your input variables. For example, to get equivalent behavior as above:
$required_fields = filter_input_array(INPUT_POST, array(
'name' => FILTER_UNSAFE_RAW,
'email' => FILTER_VALIDATE_EMAIL,
));
if (is_null($required_fields) || in_array(null, $required_fields, true)) {
// some fields are missing
}
Fields that exist but fail validation will be set to false, so this is how you detect such an event:
foreach ($required_fields as $name => $value) {
if (false === $value) {
// field $name failed validation (e.g. bad email format)
} elseif (!strlen(trim($value))) {
// field is empty
}
}
The best way would be to create some sort of form validator. However you can use this function:
<?php
function isAnyEmpty() {
$total = 0;
$args = func_get_args();
foreach($args as $arg)
{
if(empty($arg)) {
return true;
}
}
return false;
}
$var1 = 1;
$var2 = 'test';
$var3 = '';
if(isAnyEmpty($var1, $var2, $var3)) {
echo 'empty fields!';
}
?>
You could try creating a general validation class that could be reused and be more precise.
Some pseudo code:
<?
class validateFields {
$validators = array(
"name" => array(
"empty" => array(
"rule" => "some regex",
"errorMessage" => "name may not be empty"
),
"noNumbers" => array(
"rule" => "some regex",
"errorMessage" => "No numbers are allowed in the name field"
)
),
"otherVariable" => array(
"atLeast50chars" => array(
"rule" => "some regex",
"errorMessage" => "This field must be at least 50 chars"
)
)
);
public function Validate($post){
$errors = array();
foreach($_POST as $key => $value){
if(!array_key_exists($key, $validators)) {
continue;
}
foreach($validators[$key] as $validator) {
if(!preg_match($validator["rule"], $value) {
$errors[$key] = $validator["errorMessage"];
break;
}
}
}
return $errors;
}
}
?>
Then in your code you could do something like:
$errors = Validate($_POST);
foreach($error as $errorMessage) {
echo $errorMessage . "</br>";
}
Of course you could fancy this up, adding divs with classes right below/beside the concerning input field and load the $errorMessage into there.
I'm sure there's loads of examples out there :)
You can write Foreach loop
foreach($_POST as $key => $value)
{
if (!isset($_POST[$key]) || empty($_POST[$key])
{
echo '<div class="something">You have empty fields!!!</div>';
}
}
<input type="text" name="required[first_name]" />
<input type="text" name="required[last_name]" />
...
$required = $_POST['required'];
foreach ($required as $req) {
$req = trim($req);
if (empty($req))
echo 'gotcha!';
}
/* update */
OK! guys, easy...
You can make it more secure, just with type casting as all we programmers do for out coming data, like $id = (int) $_GET['id'], like $username = (string) addslashes($_POST['username']) and so on...;
$required = (array) $_POST['required'];
And then, what ever comes from post fields let them come, this code just seek what it need.
That is it! Uhh...