Create an array of function arguments not equal to NULL? - php

I'll start with explaining what my end goal is as there may be better solutions to it.
I have a function called updateUser which accepts the following parameters:
function updateUser($password = NULL, $name = NULL, $lastname = NULL, $age = NULL, $email = NULL, $relation = NULL)
As you can see I've set them to NULL, so if they aren't passed through the function they become blank. Right? (I hope I got that right)
The problem is that each of those arguments (which are passed) contains info for a user that's going to be sent in to a database, and I only want to include the passed variables in the query as I don't want to set the ones that are not passed to (blank) in the database.
And so I came up with the idea to take all the passed arguments and shove them into an array. And then loop through every item in the array and generate a string like:
$string = "$password, $email";

I guess it would be more flexible if you just pass one array containing the property/value pairs that should be updated:
function updateUser($props) {
$names = array('password', 'name', 'lastname', 'age', 'email', 'relation');
$arr = array();
for ($names as $name) {
if (isset($props[$names])) {
$arr = "$name = '".mysql_real_escape_string($props[$names]).'"';
}
}
if (!empty($arr)) {
$query = "UPDATE … SET ".implode(',', $arr);
}
}
Then you call this function with an array with the properties that should be updated:
updateUser(array('name'=>'User A', 'password'=>'secret'))

Using the function call_user_func() (php.net docs), you can call your database INSERT or UPDATE commands depending on what data is passed to the function.
For example:
function updateUser($password = NULL, $name = NULL, $lastname = NULL,
$age = NULL, $email = NULL, $relation = NULL)
{
$array = array();
// Create an array with indices of passed parameters:
if($password !== NULL) // !== to check for NULL and not empty string.
$array["password"] = $password;
if($name !== NULL)
$array["name"] = $name;
// etc...
call_user_func("addToDb", $array);
}
function addToDb($detailsArray)
{
foreach($detailsArray as $detail)
{
// Add $detail's key with $detail's value to database.
}
}

Gets all arguments and filter variables away which are not a string.
$arguments = func_get_args();
array_filter($arguments, 'is_string');
//$arguments will be an array with numeric indices

I think the problem is that you might not call the function correctly. When you do it like this:
updateUser('pass', 'user', '', '', 'user#example.com');
than the values of $lastname and $age will not be null, but an empty string. But if you call it like this:
updateUser('pass', 'user', null, null, 'user#example.com');
they will remain null.

Related

PHP class fields are the same

I have a problem with PHP code.
Here is it:
class Note {
public $title = "";
public $text = "";
}
$note = new Note();
while($note_result = pg_fetch_array($result, null, PGSQL_ASSOC)) {
$note->$title = $note_result["title"];
$note->$text = $note_result["text"];
}
The problem is that $note->$title and $note->$text have the same value. I tried assigning $note_result["..."] to two different variables and it worked, but I would like to use class to return variable as one.
Am I missing something? I been checking this code for half an hour and found nothing.

PHP ReflectionMethod does not get default boolean value of param

When I try to get the value of a boolean param, with ReflectionMethod, that have a default value set, I got empty result.
With this code:
public function GetOrderBook($symbol = null, $limit = 100, $async = false)
{
if ($symbol !== null) {
$params = [];
$ref = new \ReflectionMethod($this, 'GetOrderBook');
foreach ($ref->getParameters() as $param) {
$name = $param->name;
$params[$name] = $$name;
}
print_r($params);
}
}
I get this:
Array (
[symbol] => ETHBTC
[limit] => 100
[async] =>
)
Is there a way to get the default value of a param with reflection?
print_r function outputs string representation of values. String representation of false is empty string. To see real values that you have in an array, use var_dump:
var_dump($params);
After that you will see that:
["async"]=>bool(false)

PHP - Adding variables to an associative array with the variable names as keys

This is my first post so I'm sorry for any mistakes that I may not be aware of.
I've been fidddling with forms and POST for the past days now and I have a curious question on a certain situation.
I have this code in my basic web form. I declared some variables as shown below.
<?php
if (isset($_POST['submit'])) {
// Form submitted
$username = isset($_POST['username'])? $_POST['username'] : "";
$password = isset($_POST['password'])? $_POST['password'] : "";
$email = isset($_POST['email']) ? $_POST['email'] : "";
$country = isset($_POST['country']) ? $_POST['country'] : "";
}
?>
I wanted to create an array form_data with these variables as its elements, so I inserted the following:
<?php
$form_data = array();
$form_data['username'] = $username;
$form_data['password'] = $password;
$form_data['email'] = $email;
$form_data['country'] = $country;
print_r($form_data);
?>
My question is that is there any method in PHP that I don't know of in where I can get the same result? The variable name will be assigned as a key in the array and I prefer not to type in the keys' names manually like on that bit of code above.
So in short, if I have a variable named $number, I want to add its value into an array with 'number'(the variable name) as its key. Is there a method that does this automatically?
I hope I've made this question clear enough.
You could use compact:
$form_data = compact('username', 'password', 'email', 'country');
As long as you have the variables $username, $password, $email, and $country it will create the array you described.
compact() looks for a variable with that name in the current symbol table and adds it to the output array such that the variable name becomes the key and the contents of the variable become the value for that key.
Or, you could do a whitelist approach:
function array_whitelist($array, $whitelist = array()) {
return array_merge(array_flip($whitelist),
array_intersect_key($array, array_flip($whitelist)));
}
$form_data = array_whitelist($_POST, array('username', 'password', 'email', 'country'));
You can this with a loop. Create an array of variable names that you'll either white list (keep) or black list (remove) to help remove entries like submit from your array:
$blacklist = array('submit');
$form_data = array();
foreach($_POST as $key => $value) {
if(in_array($key, $blacklist))
continue; // skip unwanted entries
$form_data[$key] = $value;
}
Apply any trim() or other formatting during your loop.
Likewise, if you wanted to whitelist the variables you want to keep you can use a similar process:
$whitelist = array('username', 'password', 'email', 'country');
foreach($whitelist as $key) {
if(isset($_POST[$key]) && $_POST[$key] != '')
$form_data[$key] = $_POST[$key];
}
You can use array_keys function
$Keys=array_keys($_POST);
for($i=0;$i<count($Keys);$i++){
$form_data[$Keys[$i]]=$_POST[$Keys[$i]];
}
print_r($form_data);

Least verbose way of defining a default array value

Is there a cleaner way to check for array values to prevent PHP notices? Currently I do this:
$email = (isset($_POST['user_email'])) ? $_POST['user_email'] : '';
$first_name = (isset($_POST['user_first_name'])) ? $_POST['user_first_name'] : '';
$last_name = (isset($_POST['user_last_name'])) ? $_POST['user_last_namel'] : '';
$birthday = (isset($_POST['user_last_name'])) ? $_POST['user_last_namel'] : '';
Is there a way to do something like JavaScript where you just provide a default, like this?
user.email = response.email || '';
I don't want to suppress notices, but these ugly checks clutter up my code. I'm on PHP 5.2.6.
You can create a function:
$email = getPost('user_email');
$first_name = getPost('user_first_name');
$last_name = getPost('user_last_name');
$birthday = getPost('user_birthday');
function getPost($key, $default = '')
{
if (isset($_POST[$key])) {
return $_POST[$key];
}
return $default;
}
Putting it in a function also let's you do additional sanitizing more easily, e.g., trim(), if desired.
You can also pass a default value that will be returned:
$flavor = getPost('flavor', 'vanilla'); // if $_POST['flavor'] is not set, 'vanilla' is returned
If you have a set of attributes, then one concise option is array_merge. Note that the defaults go first:
$post = array_merge(
array("email" => "", "first_name" => "", "last_name" => "", "birthday" => ""),
$_POST
);
Then just access them as is:
$email = $post["email"]; // it's assured there is some value
An even more compact way to localize a limited set of variables is extract() in combination with array_intersect_key(). But only in that combination - to prevent importing arbitrary variables:
extract(array_merge($defaults, array_intersect_key(array_filter($_POST), $defaults)));
I have seen at least three ways of doing this.
Adding array with defaults
$options = $_POST + $defaults;
where $options is an associative array having everything $_POST had, but with added keys and values from $defaults (unless there was a value in $_POST for specific key in $defaults, then this specific key/value pair from $defaults is ignored and value for this specific key in $_POST is not replaced).
Merging with array of defaults
As shown by #mario (use array_merge()):
$options = array_merge($defaults, $_POST);
Using helper functions...
...such as Kohana's Arr::get() helper:
/* ... */
public static function get($array, $key, $default = NULL)
{
return isset($array[$key]) ? $array[$key] : $default;
}
/* ... */
which has some advantage of easily replacing default value (which, by default is NULL). It can be used like that:
echo Arr::get($_POST, 'user_email');
or:
echo Arr::get($_POST, 'user_email', 'N/A');
function assure(&$a, $default=null) {
if (!isset($a)) $a=$default;
return $a;
}
$email=assure($_POST['user_email'],'');
$first_name=assure($_POST['user_first_name'],'');
You can use DefaultArray from NSPL:
$post = defaultarray('', $_POST);
$email = $post['user_email'];
$first_name = $post['user_first_name'];
$last_name = $post['user_last_name'];
$birthday = $post['user_birthday'];

How to pass an array into a function, and return the results with an array

So I'm trying to learn how to pass arrays through a function, so that I can get around PHP's inability to return multiple values. Haven't been able to get anything to work so far, but here is my best try. Can anybody point out where I'm going wrong?
function foo($array)
{
$array[3]=$array[0]+$array[1]+$array[2];
return $array;
}
$waffles[0]=1;
$waffles[1]=2;
$waffles[2]=3;
foo($waffles);
echo $waffles[3];
For clarification: I want to be able to pass multiple variables into a function, do something, then return multiple variables back out while keeping them seperate. This was just an example I was trying to get working as a work around for not being able to return multiple variables from an array
You seem to be looking for pass-by-reference, to do that make your function look this way (note the ampersand):
function foo(&$array)
{
$array[3]=$array[0]+$array[1]+$array[2];
}
Alternately, you can assign the return value of the function to a variable:
function foo($array)
{
$array[3]=$array[0]+$array[1]+$array[2];
return $array;
}
$waffles = foo($waffles)
You're passing the array into the function by copy. Only objects are passed by reference in PHP, and an array is not an object. Here's what you do (note the &)
function foo(&$arr) { # note the &
$arr[3] = $arr[0]+$arr[1]+$arr[2];
}
$waffles = array(1,2,3);
foo($waffles);
echo $waffles[3]; # prints 6
That aside, I'm not sure why you would do that particular operation like that. Why not just return the sum instead of assigning it to a new array element?
function foo(Array $array)
{
return $array;
}
Try
$waffles = foo($waffles);
Or pass the array by reference, like suggested in the other answers.
In addition, you can add new elements to an array without writing the index, e.g.
$waffles = array(1,2,3); // filling on initialization
or
$waffles = array();
$waffles[] = 1;
$waffles[] = 2;
$waffles[] = 3;
On a sidenote, if you want to sum all values in an array, use array_sum()
I always return multiple values by using a combination of list() and array()s:
function DecideStuffToReturn() {
$IsValid = true;
$AnswerToLife = 42;
// Build the return array.
return array($IsValid, $AnswerToLife);
}
// Part out the return array in to multiple variables.
list($IsValid, $AnswerToLife) = DecideStuffToReturn();
You can name them whatever you like. I chose to keep the function variables and the return variables the same for consistency but you can call them whatever you like.
See list() for more information.
i know a Class is a bit the overkill
class Foo
{
private $sum = NULL;
public function __construct($array)
{
$this->sum[] = $array;
return $this;
}
public function getSum()
{
$sum = $this->sum;
for($i=0;$i<count($sum);$i++)
{
// get the last array index
$res[$i] = $sum[$i] + $sum[count($sum)-$i];
}
return $res;
}
}
$fo = new Foo($myarray)->getSum();
Here is how I do it. This way I can actually get a function to simulate returning multiple values;
function foo($array)
{
foreach($array as $_key => $_value)
{
$str .= "{$_key}=".$_value.'&';
}
return $str = substr($str, 0, -1);
}
/* Set the variables to pass to function, in an Array */
$waffles['variable1'] = "value1";
$waffles['variable2'] = "value2";
$waffles['variable3'] = "value3";
/* Call Function */
parse_str( foo( $waffles ));
/* Function returns multiple variable/value pairs */
echo $variable1 ."<br>";
echo $variable2 ."<br>";
echo $variable3 ."<br>";
Especially usefull if you want, for example all fields in a database
to be returned as variables, named the same as the database table fields.
See 'db_fields( )' function below.
For example, if you have a query
select login, password, email from members_table where id = $id
Function returns multiple variables:
$login, $password and $email
Here is the function:
function db_fields($field, $filter, $filter_by, $table = 'members_table') {
/*
This function will return as variable names, all fields that you request,
and the field values assigned to the variables as variable values.
$filter_by = TABLE FIELD TO FILTER RESULTS BY
$filter = VALUE TO FILTER BY
$table = TABLE TO RUN QUERY AGAINST
Returns single string value or ARRAY, based on whether user requests single
field or multiple fields.
We return all fields as variable names. If multiple rows
are returned, check is_array($return_field); If > 0, it contains multiple rows.
In that case, simply run parse_str($return_value) for each Array Item.
*/
$field = ($field == "*") ? "*,*" : $field;
$fields = explode(",",$field);
$assoc_array = ( count($fields) > 0 ) ? 1 : 0;
if (!$assoc_array) {
$result = mysql_fetch_assoc(mysql_query("select $field from $table where $filter_by = '$filter'"));
return ${$field} = $result[$field];
}
else
{
$query = mysql_query("select $field from $table where $filter_by = '$filter'");
while ($row = mysql_fetch_assoc($query)) {
foreach($row as $_key => $_value) {
$str .= "{$_key}=".$_value.'&';
}
return $str = substr($str, 0, -1);
}
}
}
Below is a sample call to function. So, If we need to get User Data for say $user_id = 12345, from the members table with fields ID, LOGIN, PASSWORD, EMAIL:
$filter = $user_id;
$filter_by = "ID";
$table_name = "members_table"
parse_str(db_fields('LOGIN, PASSWORD, EMAIL', $filter, $filter_by, $table_name));
/* This will return the following variables: */
echo $LOGIN ."<br>";
echo $PASSWORD ."<br>";
echo $EMAIL ."<br>";
We could also call like this:
parse_str(db_fields('*', $filter, $filter_by, $table_name));
The above call would return all fields as variable names.
You are not able to return 'multiple values' in PHP. You can return a single value, which might be an array.
function foo($test1, $test2, $test3)
{
return array($test1, $test2, $test3);
}
$test1 = "1";
$test2 = "2";
$test3 = "3";
$arr = foo($test1, $test2, $test3);
$test1 = $arr[0];
$test2 = $arr[1];
$test3 = $arr[2];
Another way is:
$NAME = "John";
$EMAIL = "John#gmail.com";
$USERNAME = "John123";
$PASSWORD = "1234";
$array = Array ("$NAME","$EMAIL","$USERNAME","$PASSWORD");
function getAndReturn (Array $array){
return $array;
}
print_r(getAndReturn($array));

Categories