Combining PHP Functions - Advanced Search? - php

I have to build an advanced search feature and some of it options are complex. For example:
is Online
have Comments
etc
To get this information, I can't make direct database queries. So, I need to build functions to do this.
Let's say... the user selects 4 or 5 options - how can I combine multiple functions results?
It doesn't make sense to do something like:
if(is_Online() && have_Comments()...)
Because I don't know which or how many options are selected... so I think there should be some dynamic alternative?
Thank you.

Difficult to provide a better answer without more detail, but this might help you. The following assumes that your if statement will proceed when each checkbox is either left unchecked or when the logic associated with that checkbox returns true.
I would be inclined to store each function in an array and call them dynamically based on the name of the field you're looking at.
<?php
$resultCheckers = array(
'is_Online' => function() { /* Is Online logic here */},
'have_Comments' => function() { /* Have Comments logic here */}
);
function IsUncheckedOrHasValue($parameter)
{
$result = true;
//Check if user has checked the box for this parameter
if(array_key_exists($parameter, $_POST))
{
//Check if this is a valid key in your $resultCheckers
if(array_key_exists($parameter, $resultCheckers))
{
//Run the result Checker
$result = $resultCheckers[$parameter]();
} else {
$result = false;
}
}
return $result;
}
?>
Your if statement would look something like this:
if(IsUncheckedOrHasValue('is_Online') && IsUncheckedOrHasValue('have_Comments'))
{
...
}
Which is a bit laborious to read, so if you wanted you could abstract it further into it's own function like this:
function IsMatch()
{
$isMatch = IsUncheckedOrHasValue('is_Online') &&
IsUncheckedOrHasValue('have_Comments') &&
IsUncheckedOrHasValue(...) &&
IsUncheckedOrHasValue(...);
return $isMatch;
}
So then your if statement would end up being
if(IsMatch())
{
...
}
NOTE: I'm a little confused that you're not passing any information about the result to your checking functions. Are you writing it Object Oriented and that information is available in the current object? Or perhaps you just omitted those extra parameters for brevity. In any event, I hope this helps you and it was fun to dip back into PHP after some time away from it :)

Related

How to use array to determine empty $_GET query string in PHP

I am trying to check that all query requests from a form is filled and not hindered before proceeding with further actions.
I have a code that works already, but i would like to make it an array in other to shorten my code.
My form queries are a,b,c
Below is my current code:
if ( isset($_GET) && !isset($_GET['a']) || !isset($_GET['b']) || !isset($_GET['c']) )
{ //Reject call
}else{
//Process call
}
I wish to shorten this code with an array, here is my current code but this isn't working.
$supportedrequests = array('a','b','c')
if (isset($_GET) && !isset($_GET[(in_array($supportedrequests))]) ) {
{ //Reject call
}else{
//Process call
}
Any help will be appreciated.
UPDATE
This question is not a duplicate of Using if(!empty) with multiple variables not in an array because it is specifically based on checking isset($_GET) query itself if it exists, and aside that, no answer was fully rendered for the said topic in the stated link.
If you want check request method GET or POST use this: $_SERVER['REQUEST_METHOD'] == 'POST'
For checking multiple parameters you can declare function and check them all.
function allIsset($params)
{
foreach ($params as $param) {
if (!isset($_GET[$param])) return false;
}
return true;
}
Or you can use this method (if you want just less lines of code)
$supportedrequests = array('a','b','c');
if (count(array_intersect(array_keys($_GET), $supportedrequests)) < count($supportedrequests)) {
//reject
}

php use value as a variable name (for a key) from an array to unpack a resultset from Drupal

I will be reusing a Drupal db_query result set unpacking function many, many times in my code for a variety of different queries - I am using O-O and as such I want to reuse it and be as 'DRY' as possible.
Therefore I have tried to strip it down to the most generic functions so that as long as the $columns supplied match the columns used in the query and similarly in the $resultset, I can loop and assign values to keys, as is shown, and return a $rows[].
I've not yet come across the issue of trying to use a variable's value as a variable name (the $key), if it's just something I should avoid entirely, please say.
foreach($this->resultSet as $aRecord) {
$c = 0;
while (isset($this->columns[$c])) {
$value = $this->columns[$c];
$rows[$i] = array(
$key[$this->columns[$c]] => $aRecord->$value,
);
$c++;
}
$i++;
}
I've read through the following and am beginning to think this is just knowledge I'm missing in my PHP experience so far.
Can I use a generated variable name in PHP?
PHP use function return value as array
https://wiki.php.net/rfc/functionarraydereferencing
It felt wrong, and someone once told me that if you have to start writing complex functions in PHP you've probably missed an available function PHP already offers.. so true... thanks to (at the time of writing...) 'MrCode' for this suggestion.
$this->sql = "SELECT foo, bar FROM foobar";
$this->result = db_query($this->sql);
if ($this->result->rowCount() > 0) {
while ($row = $this->result->fetchAssoc()) {
$this->resultArray[] = $row;
}
}

PHP: If condition with explode within foreach loop

I am trying to get multiple value from user input from text field and want to explode or keep adding into if condition statement
Here is my code
foreach ($list['post'] as $item) {
if( ($item['single']['catid'] != 8) AND ($item['single']['catid'] != 4) ){
$this->list_post($item);
}
}
Now what exactly I am looking for is in if( ($item['single']['catid'] != 8) AND ($item['single']['catid'] != 4) ) I want allow user to add multiple category ID and each ID will add AND and further id code AND ($item['single']['catid'] != 4)
I never done this before and don't know either this is proper way to do or any other possible better way.
Thanks a lot
You should have some kind of an array of the category IDs you want to check for, for example:
$categories = array(8, 4);
Then you could use something like the in_array(needle, haystack) built-in function of PHP.
Your if condition would become like that one: if (!in_array($item['single']['catid'], $categories)) {.
You should be using the above, but I am going to give you an idea of how it works, so you can understand the principle for more complex issues:
function exists($target, $array) {
foreach ($array as $element) { // Go through each element in the array
if ($element == $target) { // Check to see if any element there is what you are searching for
return true; // Return true, that it does exist, and stop there.
} else {
// Just ignore it...
}
}
return false; // If you get here, it means nothing returned true, so it does not exist...
}
To be used as if (exists($item['single']['catid'], $categories)) {.
It wouldn't work if it was "inside" the if statement because you have to do some processing before evaluating if it exists or not. So you either could have done that before the if statement, and store the result in a variable, or use a function (which PHP provides).
Hopefully the concept will help you fir more complex problems...
Note: this assumes your input is in the form of an array, which you can build via various ways, if not provided as is directly.
Update:
The input you get via the input field is sent through form, to which you specify either POST or GET as a method. Assuming it is POST that you are using, this is how you'd get the input as a string as it was entered in the text field:
$categories_string = $_POST['the_name_field_in_the_input_tag'];
After that you have to understand it as a list of items, let's say separated by commas: 1,3,5,8. Then this is simply separating by commas. You can use explode($delimiter, $string). Like that:
$categories_array = explode(',', $_POST['categories']);
But you cannot trust the input, so you could get something like 1, 2, 3,5,6. The spaces will mess it up, because you will have spaces all around. To remove them you can use trim for example.
$categories = array(); // Create the array in which the processed input will go
foreach ($categories_array as $c) { // Go through the unprocessed one
$categories[] = trim($c) * 1; // Process it, and fill the result. The times one is just so that you get numbers in the end and not strings...
}
Then you can use it as shown earlier, but keep in mind that this is just an example, and you might not even need all these steps, and there are much more efficient ways to process this input (regular expressions for example). But the concern here is not sanitizing input, but keep in mind you will need to do that eventually.
Hope it's clear enough :)
You might be better off with in_array() for checking a value against a variable number of possibilities.
I'm not sure I understand your problem. You want user to be able to input different values, e.g.:
$string = "5, 6, 7, 8, 10";
Afterwards, you want to check if 'catid' is not in that array and if it isn't you want to run $this->list_post($item);
If so, then you should use something like this:
$values = explode(", ", $string); //make array from values
foreach ($list['post'] as $item) {
if (!in_array($item['single']['catid'], $values)) { //check whether catid is in array
$this->list_post($item); // execute whatever you want
}
}
Hope it helps.

Check if a option in a form that was selected is the same as a variable in an array

I'm trying to validate some form data before adding it to a database however I need to validate that the option was an option that is in the form, not just one that was added with something like Firebug.
I tried using if and comparing the posted values like this: (there is another 27 options, and 3 more option fields)
if($data['selection'] == 'some_option' || $data['selection'] == 'some_option2') {
However it makes extremely long lines of code and its difficult to manage. So I thought about making an array that stores the possible options, then when its submitted, check if the selected option matches one of the entries in the array.
One of my ideas was to do a loop and check if it's equal:
for($i = 1; $i < sizeof($options[$currentselection]); ++$i) {
if($option[$i] == $data[$currentselection]) {
return true;
} else {
return false;
}
}
However I'd have to do one of these for each of the selection fields (which I'd rather not do). So is there a way of cleaning it up and having it all in one? Also, I'm using codeigniter.
A simple way is to use the in_array function
$values=Array('op1','op2',...);
return in_array($data['selection'],$values);
Or you can do this:
$values=Array(
'selection'=>Array('op1','op2'),
'another_field'=>Array('op3','op4'),
);
return in_array($data[$field],$values[$field]);

consecutive if's in PHP

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;
}
}

Categories