I do this to test and get session attribute in my code :
if ($session->has("myVar")) {
$myVar = session->get("myVar");
/* do something */
}
But, I read the code of session and :
/**
* Returns an attribute.
*
* #param string $name The attribute name
* #param mixed $default The default value if not found.
*
* #return mixed
*
* #api
*/
public function get($name, $default = null);
So, if the session attribute is not find, get return "null".
if ($myVar = $session->get("myVar")) {
/* do something */
}
Or better with false, if you have "myVar" but empty, you can't rely on "null" :
if ($myVar = $session->get("myVar", false)) {
/* do something */
}
according to : Null vs. False vs. 0 in PHP
I think the third is the best, one call to $session->get, instead of has and get in my actual code.
I read about alternative comparaison with ternary operator, http://fabien.potencier.org/article/48/the-php-ternary-operator-fast-or-not, I don't use it, mostly because I.m not familiar with, but, if it's not faster, I don't need it.
Can you confirm, third is the best, and if it's not, why, and how to do best ?
That depends on what you want to achieve.
First Option
if ($session->has("myVar")) {
$myVar = session->get("myVar");
/* do something */
}
Makes sense if you want to make sure, that this var is set, and if not you actually want to set it or do anything else. It presumes that having this session variable present is a necessity
Second Option
$myVar = $session->get("myVar");
This one makes sense, if you are comfortable receiving the expected result or a null value as default if not set.
Recommendation:
$myVar = $session->get("myVar");
if (null === $myVar) {
/* do something */
}
Third Option
$myVar = $session->get("myVar", false);
This one simply allows you to override the default value if this session variable is not set
Recommendation:
$myVar = $session->get("myVar", false);
if (!$myVar) {
/* do something */
}
So, in my opinion it depends what you want to do. But there is no best or worst way as you asked for, since they all differ from each other.
Related
I have the following code:
$request->headers->get('Accept-Language', 'en');
I provide a default value but Psalm thinks it's potentially null since ->get() declares that return a nullable string:
// vendor/symfony/http-foundation/HeaderBag.php
/**
* Returns a header value by name.
*
* #return string|null The first header value or default value
*/
public function get(string $key, string $default = null) { /* */ }
How can I fix this so psalm knows it's not null?
Since you cannot control the annotation in the upstream library, you'll have to provide the missing information to Psalm in your own code.
A couple of ways to go about it:
Cast to string, so Psalm has no doubt what type get() is getting you:
$a = (string) $request->headers->get('Accept-Language', 'en');
Yup, the cast is redundant, but it's clear and concise. I usually do this just for economy.
You could explicitly declare that the variable that result of this get() call is a string:
/** #var string $acceptLanguage **/
$acceptLanguage = $request->headers->get('Accept-Language', 'en');
Finally, you can simply suppress the PossiblyNullArgument wherever you need it:
/** #psalm-suppress PossiblyNullArgument */
iWantAString($request->headers->get('Accept-Language', 'en'));
See all these working here.
You can also combine some of the above with your own wrapper method to deal with getting values from the request, making sure you always return string. If you do that, you should probably throw an exception if the parameter is not found.
In addition to #yivi's answer that shows you how you can override type inference or suppress the error, you can also explain the type to Psalm by providing correct docblock using conditional types either directly in the source code (if you have control over that) or in a stub file.
/**
* Returns a header value by name.
*
* #psalm-return ($default is null ? (string|null) : string)
*/
public function get(string $key, string $default = null) { /* */ }
https://psalm.dev/r/41b8471847
What can I use other than if(!empty( $product->a_funky_function() )) to check if the method is empty before calling it?
I've tried method_exists() and function_exists() and a whole plethora of conditions. I think the issue is that I need to have my $product variable there.
Please help.
A fairly common pattern is to have two methods on your class, along the lines of getField and hasField. The former returns the value, and the latter returns true or false depending whether or not the value is set (where "set" can mean not null, or not empty, or whatever else you might want it to mean).
An example:
class Foo
{
/** #var string */
private $field;
/**
* #return string
*/
public function getField()
{
return $this->field;
}
/**
* #return bool
*/
public function hasField()
{
return $this->getField() !== null;
}
}
This would then be used like:
if ($foo->hasField()) {
$field = $foo->getField();
...
}
Often, like in this example, the has... method often just delegates to the get... method internally, to save duplicating the logic. If the getter contains particularly heavy processing (e.g. a database lookup or API call), you might want to factor in ways to avoid performing it twice, but that's a bit out of scope.
You need absolutely to call it so it can compute the value which it will return, so I think there is no other way to know if it will return something not empty without calling it...
You have to call it.
$result = $product->getFunction();
if(!empty($result)) {
//your code here
}
Using cakephp 3, I have a boolean [tinyint(1)] in a table, and the edit and add templates have a check box on the form, but how do I get the index and view templates to display a string like true/false or yes/no instead of 1/0. Do I map them over in the controller actions, or is there a option I can add to the templates?
The answers given both work fine.
I created a Helper class in /src/View/Helper/FormatBooleanHelper.php as below:
<?php
/*
* FormatBooleanHelper
*
* CakePHP Helper created to format boolean values in either Yes/No or True/False text.
* By: Jared Testa
*
*/
namespace App\View\Helper;
use Cake\View\Helper;
class FormatBooleanHelper extends Helper
{
/**
* yesNo method
*
* #param boolean| $value boolean
* #return string
*
*/
public function yesNo($value, $showNo = true) {
return ($value) ? "Yes" : (($showNo) ? "No" : "");
}
/**
* trueFalse method
*
* #param boolean| $value boolean
* #return string
*
*/
public function trueFalse($value, $showFalse = true) {
return ($value) ? "True" : (($showFalse) ? "False" : "");
}
}
?>
The helper is used in the standard convention by including $this->loadHelper('FormatBoolean'); in your initialize method in the AppView.php file.
You then use the Helper in your view by including $this->FormatBoolean->yesNo($booleanVariable) or $this->FormatBoolean->yesNo($booleanVariable, false) in your view. The latter example will leave the field blank in a false response.
Overkill? Perhaps...but I think it fits into the CakePHP structure, and it was a good exercise in creating your own helper.
I'm using the helper in CakePHP version 3.3.4. Hope this helps someone in the future.
simply:
<?= ($var)?'yes':'no' ?>
When you go in to display the data you can choose to display a string instead of the int. This is a simplified approach since you didn't provide any code or other information:
In the view, $isTrue being the boolean:
<?php if($isTrue){echo "true";}else{echo "false";} ?>
I added (for bottom, jtesta answer) method to get graphically representation - "check" or "x" using Foundation Icon Fonts 3:
public function checkX($value, $showFalse = true) {
return ($value) ? '<i class="fi-check"></i>' : (($showFalse) ? '<i class="fi-x"></i>' : '');
}
Image how it loks like
I have recently started with learning Swift for iOS development. I have a background in scripting languages, especially PHP. Seeing that it is emphasized using let to define a constant in favor of var to have the compiler optimize the resulting code, I wondered: is there an equivalent for PHP? Or does it simply not apply as PHP is not statically compiled?
I tried my luck at searching but found no satisfying information on that point.
No, you can't have locally scoped constants in PHP. All PHP constants are always globally visible. There is also no concept like immutable/mutable variables.
You can implement immutable object members (PHP: immutable public member fields), but it's a different thing.
Actually there is a const keyword in the language, but the docs say:
Note:
As opposed to defining constants using define(), constants defined using the const keyword must be declared at the top-level scope because they are defined at compile-time. This means that they cannot be declared inside functions, loops, if statements or try/ catch blocks.
(from http://php.net/manual/en/language.constants.syntax.php)
Interpreted languages with a dynamic type systems can have something like the swift let statement, so this is not because swift is compiled and PHP is interpreted (for example, there is a javascript proposal to introduce that feature: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/const)
Is there an equivalent of “let” vs. “var” in PHP?
PHP doesn't have let as a native language feature, yet (as of current version 7.1.4 - 04/2017)
But, some high-performance extensions like Phalcon and Ice have support for let, because of the underlying usage of zephir-lang.
So, there is let, but indirectly; using the above mentioned extensions.
There are two use cases:
define a variable from a super global
define a variable in the local PHP symbol table, e.g.
// set variable $price in PHP
let name = "price";
let {name} = 10.2;
As an example take a look at the source for the Ice Router:
namespace Ice\Mvc\Route;
use Ice\Mvc\Route\Parser\ParserInterface;
use Ice\Mvc\Route\DataGenerator\DataGeneratorInterface;
use Ice\Mvc\Route\Parser\Std;
use Ice\Mvc\Route\DataGenerator\GroupCount as Generator;
class Collector
{
private routeParser { set };
private dataGenerator { set };
/**
* Constructs a route collector.
*
* #param RouteParser $routeParser
* #param DataGenerator $dataGenerator
*/
public function __construct(<ParserInterface> routeParser = null, <DataGeneratorInterface> dataGenerator = null)
{
if !routeParser {
let routeParser = new Std();
}
if !dataGenerator {
let dataGenerator = new Generator();
}
let this->routeParser = routeParser,
this->dataGenerator = dataGenerator;
}
/**
* Adds a route to the collection.
*
* The syntax used in the $route string depends on the used route parser.
*
* #param string|array $httpMethod
* #param string $route
* #param mixed $handler
*/
public function addRoute(var httpMethod, string route, handler = null)
{
var routeDatas, routeData, method;
let routeDatas = this->routeParser->parse(route);
if typeof httpMethod == "string" {
let method = httpMethod,
httpMethod = [method];
}
for method in httpMethod {
for routeData in routeDatas {
this->dataGenerator->addRoute(method, routeData, handler);
}
}
}
/**
* Returns the collected route data, as provided by the data generator.
*
* #return array
*/
public function getData()
{
return this->dataGenerator->getData();
}
}
Is there a syntax for documenting functions which take a single configuration array, rather than individual parameters?
I'm thinking specifically of CodeIgniter-style libraries, which use a mechanism similar to this:
<?php
//
// Library definition
//
class MyLibrary {
var $foo;
var $bar;
var $baz;
// ... and many more vars...
/* Following is how CodeIgniter documents their built-in libraries,
* which is mostly useless. AFAIK they should be specifying a name
* and description for their #param (which they don't) and omitting
* #return for constructors
*/
/**
* #access public
* #param array
* #return void
*/
function MyLibrary($config = array()) {
foreach ($config as $key => $value) {
$this->$key = $value;
}
}
}
//
// Library usage:
//
// Iniitialize our configuration parameters
$config['foo'] = 'test';
$config['bar'] = 4;
$config['baz'] = array('x', 'y', 'z');
$x = new MyLibrary($config);
?>
So my question is, is there some supprted way of documenting the configuration array beyond just the purely textual description? Actually specifying a proper #param [type] [name] [desc] that allows PHPDoc to parse out useful values?
As an aside, CodeIgniter really does just overwrite it's own values with those passed in via the $config array as above, effectively allowing you to clobber private members. I'm not a fan, but I'm stuck with it.
I've never seen any "good" way of documenting this -- and I've never seen anything that could be used by IDEs (such as Eclipse PDT) for parameters hinting either :-(
I would have said "do like your framework does", but as you said, what it does, here, is not quite good enough...
Maybe a quick/sort list of possible keys might be better than nothing, though ; a bit like this :
#param array $config [key1=>int, otherKey=>string]
Not sure how it would be interpreted by phpDocumentor or an IDE... But might be worth a try ?
This is, btw, one reason why I tend to avoid that kind of way of passing parameters -- at least when there are not too many (optional) parameters to a method.
The correct array #param notation for arrays is as specified in PHPlint
You can use it to document a config array in a useful manner:
Example:
/**
* Does stuff
*
* #param array[int|string]array[string]Object $config
*
* #return array[int]string
*/
public function foo(array $config)
{
// do stuff here
return array('foo', 'bar', 'baz');
}
You can do this:
/**
* #param array $param1
* #param string $param1['hello']
*/
function hey($param1)
{
}
and netbeans will pick it up but phpdoc messes up the documentation
I always use <pre> tags in situations like this. Ex.:
/**
* #param array $ops An array of options with the following keys:<pre>
* foo: (string) Some description...
* bar: (array) An array of bar data, with the following keys:
* boo: (string) ...
* far: (int) ...
* baz: (bool) ...
* </pre>
*/
Most IDEs and documentation generators I have used seem to render this in a reasonable way, though of course they don't provide any type checking or inspection of the array parameters.
There is currently no "official" (as in 'supported by multiple tools') way to do this.
The PHP FIG is discussing it at the moment at https://groups.google.com/d/topic/php-fig/o4ko1XsGtAw/discussion
A text description, to whatever degree of completeness you want, is really your only option. You can make it as legible as you want, but code analysis tools (phpDocumentor, IDE support) have no way to know how your $array is actually structured at runtime.
I agree with the many commenters that writing code this way exchanges coding convenience for code legibility.
I've used classes.
<?php
class MyLibrary {
var $foo;
var $bar;
var $baz;
/**
* #param MyLibraryConfig|null $config
*/
function MyLibrary( $config = null ) {
if ( isset( $config->foo ) ) {
$this->foo = $config->foo;
}
if ( isset( $config->baz ) ) {
$this->baz = $config->baz;
}
if ( isset( $config->bar ) ) {
$this->bar = $config->bar;
}
}
}
/**
* #property string $foo
* #property int $bar
* #property array $baz
*/
class MyLibraryConfig {
}
It works fairly well, main problem is that the code becomes littered with specific classes. They can be nested so parts of configuration can be reused.