I am trying to create a function that checks to see if a user name already exists. I am still trying to get my head wrapped around MongoDB and was wonder what is the best way to approach this? I was going to do some the following (in Code Igniter):
$filter = array ('userName' => $value);
$exists = $md->find($filter);
if ($exist) {
return TRUE
} else {
return FALSE
}
Is there a better way?
Looks about right, here's what I have for mine.
if ($collection->findOne(array("username" => $username)) );
return true;
Related
Hi so I want to know the easiest way to check if multiple POST parameters are set. Instead of doing a long if check with multiple "isset($_POST['example'])" linked together by "&&", I wanted to know if there was a cleaner way of doing it.
What I ended up doing was making an array and looping over it:
$params_needed = ["song_name", "artist_name", "song_release_date",
"song_genre", "song_medium"];
I would then call the function below, passing in $params_needed to check if the parameter names above are set:
function all_params_valid($params_needed) {
foreach ($params_needed as $param) {
if (!isset($_POST[$param])) {
error("Missing the " . $param . " variable in POST request.");
return false;
}
}
return true;
}
if (all_params_valid($params_needed)) {
$song_name = $_POST["song_name"];
$artist_name = $_POST["artist_name"];
$song_release_date = $_POST["song_release_date"];
$song_genre = $_POST["song_genre"];
$song_medium = $_POST["song_medium"];
...
}
However when I do this, it gets stuck on the first index and says "Missing the song_name variable..." despite actually including it in the POST request, and I'm not sure why this is happening. The expected behavior would be for it to move on and tell me the next parameter "artist_name" is not set, but this doesn't happen.
I personally like using array_diff for this issue.
PHP array_diff documentation
What you care about is your expected input is the same as the given input.
So you can use array_diff like this:
$params_needed = ["song_name", "artist_name", "song_release_date",
"song_genre", "song_medium"];
$given_params = array_keys($_POST);
$missing_params = array_diff($params_needed, $given_params);
if(!empty($missing_params)) {
// uh oh, someone didn't complete the form completely...
}
How I approach this is by using array_map() so I can return all the values in the array whilst checking if it isset()
PHP 5.6 >
$args = array_map(function($key) {
return isset($_POST[$key]) ? array($key => $_POST[$key]) : someErrorMethod($key);
}, ["song_name", "artist_name", "song_release_date", "song_genre", "song_medium"]);
PHP 7+
$args = array_map(function($key) {
return array($key => $_POST[$key] ?? someErrorMethod($key));
}, ["song_name", "artist_name", "song_release_date", "song_genre", "song_medium"]);
Your error method could look something like this:
function someErrorMethod($key) { die("$key cannot be empty."); }
Inside of your $args variable, you will have an array of key => value. For example,
echo $args['song_name'];
Here's my code:
function prepare_machine($variables)
{
foreach ($variables AS $varname => $vartype)
{
if (isset($_REQUEST[$varname]))
{
$value = $_REQUEST[$varname];
return do_clean($value, $vartype);
}
else
exit;
}
}
It is called like this:
prepare_machine(array('order_by_time' => TYPE_BOOLEAN));
it all works fine, but if you have multiple things in the array, for examples;
prepare_machine(array('order_by_time' => TYPE_BOOLEAN, 'order_by_date' => TYPE_BOOLEAN));
it will only do anything with the first one.
Can anybody see what is wrong with my code?
Thanks
You're doing a return ... when you find a match in your inner loop. That's why it only processes one.
Also, you should be using array_key_exists($varname, $_REQUEST) because isset($_REQUEST[$varname]) will fail if $_REQUEST[$varname] is null.
return returns whatever you give it, and exits the function. You need to change your function somehow so that it only returns after processing all the variables.
$result = validateUploadedFile($_FILES);
if (!empty($result) && !empty($result['valid']) && $result['valid'])
{
// do sth
// I don't know why sometime this three checks will cause me problems
// In other words, even if $result['valid'] is TRUE, this scope will not be hit
}
The function validateUploadedFile returns an array as $result['valid'] == TRUE if it goes through.
Here is the question, does the if statement checks too much?
Can I simply check the following instead? I have few PHP language knowledge and don't know whether those checks are necessary or not.
if ( $result['valid'] )
{
// do sth
}
Thank you
function validateUploadedFile($uploadedFile)
{
// Define file size limit
$result = array('valid' => FALSE, 'error_message' => null, 'error_code' => null);
if (sth_wrong)
{
$result['error_message'] = 'sth_wrong';
return $result;
}
if (sth_wrong2)
{
$result['error_message'] = 'sth_wrong2';
return $result;
}
$result['valid'] = TRUE;
return $result;
}
It depends on what the function returns in the case where the uploaded file is not valid. This should probably suffice in most cases though:
if (!empty($result['valid']))
Since:
FALSE is empty
NULL (or an unset array index) is empty
It won't complain, even if $result is an empty array
You could also just do
if (!$result['valid'])
but this will give you E_NOTICE if that element isn't set.
I would think
if (isset($result['valid']) && $result['valid'])
would work just fine.
Your approach is more of what you should be doing with raw user input. Since you're dealing with a function, however, it would be a lot easier to have it do the heavy lifting.
Just ensure it always sets the 'valid' key; your code will be more readable and secure. If you do that, an if($result['valid']) will suffice.
You can test it. In this particular case, it seems you're not entirely sure which values to check for. In most cases and according to logic, simply doing a !$result['valid'] /should/ work - but that's assuming PHP considers null / unset values as 'false'.
Make a quick script that tests all the conditions separately.
What happens when calling empty($result['valid']) when $result is null?
What happens when calling !$result['valid'] when $result['valid'] is undefined?
Go on. Write a script. Test it, and Know.
Using PHP..
Here is what I have.. I'm gonna explain the whole thing and maybe someone can help me with the logic and maybe point me in the right direction.
I have a mail system I am working on. In the cc part, I am allowing the user to seperate the values by a semicolon, like so: 1;2;3;4...
When these values are passed to my function, I am using explode to get them into an array. What I want to do is some checking first. I want to firstly make certain that the format is correct and that every value is correctly seperated. If not, I should show an error. Once this is done, I want to make certain that every number is actually valid. I can query the database, put the reslts into an array and was thinking to use the in_array() function to verify this but I'm not certain that it will work. Can someone please help me out with the best way to handle this?
Thanks.
EDIT:
What is the best way to detect a bogus value in the CSV list of values?
In order to verify that each number was correct seperated, you want to check that there is no whitespace in the answer. So something like this should work:
$text = trim($id);
if(strpos(" ", $id) !== false)
{
//error
}
Next, to check for the values, it is very simple
if(!in_array($id, $database_ids))
{
// error
}
Finally, if you are only using numeric values, check that the id is numeric
if(!is_numeric($id))
{
//error
}
To combine, wrap it into an array
foreach($exploded_array as $key => $id)
{
$id = trim(id);
if(!is_numeric($id))
{
//error
}
if(strpos(" ", $id) !== false)
{
//error
}
if(!in_array($id, $database_ids))
{
// error
}
}
I hope the code was pretty self explanatory where it got the variables, but if you need me to explain more, feel free to ask.
You are looking for something like:
foreach ($array as $value) {
//do checking here
}
array_filter could be an option.
As whichdan suggested, here is an implementation that relies on array_filter():
<?php
function checkValue($value)
{
$id = trim(id);
if(!is_numeric($id))
{
return false;
}
if(strpos(" ", $id) !== false)
{
return false;
}
if(!in_array($id, $database_ids))
{
return false;
}
return true;
}
$values = '1;2;3;4';
$values_extracted = explode(';', $values);
if(count($values) == count(array_filter($values_extracted), 'checkValue'))
{
// Input was successfully validated
}
?>
I'm doing some validation now in PHP, and I'm running allot of conditional statements, for example:
if ($this->email->isValid($email))
return false;
if ($this->username->isValid($username))
return false;
ect..
Is there a nice way to do this? Or do I just run ten If statements like the ones above?
I can't use switch obviously, but I'm looking for that type of solution..
P.S... I'm using Zend Framework for validation
You could OR them like this:
if(cond1||
cond2||
cond3||
cond4)
{
return false;
}
Doing something like this is called a Guardian clause. It can be improved so clauses that return the same value should be grouped together.
if ($this->email->isValid($email) || $this->username->isValid($username))
{
return false;
}
Or like this, if there are many (btw how I format the if is just so it can read better, any other way should be fine as well)
if (
$this->email->isValid($email) ||
$this->username->isValid($username) ||
$this->somethingelse()
)
{
return false;
}
If this is data from a form, take a look at Zend_Form, as recommended by a poster in your other question
I posted some example code which details adding validators to form elements
Just make sure that you put the most obvious validation at the top, so if its going to fail it will trip before it runs through every statement. Also, I don't like if statements without curly brackets, but then thats just a matter of opinion.
if ($this->email->isValid($email) ||
$this->username->isValid($username))
return false;
It is always good to use some var than multiple returns
In case these are the only return conditions. We dont need to check for all conditions. like check only for true conditions return false by default or vice-versa.
$result = false; //return false by default.
if (cond1 || cond2) { //check only for conditions which result in returning true. :)
$result = true;
}
return $result;
Cheers,
-Ratnesh
I would make them data members of my class. Obviously here you will have to have a form driven class. So here for example the email could be wrapped into a class and initialised with in the constructor of the class that has them as member variables. Now the email wrapper class will do validation for email on initialisation/construction.
IMHO that would look less cluttered and you can wrap up any validation or specific methods to the email-wrapper class.
I know it might be a sledge hammer in some context; so choose wisely!
Maybe something like this:
foreach( $form->getElements as $element => $value )
{
if( !$element->isValid( sanitize($value))){
return false;
}
}
BUT if you are using ZF this is your oneliner answer because you check all the form in one not individual fields:
$form = new My_Zend_Form(); // in the controller action that you send the form to
if ( $form->isValid($_POST)) {
// Success /// do whatever you want with the data
$data = $form->getValues();
} else {
//error
}
Do something like this:
$errlvl = 0;
if($errlvl == 0 && $this->email->isValid($email)){
$errlvl++;
}
if($errlvl == 0 && $this->username->isValid($username)){
$errlvl++;
}
// your validation list keeps going
if($errlvl > 0){
return false;
}
this will
Reduce redundancy because if there's an error in front, the following will not be checked.
you can keep adding on to the list
if you want to know how many errors occurred, you can remove $errlvl == 0 in the statements
Add all objects to an array and the iterate it (I guess you or Zend are using an interface "validator" or something like that each component (username, email, etc) implements the "isValid" method):
$validators = array();
$validators[] = $this->email;
$validators[] = $this->username;
foreach ($validators as $validator)
{
if (!$validator->isValid())
{
return false;
}
}