PHP Function Array Default Values? [duplicate] - php

This question already has answers here:
PHP function with variable as default value for a parameter
(7 answers)
Closed 1 year ago.
I have a PHP function with a array within. I put the array inside so the parameters would be option and these would be the defaults. Example
/**
* Creates New API Key
*
* #return Response
*/
public function create(
$data = [
"user-id" => Auth::id(),
"level" => '1',
"ignore-limits" => '0',
]){
...
}
However I keep getting the error
syntax error, unexpected '(', expecting ']'
So I assume that you cant pass a array like this when constructing a function. What would be a better way to do this or a fix?

You can only use scalar types for the default values of function arguments.
You can also read this in the manual: http://php.net/manual/en/functions.arguments.php#functions.arguments.default
And a quote from there:
The default value must be a constant expression, not (for example) a variable, a class member or a function call.
EDIT:
But if you still need this value as default value in the array you could do something like this:
Just use a placeholder which you can replace with str_replace() if the default array is used. This also has the advantage if you need the return value of the function in the default array multiple times you just need to use the same placeholder and both are going to be replaced.
public function create(
$data = [
"user-id" => "::PLACEHOLDER1::",
//^^^^^^^^^^^^^^^^ See here just use a placeholder
"level" => '1',
"ignore-limits" => '0',
]){
$data = str_replace("::PLACEHOLDER1::", Auth::id(), $data);
//^^^^^^^^^^^ If you didn't passed an argument and the default array with the placeholder is used it get's replaced
//$data = str_replace("::PLACEHOLDER2::", Auth::id(), $data); <- AS many placeholder as you need; Just make sure they are unique
//...
}
Another idea you could do is set a default array which you can check and then assign the real array like this:
public function create($data = []){
if(count($data) == 0) {
$data = [
"user-id" => Auth::id(),
"level" => '1',
"ignore-limits" => '0',
];
}
//...
}

The issue here is the:
Auth::id()
This calls a method which is illegal to do in this context
I would solve it like this:
public function create(
$data = [
"user-id" => -1,
"level" => '1',
"ignore-limits" => '0',
]){
if($data['user-id'] === -1) {
$data['user-id'] = Auth::id()
}
...
}

More universal solution with array_mearge. This way you can rewrite any parameter without having to check each of them individually.
function create($somthing, $settings = [])
{
$default = [
'date' => date("Y-m-d H:i:s"),
'bold' => false,
'italic' => false,
];
$settings = array_merge($default, $settings);
...
}

Related

Array destructuring assignement with optional values

Is there any solution in PHP to make an array destructuring assignment with associative keys can extract optional values/default values (like the example below)?
Because when I tried, I always get undefined index 'age' (it's because it is not set).
See example:
// implementation
function myFunction(array $params = ['name' => 'user-name', 'age' => 15]){
['name' => $name, 'age' => $age ] = $params;
echo $name.' '.$age;
}
// Execution:
// normal case
myFunction(['name' => 'user', 'age' => 100]);
// Output: user 100
// Wanted case to be released
myFunction(['name' => 'user']);
// Output: user 15 <== i want to get this default age value if i don't set it in the given associative array params.
What about defining an array with default values?
function myFunc(array $params, array $defaults = [ 'name' => 'Marcel', 'age' => 40 ]): string
{
$data = array_merge($defaults, $params);
[
'name' => $name,
'age' => $age
] = $data;
return $name . $age;
}
The array merge overwrites the default values with the given param values. So the return will always be a complete mixture of both values. If you send a name only, the name will be mixed up with the default age. If you give an age only, the age will be mixed up with the default value.
myFunc([ 'name' => 'sohaieb', 'age' => 15 ]); // => sohaieb15
myFunc([ 'name' => 'yadda' ]); // => yadda40
The second parameter $defaults can be changed, if the defaults change in the future. A possible scenario: You set the default values in a config. With this solution the function can take the default settings from the config and don 't has to be touched in the future.
Well, since you pass in a parameter, it will always take that instead of the default one. However, you can use the union operator + to merge it with default values if not present in the originally supplied value during function call.
<?php
function myFunction(array $params = []){
$params = $params + ['name' => 'user-name', 'age' => 15];
['name' => $name, 'age' => $age ] = $params;
echo $name.' '.$age;
}
myFunction(['name' => 'user']);
Because $params is an array, so it overrides the default values even if you pass in an empty array.
One way to do this is to check the value inside your function body.
function myFunction(array $params){
$name = $params['name'] ?? 'user-name';
$age = $params['age'] ?? 15;
echo $name.' '.$age;
}
// Execution:
// normal case
myFunction(['name' => 'user', 'age' => 100]);
// Output: user 100
// Wanted case to be released
myFunction(['name' => 'user']);
Reference
https://wiki.php.net/rfc/isset_ternary

Doctrine 2 DBAL expressions in update or insert methods

I like the convenience methods for data manipulation queries $conn->insert() and $conn->update() in doctrine 2 DBAL because insert/update values can be held an passed as associative array. But how can i pass a NULL value, a MySQL function or other expressions as value?
E.g:
/* $conn is a \Doctrine\DBAL\Connection object */
$conn->update('person', array('phone' => 'NULL'), array('id' => 1));
$conn->update('person', array('lastlogin' => 'NOW()'), array('id' => 1));
$conn->update('person', array('visit' => 'visit + 1'), array('id' => 1));
These function calls would create prepared statements like
UPDATE person SET phone = ? WHERE id = ?
and thus the values would be treated as strings.
Is there a way to make this work using this technique?
There is an optional $types argument, which defaults to an empty array:
public function update($tableExpression, array $data, array $identifier, array $types = array())
The $types array can contain PDO type constants which will change how the corresponding $data values are treated.
So I'd try:
$conn->update(
'person', // $tableExpression
array('phone' => null), // $data
array('id' => 1), // $identifier
array('phone' => \PDO::PARAM_NULL) // $types
);

Insert object into array

i have an array in php full of "Eventos Calendario" objects, at some point in my script i need to introduce a new object of the same type at position x of this array. this is the code i am using
$EventoLimite = new EventosCalendario(null,$Timestamp, $TipoEvento);
var_dump($EventoLimite);
array_splice($this->EventosEntrada, $i, 0, $EventoLimite); //
var_dump($this->EventosEntrada[$i]);
And the "Var_Dumps" i am getting are:
object(EventosCalendario)[15]
public 'FechaHora' => int 1376334000
public 'FechaHoraOriginal' => null
public 'Tipo' => string 'Entrada' (length=7)
public 'Origen' => string 'Insertado' (length=9)
public 'Subtipo' => null
public 'ID' => null
int 1376334000
Why is the new slot in the array only getting the value of "FechaHora" property? i need to get the whole object in $this->EventosEntrada[$i]. how can i do that??
The "replacement" argument must be an array itself, so you should write
array_splice($this->EventosEntrada, $i, 0, [$EventoLimite]); // note []s
maybe its because of that when you introduce a new object, just public variables and functions are available in the specific file you work on. I mean it is cause by access of clsasses.

How print array if he created in function? [duplicate]

This question already has answers here:
Multiple returns from a function
(32 answers)
PHP: Is it possible to return multiple values from a function? [duplicate]
Closed 8 years ago.
Arrays created in function test().
Then I would like print their on page test.php.
My code down:
conf.php
function test(){
$str= array(
'items' => array(
0 => array(
'title' => 'Title',
'category' => 'Category name',
),
1 => array(
'title' => 'Title',
'category' => 'Category name',
),
),
'details' => array(
'firstname' => 'firstname',
'lastname' => 'lastname',
),
'Id' => $Id,
'OrderId' => 'fsdfsfdsrew'
);
$json = json_encode($str);
$base64 = base64_encode($json);
$sig = signMessage($base64, $secretPhrase);
}
test.php
require_once("conf.php");
test();
print_r($str);
print_r($json);
print_r($base64);
print_r($sig);
Tell me please why code not worked?
Tell me please why weren't printed $str, $json, $base64, and $sig?
How do it?
Preferably without global parameters.
You can't without returning them as the function return value. In PHP, variables declared in a function (the arrays you're trying to print_r in this case) are only available within the scope of that function unless you declare them global with the global keyword.
Here's the details on variable scope in PHP: http://php.net/manual/en/language.variables.scope.php
You could construct a larger array to contain these arrays and return them from the test() function:
function test(){
//function code here....
////...
$results = array('str'=> $str,
'json'=> $json,
'base64'=>$base64,
'sig' => signMessage($base64, $secretPhrase)
) ;
return $results;
}
Then call it like this:
$results = test();
print_r($results['str']);
print_r($results['sjson']);
print_r($results['base64']);
print_r($results['sig']);
Many ways to do that:
first, you have to return the value if you want use on other class.
on your test you can do:
$something = new Conf();
$someelse = $something->test();
echo $someelse;

Array lookup value from dynamic string

I'm trying to build a dynamic associative array value lookup function (within a class):
class Family
{
public static $members = array(
'one' => array(
'child' => 0,
'children' => 5
),
'two' => array(
'child' => 2,
'children' => null
)
);
public static function resolveMemberValue()
{
$chain = func_get_args();
$lookup = 'members' . '[\'' . implode('\'][\'', $chain) . '\']';
var_dump( $lookup );
return static::$$lookup;
}
}
Family::resolveMemberValue('one', 'child');
But this results in:
string(23) "members['one']['child']"
Fatal error: Access to undeclared static property: Family::$members['one']['child'] in /family.php on line 23
PHP Fatal error: Access to undeclared static property: Family::$members['one']['child'] in /family.php on line 23
Though, copying the dumped value, and pasting inside the script + appending dollar sign, it returns what's expected:
var_dump( Family::$members['one']['child'] );
int(0)
Reason why I need this is, because it will be used with multiple variables, and called from generator functions.
What is wrong with the snippet?
Variable variables only substitutes in a string for the name of the variable. It can't evaluate the content of that string (in this case the string members['one']['child'])
Your code is looking for a static property literally with the named $members['one']['child'] not an element of the static array $members.
Try this instead:
$member = static::$members[$chain[0]];
return $member[$chain[1]];
Also, I'd recommend not using func_get_args(), but explicitly naming your parameters in the method declaration. Some features of PHP a best left behind....
Oh, had to just tinker a little - managed to make a helper function.
The function replaces the implode() and the explicit key definition.
function array_lookup()
{
$chain = func_get_args();
$array = array_shift($chain);
foreach ($chain as $key) $array = $array[$key];
return $array;
}
$test = array(
'one' => array(
'child' => 0,
'children' => 5
),
'two' => array(
'child' => 2,
'children' => null
)
);
var_dump($test, 'one', 'child'); // int(0)
I have left out any kind of error checking for this example, but it does what I was looking for.
And yes, for my example, it nails it.

Categories