PHP foreach in a function only runs once - php

I'm trying to run a foreach loop to check if one of the required fields in a form is empty, and output the missing fields through an error array. Each of the variables is assigned to a $_POST variable.
However, once I call the function:
fields_empty($requiredFields, $fieldErrors);
It only runs once, and not looping through the error. Here's the full source code:
$requiredFields = array(
"First Name"=>$fname,
"Last Name"=>$lname,
"Email"=>$email,
"Password"=>$pass1,
"Confirm Password"=>$pass2,
"Country"=>$country,
"Address 1"=>$addr1,
"City"=>$city,
"State"=>$state,
"Postal Code"=>$pcode,
"Phone Number"=>$phone
);
$fieldErrors = array();
function fields_empty($requiredFields, $fieldErrors) {
global $fieldErrors;
foreach($requiredFields as $name => $field) {
if (empty($field)) {
array_push($fieldErrors, "$name is required.<br>");
return true;
}
}
}
fields_empty($requiredFields, $fieldErrors);
print_r($fieldErrors);
Output in browser:
Array (
[0] => First Name is required.
)
Also, this only happens when it's in a function. If I execute it without a function, it shows all the missing fields.

Remove return from your function. What return does is terminate the function and return whatever is passed with the return, here its set to true. Removing return will keep the loop running.
function fields_empty($requiredFields, $fieldErrors) {
global $fieldErrors;
foreach($requiredFields as $name => $field) {
if (empty($field)) {
array_push($fieldErrors, "$name is required.<br>");
}
}
}

Related

Why does my code return multiple echo strings

Whenever I submit my form, it returns three times "Good" as "GoodGoodGood" and I'm trying to figure out why. The ony thing I know, that it has to do something with Arrays.
check.php checks if all 3 inputs are not empty, if everthing is fine it echo'es "Good".
class Check {
public function mty() {
global $required;
global $field;
foreach($required as $field) {
if (empty($_POST[$field])) {
//Code...
} else {
echo "Good";
}
}
}
}
submit.php
$check = new Check;
//Gets names of inputs
$required = array('name', 'price', 'id');
if(isset($_POST['submit'])) {
$check->mty();
}
I'm new to OOP, just want to find a fix for the problem. Is there anything I can improve in this code?
The issue is that you're echoing "good" on each iteration in your loop.
You can create a variable that hold the state and check that and echo after the loop instead:
// The variable that keeps the state
$success = true;
foreach($required as $field) {
if (empty($_POST[$field])) {
// Set the state as false
$success = false;
}
}
// If state is true, no value was empty and we echo 'Good'... once.
if ($success) {
echo 'Good';
}
As others have mentioned, using global should be avoided when ever possible (which is always if you're structure is sound).
There's also the issue of you using global $field; while using $field in your foreach loop as well. If you're planing to use $field you've imported using global $field; in that method, you should use another name in your foreach. If you're not planing on using it, remove global $field;.
I prefer using the array_filter() to get only non-empty values and compare the count of that against the original $_POST count
<?php
# pretend like this was what was posted
$posted = [
'foo' => 'bar',
'bar' => 'foo',
'treybake' => 'is awesome?'
];
# your GLOBALS
$required = ['foo', 'treybake'];
# compare the count of the array without any empty elements
# vs original post count
if (count(array_filter($posted, function($el){return (!empty($el));})) === count($posted)) {
echo 'good';
} else {
echo 'something bad';
}

If Class exists && If Method exists PHP / Laravel

PHP/Laravel
Hey, I'm moving into abstraction in php and am attempting to validate and store values based on whatever has been submitted, where I expect that the methods should neither know what to validate against and/or which class and method to use to do so -
What I've got works but I can see that there would be issues where classes/methods do not exist. Here lays my question.
If I were to call a method in the following format, which way would be best to 'check' if class_exists() or the method exists()?
public function store(Request $request)
{
$dataSet = $request->all();
$inputs = $this->findTemplate();
$errors = [];
$inputValidators = [];
foreach ($inputs as $input) {
$attributes = json_decode($input->attributes);
if (isset($attributes->validate)) {
$inputValidators[$input->name] = $input->name;
}
}
foreach ($dataSet as $dataKey => $data) {
if (array_key_exists($dataKey, $inputValidators)) {
$validate = "validate" . ucfirst($dataKey);
$validated = $this->caseValidator::{$validate}($data);
if ($validated == true) {
$inputValidators[$dataKey] = $data;
} else {
$errors[$dataKey] = $data;
}
} else {
$inputValidators[$dataKey] = $data;
}
}
if (empty($errors)) {
$this->mapCase($dataSet);
} else {
return redirect()->back()->with(['errors' => $errors]);
}
}
public function mapCase($dataSet)
{
foreach($dataSet as $dataKey => $data) {
$model = 'case' . ucfirst($dataKey);
$method = 'new' . ucfirst($dataKey);
$attribute = $this->{$model}::{$method}($dataKey);
if($attribute == false) {
return redirect()->back()->with(['issue' => 'error msg here']);
}
}
return redirect()->back->with(['success' => 'success msg here'])'
}
For some additional context, an input form will consist of a set of inputs, this can be changed at any time. Therefore I am storing all values as a json 'payload'.
When a user submits said form firstly the active template is found, which provides details on what should be validated $input->attributes, once this has been defined I am able to call functions from caseValidator model as $this->caseValidator::{$validate}($data);.
I do not think that any checks for existence will be needed here as the validation parameters are defined against an input, thus if none exist this check will be skipped using if (array_key_exists($dataKey, $inputValidators))
However, I am dispersing some data to other tables within the second block of code using mapCase(). This is literally iterating over all array keys regardless of if a method for it exists and thus the initial check cannot be made as seen in the first block. I've attempted to make use of class_exists() and method_exists but logically it does not fit and I cannot expect them to work as I'd like, perhaps my approach in mapCase is not correct? I guess if I'm defining a class for each key I should instead use one class and have methods exist there, which would remove the need to check for the class existing. Please advise
Reference:
$attribute = $this->{$model}::{$method}($dataKey);
Solved the potential issue by using class_exists(), considering I know the method names as they are the same as the $dataKey.
public function mapCase($dataSet)
{
foreach($dataSet as $dataKey => $data) {
$model = 'case' . ucfirst($dataKey);
if (class_exists("App\Models\CaseRepository\\" . $model)) {
$method = 'new' . ucfirst($dataKey);
$attribute = $this->{$model}::{$method}($dataKey);
}
if($attribute == false) {
return redirect()->back()->with(['issue' => 'error msg here']);
}
}
return redirect()->back->with(['success' => 'success msg here'])'
}

Php function is not returning the value

I'm trying to fill dynamicly a value in a form (Gravity form), so i'm using the function add filter :
add_filter( 'gform_field_value_champp', 'test' );
which fill the field "champp" with the return of the function test which is :
function test ( $fieldname)
{
return $fieldname ;
}
But i don't know why, nothing is returned. If i do a var_dump($fieldname), the variable is not empty.
Despite, if i do
function test ( $fieldname)
{
echo var_dump ($fieldname);
$fieldname = "value";
return $fieldname ;
}
The value "value" is well returned and it fill the form ... ! So i don't understand ...
Thanks
var_dump() is a 'void' function which means it does not return a value as a result of calling the function. And as such when the line:
// ...
echo var_dump($fieldname)
// ...
You are trying to echo an empty value.
So if you want to directly print the variable passed into the functions via the filter here's what your code would look like:
function test ( $fieldname ) {
echo $fieldname; // this is print the value of the variable
$fieldname = "value";
return $fieldname ;
}

PHP return true if all method calls inside a foreach method return true

I am stuck with a problem using foreach essentially my method should return true if the IF statement inside the foreach loop returns true however the problem is that the statement only executes for the first element in the array not the whole array. I tried searching but I cant find a clear answer for my problem. Here is my code snippet
public function SaveDisplayOrder($aUnitCustomField)
{
var_dump($aUnitCustomField);
foreach($aUnitCustomField as $pUnitCustomField)
{
if (CUnitCustomFieldsTable::SaveUnitCustomField($pUnitCustomField))
{
return true;
}
}
return false;
}
So this returns if the SaveUnitCustomField method returns true for the first element of $aUnitCustomField and stops the execution, how can I check SaveUnitCustomField for the whole $aUnitCustomField array.
You know what's better than "something failed"? "These specific things failed" so you can actually take action.
public function SaveDisplayOrder( $aUnitCustomField ) {
$returnValue = true;
$errors = [];
foreach( $aUnitCustomField as $pUnitCustomField ) {
if ( ! CUnitCustomFieldsTable::SaveUnitCustomField($pUnitCustomField) ) {
$returnValue = false;
$errors[] = "Error when saving $pUnitCustomField";
}
}
return [$returnValue, $errors];
}

Assign key of an array element to a variable

I have the following piece of code and inside the function field_has_input(), I would like to assign the element's key to the errors[]
i.e. errors[]=$key instead of errors[]=$field
The function field_has_input($field) gets called from check_all_fields($_POST)
Hopefully someone can help out.
function field_has_input($field)
{
global $errors;
if(!isset($field) || empty($field))
{
$errors[]=$field;
}
}
function check_all_fields($_POST)
{
global $errors;
foreach($_POST as $key => $value)
{
echo $_POST[$key] . "<br />";
field_has_input($_POST[$key]);
}
//exit;
var_dump($errors);
return $errors;
}
I would suggest you dispense with the field_has_input() function entirely, and just do the work inside the other loop. Otherwise, you would need to be passing the $key into the inner function. In its current simplicity it is totally unnecessary and adds complexity.
function check_all_fields($_POST)
{
global $errors;
foreach($_POST as $key => $value)
{
// empty() calls isset() implicitly...
if (empty($value)) {
$errors[] = $key;
}
}
//exit;
var_dump($errors);
return $errors;
}
Further, I would recommend not using the global errors, but instead passing it to the function. Because $_POST is a superglobal, it is unnecessary to pass it as a parameter to your function. Pass only $errors instead.
function check_all_fields($errors) {
// $_POST is already available here...
foreach($_POST as $key => $value)
{
if (empty($value)) {
$errors[] = $key;
}
}
return $errors;
}
If you must use an inner function, such as if the actual work to be done in field_has_input() is more complex than just checking empty(), pass the $key and check $_POST[$key] inside the function
function field_has_input($key, $errors) {
if (empty($_POST[$key])) {
$errors[] = $key;
}
}
If you want to get an array of values consisting of the $_POST keys that are empty, you can do that with just one line:
$errors = array_keys( array_diff_key( $_POST, array_filter($_POST) ) );
array_filter will remove false, null or empty string values
array_diff_key will compare the original full post array to the filtered version and return only the keys that have been filtered.
array_keys will create an array of values using the array keys of the given array
Example, if:
$arr = array (
'name' => 'Bob'
,'company' => ''
,'state' => 'CA'
,'phone' => ''
);
$errors = array_keys( array_diff_key( $arr, array_filter($arr) ) );
var_dump($errors);
// output:
array(2) {
[0]=>
string(7) "company"
[1]=>
string(5) "phone"
}

Categories