I'm trying to print data from an array. The array is from a class. I'm getting
array(0) { }
instead of:
Array ( [0] => header_index.php [1] => footer.php )
The code is:
<?php
class TemplateModel {
public function getTemplate($template = "index"){
switch($template){
case "index":
$templateconfig = array("header_index.php","footer.php");
break;
}
return $templateconfig;
}
}
$temodel = new TemplateModel();
var_dump(get_object_vars($temodel));
$temodel -> getTemplate();
?>
What i'm doing wrong? Thanks in Advance
var_dump(get_object_vars($temodel));
will output class member $temodel. There are no class member variables, so output is empty. If you want to output your array, you have to for example do this:
print_r($temodel -> getTemplate());
My immediate thoughts are it looks like you are setting the variables in the function 'getTemplate' and that is not being called until after the var_dump.
ADD:
And I just noticed you are not capturing the return of the function. You are var_dumping the object created from the class.
FIX:
<?php
class TemplateModel {
public function getTemplate($template = "index"){
switch($template){
case "index":
$templateconfig = array("header_index.php","footer.php");
break;
}
return $templateconfig;
}
}
$temodel = new TemplateModel();
$returned_var = $temodel -> getTemplate();
var_dump($returned_var);
?>
If you want to set the array as a variable of the object, that is a different problem.
It looks like you're not initializing the $templateconfig variable until getTemplate() is called. And you don't call it until after var_dump().
So basically, you're dumping an object that has no initalized member properties which is why you see an empty array.
Your object itself has no variables (properties) to be returned with a call to get_object_vars(). The $templateconfig variable only exists within the scope of the getTemplate() function and is not a property of the object.
If your intent is to make it a property of the object, you should do something like this:
class TemplateModel {
private $template_config = array(
'index' => array("header_index.php","footer.php"),
// add other configs here
);
public function getTemplate($template = "index"){
if(empty($template)) {
throw new Exception('No value specified for $template');
} else if (!isset($this->template_config[$template])) {
throw new Exception('Invalid value specified for $template');
}
return $this->template_config[$template];
}
}
$temodel = new TemplateModel();
var_dump($temodel->getTemplate());
Note here if you call get_object_vars() you still would get an empty array as I have made the $template_config variable private, forcing the caller to use the getTemplate() method to access the template data.
Related
I created a class. The code is below
class Another {
public $error = array();
public function set_error( $key, $value )
{
if ( isset( $key ) ) {
$sanitizedKey = sanitize_key( $key );
$this->error[ $sanitizedKey ] = wp_json_encode( $value );
return $this->error;
}
}
public function get_error( $id )
{
if ( ! is_null( $id ) ) {
return $this->error[ $id ];
}
}
public function print_error()
{
if ( $this->error ) {
foreach ($this->error as $key => $value) {
$decodeJson = json_decode( $value );
?>
<div class="ud-error">
<p class="ud-error-<?php echo $key; ?>">
<?php echo __( $decodeJson, 'ud-for-edd' ); ?>
</p>
</div>
<?php
}
}
}
}
If I invoke it in the following way it works. It echos the content as expected.
$error = new Another();
$error->set_error('gg', 'hhhh');
$error->print_error();
But if I use it with function then it doesn't work as expected. Do I have to pass parameters by reference or any other? The following way it doesn't work
function create_error($id, $val) {
$errr = new Another();
return $errr->set_error($id, $val);
}
create_error('raa', 'raashid');
$error = new Another();
$error->print_error();
I am confused about why this doesn't work. Any clue. Thanks in advance.
Steps I want the code to perform:
Create a class with 3 methods, set_error, get_error, and print_error
Then invoke the class inside the function. The function will accept two parameters because inside the class the set_error() method accepts two parameters.
In order to print the error, I will instantiate the class and call the print_error() method.
In case, if I have to print the new error. I will just call the create_error() function to do this for me. Because the function needs 2 parameters. The arguments supplied to the function must be supplied as arguments to the set_error() method.
I hope the list helps.
Update:
If I use a global variable then it works. Below is working.
$customError = new Another();
function create_error($id, $val) {
global $customError;
$customError->set_error($id, $val);
}
create_error('raa', 'rashid');
$customError->print_error();
Thanks, #roggsFolly and #El_Vanja. By understanding your tips I was able to solve the error. If there is anything wrong with the code I just said worked. Please point out.
The object you instantiate inside the function is not the same one you try and print the error message from.
First the object you instantiate inside the function scope is not visible outside the function.
function create_error($id, $val) {
$errr = new Another();
return $errr->set_error($id, $val);
}
create_error('raa', 'raashid');
// this instantiates a seperate Another object from the one
// you created in the function
$error = new Another();
// this tries to print from the new object taht has no message stored in it yet
$error->print_error();
To instantiate the object inside a function scope and then use that object outside the function scope you must pass that object back to the caller of the function
function create_error($id, $val) {
$errr = new Another();
$errr->set_error($id, $val);
return $errr; // this returns the object
}
$error = create_error('raa', 'raashid');
// now you can use its methods to print the stored message
$error->print_error();
Update as per your additional Information
A couple of things I think you may be getting confused about.
Each time you do $var = new ObjectName; you are creating a brand new instance of that class. This new instance has no knowledge about any other instances of that class that may or may not have been created before or may be created after that point. And more specifically to your problems, it does not have access to the properties of another version of that object.
You are I believe missing the concept of variable scope. The Object you create inside that function, will only actually exist while the function is running. Once the function completes anything created/instantiated wholly within that function is DESTROYED ( well in truth it is just no longer accessible ) but to all intent and purpose it is destroyed. you therefore cannot expect to be able to address it outside the scope of the function.
If you want the Object you instantiate within the function to be usable outside the function, you must pass a reference to that object out of the function to the calling code. This passes that reference into the scope of the calling code and keeps the object alive, global scope in your case, but that might be another function or even another object. That allows you access to that instantiation and any properties that were set within it.
I wrote some program to check the value in an array.
var_dump($profileuser);//NULL
$profileuser = get_user_to_edit($user_id);//fetch the value of $profileuser
var_dump($profileuser);//does not print the value of $profileuser->user_url
//nor by print_r($profileuser)
if(isset($profileuser->user_url))
echo $profileuser->user_url;//printed!!!!How is it possible??
Could somebody can explain how this happened?
background:
I modified the kernel of wordpress.
This happened when I modified the file of wp-admin/user-edit.php.
You say it's an array, but you're accessing it as an object ($obj->foo rather than $arr['foo']), so it's most likely an object (actually it is - get_user_to_edit returns a WP_User). It could easily contain the magic __get and __isset methods that would lead to this behaviour:
<?php
class User {
public $id = 'foo';
public function __get($var) {
if ($var === 'user_url') {
return 'I am right here!';
}
}
public function __isset($var) {
if ($var === 'user_url') {
return true;
}
return false;
}
}
$user = new User();
print_r($user);
/*
User Object
(
[id] => foo
)
*/
var_dump( isset($user->user_url) ); // bool(true)
var_dump( $user->user_url ); // string(16) "I am right here!"
DEMO
One possibility is that $profileuser is an Object that behaves as an array and not an array itself.
This is possible with interface ArrayAccess. In this case, isset() would return true and you might not see it when you do var_dump($profileuser);.
When you want an object to behave like an array, you need to implement some methods which tell your object what to do when people use it as if it were an array. In that case, you could even create an Object that, when accessed as an array, fetches some webservice and return the value. That may be why you are not seeing those values when you var_dump your variable.
I thinks it's not possible, I've created test code and var_dump behaves correctly. Are you 100% sure you don't have any typo in your code? I remind variables in PHP are case sensitive
<?php
$profileuser = null;
class User
{
public $user_url;
}
function get_user_to_edit($id) {
$x = new User();
$x->user_url = 'vcv';
return $x;
}
var_dump($profileuser);//NULL
$user_id = 10;
$profileuser = get_user_to_edit($user_id);//fetch the value of $profileuser
var_dump($profileuser);//does not print the value of $profileuser->user_url
//nor by print_r($profileuser)
if(isset($profileuser->user_url))
echo $profileuser->user_url;//printed!!!!How does it possible??
Result is:
null
object(User)[1]
public 'user_url' => string 'vcv' (length=3)
vcv
I'm using reflection to dynamically call methods.
$object = new $class;
$reflector = new ReflectionMethod($class, $method);
$reflector->invokeArgs($object, $arguments);
The $arguments array looks like:
Array
(
[fooparam] => false
[id] => 238133
)
The method called could be:
class MyClass
{
public function myMethod ($id, $fooParam)
{
// Whatever
}
}
The problem is that everything comes from frontend designers, depending on data-* attributes, href... so $arguments array has arbitrary sorting.
How can I sort this array to match method parameters?
O maybe, is there a better solution? Named parameters?
Use ReflectionMethod::getParameters() to get a list of arguments and filter map them to their corresponding position, e.g.:
$sorted_args = array_map(function($param) use($arguments) {
$name = $param->getName();
if (!isset($arguments[$name]) && !$param->isOptional())
throw new BadMethodCallException("Argument '{$name}' is mandatory");
return isset($arguments[$name]) ? $arguments[$name] : $param->getDefaultValue();
}, $reflector->getParameters());
You could also use a simple foreach loop, it's up to you.
Then invoke the method with $sorted_args instead:
$reflector->invokeArgs($object, $sorted_args);
I have a method in PHP which calls a SOAP service, parses some data and returns it.
It will return the same data - it asks how many records in a data object.
I need to call it twice with a pass.
My question is, what is best practice for structuring this in PHP? I've tried to see if the function has been called already.Do I use static variables / functions?
function MinimumRequired() {
return $this->NumberPeopleJoined();
}
function NumberPeopleJoined () {
if (isset($NumberPeople)) {
Debug::Show($NumberPeople);
}
static $NumberPeople;
$NumberPeople = Surge_Controller::NumberPeopleJoined();
return $NumberPeople;
}
Thanks!
Just create a local class member, and check if that has a value. If not, set the value to whatever is retrieved from Surge_Controller, and if it was already set, just return the value:
<?php
class Surge_Controller {
static public function NumberPeopleJoined() {
echo "Surge_Controller::NumberPeopleJoined() got called.\n";
return 2;
}
}
class Foo {
protected $cacheNumberPeople;
function MinimumRequired() {
return $this->NumberPeopleJoined();
}
function NumberPeopleJoined () {
if( !isset( $this->cacheNumberPeople ) ) {
$this->cacheNumberPeople = Surge_Controller::NumberPeopleJoined();
}
return $this->cacheNumberPeople;
}
}
$foo = new Foo( );
echo $foo->numberPeopleJoined( ) . "\n";
echo $foo->numberPeopleJoined( ) . "\n";
Output:
$ php foo.php
Surge_Controller::NumberPeopleJoined() got called.
2
2
The simple way is to have a global variable, and check if is "true", and set it to true at the end of your function. The value can be cached too...
But if you want to make your code fun, you can use underscore:
http://brianhaveri.github.com/Underscore.php/#once
http://brianhaveri.github.com/Underscore.php/#memoize
I am building a Language class for internationalization, and I would like to access the properties dynamically (giving the string name), but I don't know how to do it when dealing with arrays (this is just an example):
class Language {
public static $languages_cache = array();
public $index_header_title;
public $index = array(
"header" => array(
"title" => NULL
)
);
}
Now I add languages like this:
Language::$languages_cache["en"] = new Language();
Language::$languages_cache["en"]->index_header_title = "Welcome!"; //setting variable
Language::$languages_cache["en"]->index["header"]["title"] = "Welcome!"; //setting array
Function for accessing members dynamically:
function _($member, $lang)
{
if (!property_exists('Language', $member))
return "";
return Language::$languages_cache[$lang]->$member;
}
So, outputting members:
echo _('index_header_title', "en"); //works
echo _('index["header"]["title"]', "en"); //does not work
I would need a way for accessing arrays dynamically.. for public and private via __set() function.
Thank you!
You could try using a separator flag so that you can parse the array path. The only problem is you are mixing you properties and arrays so that might complicate things.
You would call your function like this:
echo _('index.header.title', "en");
And your function would parse the path and return the correct value. Take a look at the array helper in Kohana 3.0. It has the exact function that you want. http://kohanaframework.org/guide/api/Arr#path