in the flat php I can just writing this line like that
if(isset($_POST['MoveString'])){
//code here
}
but in symfony when I write my code like that
if(isset($request->get('MoveString'))){
//my code here
}
I get this error
Compile Error: Cannot use isset() on the result of an expression (you can use "null !== expression" instead)
so what's the wrong aren't they the same result ?
according to this part of isset documentation :
Warning
isset() only works with variables as passing anything else will result
in a parse error.
and where is the result of expression in your code ?
to figure out this, take a quick look at the implementation of Request\get method :
public function get($key, $default = null)
{
if ($this !== $result = $this->attributes->get($key, $this)) {
return $result;
}
if ($this !== $result = $this->query->get($key, $this)) {
return $result;
}
if ($this !== $result = $this->request->get($key, $this)) {
return $result;
}
return $default;
}
and as you can see, for example from the ParameterBag object which is called via $this->attributes property, and you can check the other properties [ query, request ]'s objects too.
$result is returning a result of an expression
public function get($key, $default = null)
{
return array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default;
}
so you simply needs to -as the error explains- to use your statement as follows:
if($request->get('MoveString') !== null){
//my code here
}
or even simpler :
if($request->get('MoveString')){
//my code here
}
In case you want to know if the parameter exists, even with a null value, you can use the has() method instead of get():
if ($request->has('MoveString')){
//my code here
}
Related
If I do a post, I can get content by doing $payload = json_decode($app->request->getBody());
But I cannot understand how request->getBody works in slim.
First, there's a magic method :
public function __get($name)
{
return $this->container->get($name);
}
This will return a Slim\Http\Request object. That's fine for now.
$this->container is the Slim\Helper\Set, and this is the get function :
public function get($key, $default = null)
{
if ($this->has($key)) {
$isInvokable = is_object($this->data[$this->normalizeKey($key)]) && method_exists($this->data[$this->normalizeKey($key)], '__invoke');
return $isInvokable ? $this->data[$this->normalizeKey($key)]($this) : $this->data[$this->normalizeKey($key)];
}
return $default;
}
$this->data[$this->normalizeKey($key)] is the same as $this->data['request'], which is something of type "Closure" (not sure to understand this).
$isInvokable is true, so this is called :
$this->data[$this->normalizeKey($key)]($this)
What is this line doing ? Why the ($this) (Slim\Helper\Set) at the end ?
Especially, why the next function to be called is this :
public function singleton($key, $value)
{
$this->set($key, function ($c) use ($value) {
static $object;
if (null === $object) {
$object = $value($c);
}
return $object;
});
}
Why singleton($key, $value) ?
It has never been called !
$key is not defined at the start of the function. Also what makes $c a Slim\Helper\Set, and $value a closure ?
And why the execution of only static $object makes the $object goes from unitialized to one of type Slim\Http\Request ?
Disclaimer: I'm not familiar with Slim. I'm just going by what you've posted.
Well, the Set->get() method tests, if the value in the data property array with the key $key can be invoked, and then does it, if true.
So $this->data[$this->normalizeKey($key)]($this) is calling a method with $this given as parameter and then Set->get() returns that method's return value.
A closure is also often called an "anonymous function", which is a new feature as of PHP 5.3. Using an array as variable to call a function is available since PHP 5.4.
It allows you to pass around functions/methods as values, which is arguably the distinctive feature in functional programming.
Function singleton is called before in the initialization.
It is setting all $key to a function.
So, $this->data[$this->normalizeKey($key)]($this) is that function !
Novice question but then I am a novice at this...
I have a class for registering users and I have functions for different validation. Basically, I run "mainTest" which pulls in the variables from a form and then runs each function (test1, test2). Within those functions if something doesn't validate within the function I set a variable called $error to true. What I am trying to do within the "mainTest" function check if the variable $error has been set to true in any of the other functions do something but when I echo the $error variable it just says null i.e. the functions aren't linking. (trying not to use Global Variables).
Any Ideas here is an example of how I am doing this...
class myClass {
private function test1($var1, $var2) {
if....
else {
$error = true;
return $error;
}
}
private function test2($var3, $var4) {
if....
else {
$error = true;
return $error;
}
}
public function mainTest($var1, $var2, $var3, $var4) {
$this->test1($var1, $var2);
$this->test2($var3, $var4);
if ($error == true) {
//do something
}
}
}
use an instance variable in the class ie..
class myClass {
private $error = '';
function test2()
{
//some code here
$this->error = true;
return $this->error;
}
Now you can access the error variable in other function using the $this keyword
$this->error, here's a little reading
From what you have submitted in the way of code, all of your functions return a boolean. This means that inside of your mainTest you can do something like this:
$error = test1() || test2();
This means that if either of test1 or test2 return true, error will be set to true. But if they both fail, error is false. You can use the || operator any number of times, take my trivial example for instance:
function one(){
return false;
}
function two(){
return false;
}
function three(){
return false;
}
$var = one() || two() && three();
var_dump($var);
In this example, var will be a boolean variable set to false. However, if any one of the three functions returned true, var would of corse be true.
With this, you are semantically saying "the result of one OR the result of two OR the result of three." With || true takes precedence over false, meaning that is anything is true, the end result is true.
In your example, the problem with using the class variable approach as others have suggested, is that, what if test1() sets error to true and then test2() later sets it to false. This can of corse be overcome, however it would require more logic in your mainTest function. Essentially you would need to check the value of error after each function.
Since you're returning the TRUE boolean, you can check to see each function's output to see if it's TRUE, or not:
public function mainTest($var1, $var2, $var3, $var4) {
if ($this->test1($var1, $var2) === TRUE) || $this->test2($var3, $var4) === TRUE) {
// an error occurred, because your function returned a TRUE boolean
}
}
If you'd want to re-structure your code, you can declare a public variable as part of your class and set it using your functions.
class myClass {
// ...
private $error;
private function test1($var1, $var2) {
if....
else {
$this->error = true;
}
}
// ...
public function mainTest($var1, $var2, $var3, $var4) {
$this->test1($var1, $var2);
$this->test2($var3, $var4);
if ($this->error === TRUE) {
// an error occurred
}
}
}
I sometimes have variables that might not be set and I would like to use a default parameter instead. Like here:
if ($p == "a") doSomething();
If $p is not defined PHP throws Notice: Undefined variable. To avoid this I often I used this construct in such a case:
$p = (isset($p) ? $p : "");
But that is ugly if you have to use it a lot. So I wrote a function for it:
function getIfSet(&$value, $default = '')
{
return isset($value) ? $value : $default;
}
// Example
if (getIfSet($p) == "a") doSomething();
I wonder if there is a PHP function for this or how you solve this.
Just a little improvement, prefer passing null value to $default, passing empty string can be confusing, cause correct value can be empty string.
function getIfSet(&$value, $default = null)
{
return isset($value) ? $value : $default;
}
$p = getIfSet($p);
isset() is about as clean as it gets. Although I must admit that I'm not too fond of defaulting to an empty string, simply because a variable could be an empty string, yet still "be set". I think that a default of bool false or null would be truer to the behavior of isset:
function getIfSet(&$value, $default = false)
{
return isset($value) ? $value : $default;
}
$p = getIfSet($p);
if($p !== false){
//insert or whatever
}
else{
header('Location: error.php');
exit;
}
Depending on what kind of values you're checking (maybe REQUEST data?), consider using classes. They are fun and they could be available anywhere.
Assuming you're checking POST data (if you don't, well, take this as an idea), create a class that checks this array:
class Post
{
public function __get($index)
{
if (isset($_POST[$index]))
return $_POST[$index];
else
return null;
}
}
As simple as that. You know that __get() will trigger when you try to access a non-existant property. In this case, if the property (actually, the index in the $_POST array) doesn't exist, null will be returned and no errors are generated.
Now you can do:
$params = new Post();
$foo = $params->name ?: ''; // of course this doesn't make much sense.
if (!$params->password) ...
// instead of
if (isset($_POST['password'])) ...
// you'll still have to use isset for cases like:
if (isset($_POST['user']['password']) ...
if (isset($params->user['password'])) ...
// but still looks neater I'd say
A problem you'll find soon is that $params isn't a super global variable, while $_POST are. How to solve this? Create it in the constructor of your controller class and use Dependency Injection for all other objects your are using.
I tried to make renocor's answer more clean and OOP when I came up with this solution:
class NiceArray implements ArrayAccess {
protected $array;
public function __construct(&$array) {
$this->array =& $array;
}
public function offsetExists($offset) {
return true;
}
public function offsetGet($offset) {
if (isset($this->array[$offset]))
{
return $this->array[$offset];
}
else
{
return null;
}
}
public function offsetSet($offset, $value) {
$this->array[$offset] = $value;
}
public function offsetUnset($offset) {
unset($this->array[$offset]);
}
}
Usage:
$get = new NiceArray($_GET);
if ($get['p'] == "a") doSomething();
I know the class is kind of big but this way you still have an array and you can easily use it for every array you want. You do not need to change any code you may had before. You can still access and change the data. It will even change the original array.
I am in need of a PHP function to check that a variable exist or not outside of function. If it does not exist, then assign a default value to it.
The function will be something like: function if_exist($argument, $default = '') where $argument will be any variable outside the function. It can be a variable's variable, and $default will be the default value of the variable if the variable doesn't exist.
Please avoid using global scope in the function, because I heard that it's not good for a site's security.
You can make $argument pass-by-reference:
function if_exist(&$argument, $default="") {
if(!isset($argument)) {
$argument = $default;
return false;
}
return true;
}
DEMO
I don't see why you want a function for this at all.
$a = isset($a) ? $a : "my default string";
Everybody will understand what your code does without resorting to little-known "features" of PHP and having to look at your functions body to see what it does.
Even though it may look like a function call, it's not. isset() is a language construct! That's why it will not raise a Notice.
There are two ways of going at this. You may be looking for the first non-null value or if the actual variable is set or not...
The first use-case is easy... To get the value of the first variable that isn't null, define a function as such:
function coalesce() {
$args = func_get_args();
if(is_array($args))
return null;
foreach($args as $arg) {
if($arg !== null)
return $arg;
}
return null;
}
Using this function is easy. Simply call coalesce() with a number of different arguments and it will always return the first non-null value it encounters.
$myVar = coalesce($myVar, null, 'Hello There', 'World');
echo $myVar; // Hello there
However, if you are looking for a function to check if a variable is defined, and if it isn't define it, then you need to create a function which forces the first argument to be a reference.
function set_default(&$variable, $defaultValue = null) {
if(!isset($variable)) {
$variable = $defaultValue;
return false;
}
return true;
}
Use this:
function setGlobalIfNotSet( $variableName, $defaultValue = false ) {
if ( ! isset( $variableName )) {
global $$variableName;
$$variableName = $defaultValue;
}
}
You can make a function to use isset:
function isset_default($v, $default = '') {
return isset($v) ? $v : $default;
}
Usage:
$v = isset_default($v, 'somedefaultvalue');
Alrighty, I'm getting quite frustrated, namely because I thought I had this issue solved, or had accomplished this successfully before.
Quick preliminary:
PHP 5.3.6.
Error reporting cranked to 11. (-1 actually; future safe, all errors/notices)
I have a class, it aggregates request parameters. For giggles here is a stripped down version:
class My_Request{
private $_data = array();
public function __construct(Array $params, Array $session){
$this->_data['params'] = $params;
$this->_data['session'] = $session;
}
public function &__get($key){
// arrg!
}
}
Anyways, the reason for arrg! is, no matter what I try, I always get an error whenever the $key doesn't exist. I've tried:
// doesn't work
$null = null;
if(isset($this->_data[$key])){ return $this->_data[$key]; }
return $null;
// doesn't work
return $this->_data[$key];
I've been told ternary operators cannot result in a reference, ergo, that of course doesn't work, but we know that from the if condition attempt anyways. What happens, for example:
// params will have foo => bar, and session hello => world
$myRequest = new My_Request(array('foo' => 'bar'), array('hello' => 'world'));
// throws an error - Undefined index: baz
echo $myRequest->params['baz'];
I'm losing my mind here; perhaps I hallucinated a scenario where I achieved this. Is it not possible to (without throwing a notice) successfully do this?
Clarification: Things I've tried
The aforementioned:
// no check, no anything, just try returning : fails
public function &__get($key){
return $this->_data[$key];
}
// null variable to pass back by reference : fails
public function &__get($key){
$null = null;
if(isset($this->_data[$key])){
return $this->_data[$key];
}
return $null;
}
Other attempts:
// can't work - can't return null by reference nor via ternary : fails
public function &__get($key){
return isset($this->_data[$key])
? $this->_data[$key]
: null;
}
echo $myRequest->params['baz'];
The isset check in your __get function will look up "params" from $this->_data and return the array. The notice you get is from outside the class and about a key "baz" in the returned array - which in your example was never actually defined.
I realize this question is stale, but I just stumbled on it via Google while looking for the answer (which I have since found).
class My_Request{
private $_data = array();
public function __construct(Array $params, Array $session){
$this->_data['params'] = $params;
$this->_data['session'] = $session;
}
public function &__get($key){
if (array_key_exists($key, $this->_data)) {
return &$this->_data[$key]; // Note the reference operator
} else {
$value = null; // First assign null to a variable
return $value; // Then return a reference to the variable
}
}
}
$this->_data[$key] is an operation that returns a value, so returning the value will result in an error because it's not a reference. To make it return a reference instead, you have to use the reference: &$this->_data[$key].
Haven't tried this because I avoid __get and __set, but maybe this would work for you:
public function __get($key){
if(!isset($this->_data[$key]))
return false;
return $this->_data[$key];
}
Totally untested, but it looks like it could maybe do the job.