I've created an array that contains a form data (the form and php scripts are in a single php file).
I need to create a function to specify which one of the array elements are empty.
This is my code:
if(isset($_POST['submit'])){
$data=array("username"=>$_POST['username'],
"email"=>$_POST['email'],
"password1"=>$_POST['password1'],
"password2"=>$_POST['password2'],
"gender"=>$_POST['gender']);
check($data);
}
function check(){
if(isset($_POST['username']) && isset ($_POST['email']) && isset ($_POST['password1'])){
echo 'ok';
}
else{
echo 'missing';
}
}
Hi #Sina you didn't pass the param $data in the function definition.
<?php
if (isset($_POST['submit'])) { //only if form is submitted
$data = array(
'username' => $_POST['username'],
'email' => $_POST['email'],
'password1' => $_POST['password1'],
'password2' => $_POST['password2'],
'gender' => $_POST['gender']
);
check($data);
}
/**
* #description: validates the form data
* #return none
* #params array($data)
*/
function check($data) {
foreach ($data as $key => $value) {
if (empty($value)) {
echo ucwords($key)." is empty.<br/>";
}
}
}
?>
Thanks & Regards,
Vivek
Just use foreach :
function check($data)
{
foreach($data as $key => $value)
{
echo $key . isset($data[$key]) ? ' Ok' : ' Missing';
}
}
Edit : Fixed function with parameter
There are different ways of solving this, you can use foreach with empty() and a second array to contain the empty elements list.
Follow these steps:
Use foreach to get the values
Read index value and check if (empty($_POST[$key]))
If it's empty, either echo it or save it in a second array to use it later.
The following implementation is one suggestion but have a read at this good article on security and validations.
$_POST exists?
define a list of keys ( to iterate )
do validations in loop ie.isset(),is_null(),empty(),striptags/slash, sanitize etc.
Example:
if(empty($_POST)) {
// handle error ie. redirect
}
// define required keys or as constants using define();
$post_keys = array(
'username',
'email"'
'password1',
'password2',
'gender'
);
foreach($post_keys as $k => $v) {
// _isValid() is optional
// ie. or revalidate email format, empty string, blah etc.
// if(!isset($_POST[$k]) || !_isValid($k, $v)) { .. }
if(!isset($_POST[$k]) {
// handle error
}
}
// everything ok, do stuffs ie.$_POST['username'];
Hope this helps.
Related
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';
}
I am using the following code to validate integer input fields in my form:
if (isset($_POST['MaxiVegXP']) && ctype_digit($_POST['MaxiVegXP']))
{
$MaxiVegXP = $_POST['MaxiVegXP'];
} else {
$MaxiVegXP = FALSE;
}
I have another 20 or so similar form input fields. Is there a quicker way of doing this with a PHP loop? I'd rather not do the above for another 20 input fields :-)
I would do something like #Simply Dread, but with a slight improvement, so I could explicitly indicate which fields needed to be fixed:
$validFields = array('field1' => true, 'field2' => true, 'field3' => true, ..., 'fieldN' => true);
foreach ($validFields as $field => $valid) {
if (!isset($_POST[$field]) && !ctype_digit($_POST[$field])) {
$validFields[$field] = false;
}
}
With this information, I can now show errors on the appropriate fields instead of only saying that there is a problem.
You could iterate over all fields for example:
foreach ($_POST as $key=>$value){
if (isset($_POST[$key]) && ctype_digit($_POST[$key])) {
$$key = $value;
} else {
$$key = FALSE;
}
}
But I would instead put the code in a function and call the fuction excplicitly for every post variable:
function isDigit($value) {
if (isset($value) && ctype_digit($value)) {
return true;
}
return false;
}
$MaxiVegXP = isDigit($_POST["MaxiVegXP"]) ? $_POST["MaxiVegXP"] : false;
An option would be to create an array of the field names and loop over it. Doing it this way will ensure all fields have to be set and are digits. Check the validate variable afterwards and you'll know if it was successful. :-)
$fieldArray = array('fieldOne', 'fieldTwo', 'fieldThree');
$validate = true;
foreach ($fieldArray as $field) {
if (!isset($_POST[$field]) && !ctype_digit($_POST[$field])) {
$validate = false;
}
}
Is there a quicker way of doing this with a PHP loop?
there's a quicker to do this without a PHP loop:
I would use filter_input_array. This code will assign null to the value if it does not pass the filter. It's quite practical, you just have to add the name of the variable and it's desired filter in the array.
$vars = filter_input_array(INPUT_POST,array (
'MaxiVegXP'=>FILTER_VALIDATE_INT,
'myVar'=>FILTER_DEFAULT,
// or FILTER_VALIDATE_INT. you can also define validator callbacks if need be
));
here you define the keys you wish to get from the input ($_POST in this example, but you can use INPUT_GET to get variables from the $_GET superglobal). You can also define more advanced options in the array to define a min or max range for your inputs, for instance
$vars = filter_input_array(INPUT_POST,array (
'MaxiVegXP'=>array(
'filter'=>FILTER_VALIDATE_INT,
'options'=>array('min_range'=>1, 'max_range'=>10),
),
));
the usefulness is that you don't have to verify manually for each key if they exist and what type they're of, filter_input_array takes care of that once you've defined your array of accepted value
For a project with Laravel 4.1 I have a little UI issue I'd like to solve.
Some inputs make an ajax call to laravel on blur and that works fine. It simply sends it's value. In laravel I then check with the validator.
public function validate() {
if(Request::ajax()) {
$validation = Validator::make(Input::all(), array(
'email' => 'unique:users|required|email',
'username' => 'required'
));
if($validation->fails()) {
return $validation->messages()->toJson();
}
return "";
}
return "";
}
Although this works, the json string also contains fields I have no need to check. To be precise this is the feedback I get:
{"email":["The email field is required."],"username":["The username field is required."]}
But seeing it is on blur I only want the one I'm actually checking in return. So if i'm blurring email I want a return of:
{"email":["The email field is required."]}
Now I know it's obviously because my array contains multiple fields, but I don't feel like writing a complete validation for each possible input I ever make.
My question is: can I somehow only get a return of the post values that are actually posted, even though the value might be null and not get rest of the array back.
Try this (untested, feel free to comment/downvote if it doesn't work) :
// Required rules, these will always be present in the validation
$required = ["email" => "unique:users|required|email", "username" => "required"];
// Optional rules, these will only be used if the fields they verify aren't empty
$optional = ["other_field" => "other_rules"];
// Gets input data as an array excluding the CSRF token
// You can use Input::all() if there isn't one
$input = Input::except('_token');
// Iterates over the input values
foreach ($input as $key => $value) {
// To make field names case-insensitive
$key = strtolower($key);
// If the field exists in the rules, to avoid
// exceptions if an extra field is added
if (in_array($key, $optional)) {
// Append corresponding validation rule to the main validation rules
$required[$key] = $optional[$key];
}
}
// Finally do your validation using these rules
$validation = Validator::make($input, $required);
Add your required fields to the $required array, the key being the field's name in the POST data, and the optional fields in the $optional array - the optional ones will only be used if the field exists in the submitted data.
You can also use Laravel requests in a much cleaner way
public function rules(){
$validation = [];
$input = Request::all();
if (array_key_exists('email', $input)) {
$validation['email'] = 'unique:users|required|email';
}
if (array_key_exists('username', $input)) {
$validation['username'] = 'required|min:6';
}
return $validation;
}
I found it. It's going to be something like this:
if(Request::ajax()) {
$arr = array();
$arr['email'] = 'unique:users|required|email';
$arr['username'] = 'required|min:6';
$checks = array();
foreach($arr as $key => $value) {
if(Input::has($key)) {
$checks[$key] = $value;
}
}
if(count($checks)) {
$validation = Validator::make(Input::all(), $checks);
if($validation->fails()) {
return $validation->messages()->toJson();
}
}
return "ok";
}
return "";
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"
}
I'm trying to save a long form in Codeigniter's Datamapper. I'm able to save the form if I pass the value like this
$t->brandName = $this->input->post('brandName');
$t->specialNotes = $this->input->post('specialNotes');
$t->name = $this->input->post('name');
Now if I call save method it works
$t->save();
Since the form is big I tried to add object values in foreach
$a = get_object_vars($t);
foreach ($a['stored'] as $k => $val){
$t->$k = $this->input->post("$k");
}
however if I call the $t->save() it doesn't work.
I'm not sure what $a['stored'] represents, but it's nothing that's default in Datamapper.
Why don't you do it the opposite way, looping through the post keys?
foreach ($_POST as $key => $val)
{
$t->$key = $this->input->post($key);
}
$t->save();
Note: Any columns that don't exist will just be ignored by Datamapper.
I actually wrote a Datamapper extension for this:
class DM_Data {
function assign_postdata($object, $fields = NULL)
{
// You can pass a different field array if you want
if ( ! $fields)
{
$fields = $object->validation;
}
foreach ($fields as $k => $data)
{
$rules = isset($data['rules']) ? $data['rules'] : array();
if ( ! isset($_POST[$k])) continue;
// Cast value to INT, usually for an empty string.
if (in_array('integer', $rules))
{
$object->$k = (integer) $_POST[$k];
}
// Do other manipulation here if desired
else
{
$object->$k = $_POST[$k];
}
}
return $object;
}
}
You can use $t->assign_postdata()->save(), and optionally pass an array of fields to update to the function (in the datamapper validation format). However, I forget why I use that... but I removed some of the custom stuff. This should be useful for you if you are doing this a lot. It definitely saves me time.