Function returns Null :: laravel - php

I have a function which gets the value from a database and returns. When I echo, the value does exist. But returned value is null;
public static function getCountryCode($country) {
$country = (int) $country;
$x = Country::where('id', $country)->get();
$country_code = '';
foreach($x as $row)
$country_code = $row->alpha_2;
//return 'bd';
echo $country_code;
return $country_code;
}
Not sure what's wrong in there. It's a laravel project.
Function that is calling this method
public function countryselect()
{
$country_id = HomeController::detectCountry();
$country_code = SiteController::getCountryCode($country_id);
var_dump($country_code);
return View::make('Layout.countryselect', compact('country_id', 'country_code'));
}

You don't have to use "foreach" function. You can get country code in much easier way. Just make some changes in getCountryCode() like
public static function getCountryCode($countryId) {
$countryId = (int) $countryId;
$country = Country::where('id', $countryId)->get()->first();
return $country->code;
}
This will return the country code of specified country id. Use descriptive name for variable like you used for the function

Related

how to instantiate an object even if not all parameters are passed to the constructor

I'm trying to make it possible to create an instance of an object even if I enter one parameter out of two.
Here is what i did :
class BMW implements iCars
{
private $_price;
private $_weight;
function __construct($price, $weight)
{
$this->_price = $price;
$this->_weight = $weight;
if ($weight === null) {
$weight = "4242";
}
}
function setPrice()
{
return $this->_price;
}
function setWeight()
{
return $this->_weight;
}
function getPrice()
{
return $this->_price;
}
function getWeight()
{
return $this->_weight;
}
}
I need to be able to create an instance if I put the weight and price in parameters, or just the price.
You can either just add null for of the argument when instantiating the object, e.g.:
$car = new BMW(123, null);
Demo: http://sandbox.onlinephpfunctions.com/code/46cd960eff0530c0d0a3a384fe426cae4022523f
or you can change the constructor definition to make the second parameter optional (by using default parameter arguments):
function __construct($price, $weight = null)
{
$this->_price = $price;
$this->_weight = $weight;
//...
}
//....
$car = new BMW(123);
Demo: http://sandbox.onlinephpfunctions.com/code/27970a41be1ff259d112a8a1a5db0d25c940092d
N.B. extra note: I suspect that
$weight = "4242";
in the if statement in the constructor is probably not what you intended - it will only set the incoming $weight variable, which will be lost when the constructor finishes. I imagine you really intended to set the property on the object e.g.
$this->_weight = 4242;
(Note I also removed the quote marks, as it's a number, not a string.)
Try changing your constructor to:
function __construct($price, $weight = null)
{
$this->_price = $price;
$this->_weight = $weight;
if ($weight === null) {
$weight = "4242";
}
}
Adding the = null at the parameters, will set them to a default value if you do not pass a value.
So $car = new BMW(25000); will work without a error.
Edit: If you always want 4242 as default value, you can add this in the constructor signature.
function __construct($price, $weight = "4242")
{...}
$car = new BMW(123);
echo $car->getWeight();
//Will echo 4242
You won't need the if ($weight == null) anymore.

PHP - Generate Functions from array of string

In my application i need many getter and setter and my idea was to generate them from an array, for example:
protected $methods = ['name', 'city'];
With this two parameters, i will need to generate the following methods:
public function getNameAttribute() {
return $this->getName();
}
public function getName($lang = null) {
return $this->getEntityValue('name', $lang);
}
And for city, the method will be:
public function getCityAttribute() {
return $this->getCity();
}
public function getCity($lang = null) {
return $this->getEntityValue('city', $lang);
}
Sure, i should need to generate the setter too (with the same logic).
As you can see, i will need a method with get<variable_name>Attribute and inside this call get<variable_name> and the other (getName) return even the same method (for each getter) and just change the 'name' parameter.
Every method have the same logic and i would like to generate them "dynamically". I don't know if this is possible..
You can leverage __call() to do this. I'm not going to provide a full implementation but you basically want to do something like:
public function __call($name, $args) {
// Match the name from the format "get<name>Attribute" and extract <name>.
// Assert that <name> is in the $methods array.
// Use <name> to call a function like $this->{'get' . $name}().
// 2nd Alternative:
// Match the name from the format "get<name>" and extract <name>.
// Assert that <name> is in the $methods array.
// Use <name> to call a function like $this->getEntityValue($name, $args[0]);
}
Send this params(name, city or other) as parameter to universal method(if you don't know what params you can get)
public function getAttribute($value) {
return $this->get($value);
}
public function get($value, $lang = null) {
return $this->getEntityValue($value, $lang);
}
If you know yours parameters, you can use this:
public function getNameAttribute() {
return $this->getName();
}
$value = 'Name'; //for example
$methodName = 'get' . $value . 'Attribute';
$this->$methodName; //call "getNameAttribute"
Take a look at this and let me know is it your requirement or not.
$methods = ['name', 'city'];
$func = 'get'.$methods[1].'Attribute';
echo $func($methods[1]);
function getNameAttribute($func_name){
$another_func = 'get'.$func_name;
echo 'Name: '.$another_func();
}
function getCityAttribute($func_name){
$another_func = 'get'.$func_name;
echo 'City: '.$another_func();
}
function getCity(){
return 'Dhaka';
}
function getName(){
return 'Frayne';
}

$_GET and static in PHP

I get for example name=carl from the url in FooStatic and want to initiate the $Name with Carl so I can use it from another function. Can I do that? Or is there some other better way to do that?
class Foo {
private static $Name = "name";
public static function FooStatic(){
if (isset($_GET["name"])){
self::$Name = $_GET["name"];
return true;
} else {
return false;
}
}
I am using the name to get more info from another class
public static function getSomething() {
if (isset($_GET[self::$Name])) {
$name = $_GET[self::$Name];
$ret = $someClass->Foo($name);
return $ret;
}
}
The GET-variables are global, so you can always get them from virtually anywhere (if it is in the same span of the execution) if that's what you are asking.

Setting array values in $_SESSION through an accessor method

Can anyone please explain to me why the following code does not set the values on the array as expected? $_SESSION['foo'] stays empty, even after assigning time() and rand(). I've checked, the __get accessor method is actually called when assigning the variables but they aren't stored for one reason or another.
$test = Session::getSession('test');
$test->foo = array();
$test->foo[] = time();
$test->foo['baz'] = rand(1,9);
var_dump($_SESSION);
Using this simple Session wrapper
class Session
{
protected $namespace = null;
public static function getSession($namespace)
{
return new Session($namespace);
}
public static function destroySession($namespace)
{
if(isset($_SESSION[$namespace])) {
unset($_SESSION[$namespace]);
return true;
}
return false;
}
private function __construct($namespace)
{
$this->namespace = $namespace;
if(!isset($_SESSION[$namespace])) {
$_SESSION[$namespace] = null;
}
}
public function &__get($name)
{
return (isset($_SESSION[$this->namespace][$name])) ? $_SESSION[$this->namespace][$name] : null;
}
public function __set($name, $value)
{
$_SESSION[$this->namespace][$name] = $value;
}
}
In case it might be relevant, i'm using php 5.3.6
I 'm not sure if this can be made to work at all.
For one, to return by reference you should add the & operator at the call site as well. I 'm not sure how that might be possible without screwing up the nice syntax you 're trying to achieve.
Also, you cannot return expressions by reference (only variables). So this won't work:
public function &__get($name)
{
return (isset($_SESSION[$this->namespace][$name]))
? $_SESSION[$this->namespace][$name]
: null;
}
At the very least it should be written as
public function &__get($name)
{
$value = isset($_SESSION[$this->namespace][$name])
? $_SESSION[$this->namespace][$name]
: null;
return $value;
}

PHP array references; holding references in an array for later use

I'm trying to hold onto a variable reference for later use.
Not certain this is even possible, but I'm hoping I can initialize an array element, and reference it with a variable. Then, set the value of said array element to something, therefore making the value accessible from the referenced variable.
For example, this works:
class Test{
private $_vars = array();
public function bind($key, &$var){
$this->_vars[$key] = &$var;
return $this;
}
public function fetch($key, &$var){
$var = $this->_vars[$key];
return $this;
}
}
$test = new Test();
$string_set = 'This is a string';
$test->bind('string', $string_set)
->fetch('string', $string_get);
var_dump($string_get);
// expected: string(16) "This is a string"
// actual: string(16) "This is a string"
Now here's the problem; the ordering of method calls. I can't have the call() function returning a reference to $this, as the call() function needs to pass up the return value of the stored anonymous function (otherwise I'd reorder the calls to be ->call()->fetch() instead of ->fetch()->call())
Anyways, the fetch() method should be setting the appropriate element by key in $_vars to NULL (to empty any existing value, or initialize it, whichever) and then referencing that element to the passed $var.
When the anonymous function is called (after the fetch() binding is done), it calls bind(), now binding the element in $_vars to whatever (a $string_set containing This is a string in this case) If my logic is correct, the fetch() bound variable ($string_get in this case) should now reference the array element in $_vars which is referencing $string_set which contains This is a string.
Doesn't seem that way though. Here's the code that's failing (stripped down for brevity, but all the important parts are there)
class Test{
private $_vars = array();
private $_function;
public static function factory(){
return $test = new self(function() use(&$test){
$string_set = 'This is a string';
$test->bind('string', $string_set);
return true;
});
}
private function __construct($function){
$this->_function = $function;
}
public function bind($key, &$var){
$this->_vars[$key] = &$var;
return $this;
}
public function fetch($key, &$var){
$this->_vars[$key] = null;
$var = &$this->_vars[$key]; // edited; was not assigning by reference
return $this;
}
public function call(){
return (bool) call_user_func($this->_function);
}
}
$return = Test::factory()
->fetch('string', $string_get)
->call();
var_dump($return, $string_get);
// expected: bool(TRUE), string(16) "This is a string"
// actual: bool(TRUE), NULL
Am I chasing daisies here, is this even possible? Either way, I appreciate and thank you in advance for even glancing at this problem, any insight is really appreciated.
Edit: the line in fetch() - $var = $this->_vars[$key]; wasn't assigning the array element by reference. I've edited it now to $var = &$this->_vars[$key];, though it seemingly has no effect.
Bonus: If this problem is solvable, that's obviously great; I'm actually hoping that bind() can take $var by value, rather than by reference. The method signature would be changed to something like set($key, $value). Anyways, thanks again in advance.
To elaborate for the seemingly curious (looking in your direction #Tomalak) I'll provide the more complete class, and usage scenario:
class Action{
private static $_cache = array();
private static $_basePath;
private $_vars = array();
private $_function;
public static function setBasePath($basePath){
$basePath = rtrim($basePath, '/') . '/';
if(!is_dir($basePath)){
// throw exception, $basePath not found
}
self::$_basePath = $basePath;
}
public static function load($actionPath){
$actionPath = self::$_basePath . $actionPath;
if(array_key_exists($actionPath, self::$_cache)){
return self::$_cache[$actionPath];
}
if(!is_file($actionPath)){
// throw exception, $actionPath not found
}
$action = call_user_func(function() use(&$action, $actionPath){
return require($actionPath);
});
if(!($action instanceof self)){
// throw exception, $action of invalid type
}
self::$_cache[$actionPath] = $action;
return $action;
}
public function __construct($function){
if(!is_callable($function)){
// throw exception, $function not callable
}
$this->_function = $function;
}
public function bindReturn($key, &$var){
$this->_vars[$key] = &$var;
return $this;
}
public function fetchInto($key, &$var){
$this->_vars[$key] = null;
$var = &$this->_vars[$key];
return $this;
}
public function run(){
return (bool) call_user_func_array($this->_function, func_get_args());
}
}
############################################################################
// actions/test.php
return new Action(function($name)
use(&$action){
if($name == 'Alice'){
return false;
}
$data = "Hi, my name is {$name}.";
$action->bindReturn('data', $data);
return true;
});
############################################################################
// index.php (or whatever)
$result = Action::load('actions/test.php') // loaded
->fetchInto('data', $data)
->run('Alice');
// Failed
echo $result
? 'Success - ' . $data
: 'Failed';
$result = Action::load('actions/test.php') // called from cache
->fetchInto('data', $data)
->run('Bob');
// Success - Hi, my name is Bob
echo $result
? 'Success - ' . $data
: 'Failed';
What you want do is simply not possible (at least with referencces), because you cannot "redirect" a reference. Here's what happens:
$instance->fetch('foo', $myVar);
public function fetch($key, &$var){
// Here $var is a reference to $myVar.
$var = &$this->_vars[$key]; // now $var is a reference to $this->_vars[$key]
// it is not connected to $myVar anymore.
}
Here's what you can do: You can pass fetch() a reference to an array and set an element in that array to be a reference to $this->_vars[$key] or you can pass fetch() an object and set a member variable to be the reference.
Oh, sry missed the obvious: You can of course just use your bindReturn() function in the use-case you presented. That would work without problems.
Looks like you have problem with
public function fetch($key, &$var){
$this->_vars[$key] = null;
$var = $this->_vars[$key];
return $this;
}
If you want to remove the key, don't set it to null, unset it:
Edit: changed the code to avoid uninitialized variable exception.
public function fetch($key, &$var){
if(isset($this->_vars[$key]))
{
$var = $this->_vars[$key];
unset($this->_vars[$key]);
}
else
{
$var = null;
}
return $this;
}

Categories