PHP: Call method with array? - php

Not quite sure how to word the title better.
What i need to do, is call a method with call_user_func. The method i'm calling accept several different variables (var1, var2, var3 etc), not an array. The problem is, when calling the function i need to pass the array i have as seperate variables to the method. Let me show you.
Here's my method:
class Test {
public function testing_cronjob($p1, $p2, $p3, $p4, $p5) {
echo 'p1 = ' . $p1 . '<br />';
echo 'p1 = ' . $p2 . '<br />';
echo 'p1 = ' . $p3 . '<br />';
echo 'p1 = ' . $p4 . '<br />';
echo 'p1 = ' . $p5 . '<br />';
}
}
And here's how i currently (try) to call it:
$obj = new Test();
call_user_func(array($obj, 'testing_cronjob'), $params);
The method runs, but it only gets one variable, which is not what i want.
$params look like this:
$params = array(
0 => 'first one',
1 => 'second one',
2 => 'third param!',
3 => 'oh and im fourth!!',
4 => 'im last, fml! :('
)
The way i got myself into this situation, is because i'm creating a cronjob model. It accepts params along with class and method name. It's all stored in a database, and when it runs, i need to be able to send the $params to the method as intended.
I can't rewrite how methods accept variables, because that would be way too much work. I'm going to be calling several (10+) methods from the cronjob, all of which are pretty well used in the application. I'm also not sure how i would re-write it, but if you have any suggestions about that, let me know.
Also, i'm using codeigniter if that matters. If i forgot to mention anything or you want more code, just drop a comment.
Is this possible? Are there any workarounds? Any suggestions are welcome!

You have to use call_user_func_array instead:
$obj = new Test();
call_user_func_array(array($obj, 'testing_cronjob'), $params);

Related

AWS SDK PHP iterator

I've written a small function (in PHP) to return all AWS instances in my account.
I've tried using the basic describe instances method but it times out (see below).
So the new function uses the getIterator, however, the page still times out. If it set the max results to 10 it works, but I think that defeats the object. I want a full list of all of my instances.
Any thoughts on what I might be doing wrong that would cause my request to time out? The time out message I get is:
Unable to load the webpage because the server sent no data. Error code: ERR_EMPTY_RESPONSE"
public function allInstances(){
$response = $this->ec2Client->getIterator('describeInstances',array(
'Filters' => array(
array(
'Name' => 'instance-state-name',
'Values' => array('running')
)
))
);
return $response;
}
Update to original post:
This is my code for iterating through the results return by the describeInstances itertator. I know I have around 400 instances running, however the result never returns anything more than about 280.
foreach($iterator as $object){
$value = $object['Reservation'];
//echo "<pre>" . print_r($object,true) . "</pre>";
$number = $count++;
echo $count . ">" . "<b>InstanceID: </b>" . $object['InstanceId'] . " <b>AMI: </b>" . $object['ImageId'] . "</br>";
}

How can I create a local shortcut to an instance method?

In Python I can do this in a class instance method:
esc = self.super_long_escape_function_name
print esc(param1) + ", " + esc(param2)
In PHP, this is the closest "equivalent" I've been able to concoct:
$self = $this;
$esc = function($str) use($self) {
return $self->super_long_escape_function_name($str);
};
echo $esc($param1) . ", " . $esc($param2);
and I wouldn't really even call that an equivalent. I also tried this without success:
$esc = '$this->super_long_escape_function_name';
Are there any good ways of creating a local shortcut for a class instance method?
Right after asking this question, I discovered that this works:
$esc = array($this, "super_long_escape_function_name");
echo $esc($param1) . ", " . $esc($param2);
This doesn't work in PHP 5.3 though, so I will accept a better answer if it comes along.
Try this one
$esc = array($this, "super_long_escape_function_name");
echo $esc($param1) . ", " . $esc($param2);

NetBeans code template for using all the arguments declared in the function's header

Is it possible to write a NetBeans code template for using all the arguments declared in a function's header (e.g. for calling another function with these variables)? The number of the arguments can be different, so it doesn't seem to be easy.
For example, sometimes I want to print out all the arguments in a function for debugging purposes.
Here's an example usage (calling dsm() function multiple times depending on the number of the arguments):
function testModule_theme($existing, $type, $theme, $path) {
dsm($existing, '$existing in ' . __FUNCTION__ . '()');
dsm($type, '$type in ' . __FUNCTION__ . '()');
dsm($theme, '$theme in ' . __FUNCTION__ . '()');
dsm($path, '$path in ' . __FUNCTION__ . '()');
return array(
// ......
);
}
Here's another one:
function testModule_block_view($delta = '') {
dsm($delta, '$delta in ' . __FUNCTION__ . '()');
$block = array();
// .....
return $block;
}
As you can see, there are 4 arguments in the first case, and only 1 in the second. The name of the arguments is also changing depending on the given function.
There's a code template I already wrote for using dsm() function:
dsm($$${VARIABLE newVarName default="variables"}, '$$${VARIABLE} in '.__FUNCTION__.'()');
this way I just type ddsm, hit Tab, and then I have to type the exact name of the variable. So it would print out the following:
dsm($variables, '$variables in ' . __FUNCTION__ . '()');
After that, I can change the variables part, and type another name, and the same would be used in the string. An example:
But I'm still too laggard to type that stuff :D, and I'm curious if there is a way to use all the arguments of a given function when using a code template in NetBeans.
This really seems difficult. If you knew you will be using the macro when you declare the function, you could use templates like this:
// shortcut dsmfun1
function ${FUNCTION_NAME}($$${PAR1}) {
dsm($$${PAR1}, '$$${PAR1} in ' . __FUNCTION__ . '()');
${selection}${cursor}
}
...
// shortcut dsmfun4
function ${FUNCTION_NAME}($$${PAR1}, $$${PAR2}, $$${PAR3}, $$${PAR4}) {
dsm($$${PAR1}, '$$${PAR1} in ' . __FUNCTION__ . '()');
dsm($$${PAR2}, '$$${PAR2} in ' . __FUNCTION__ . '()');
dsm($$${PAR3}, '$$${PAR3} in ' . __FUNCTION__ . '()');
dsm($$${PAR4}, '$$${PAR4} in ' . __FUNCTION__ . '()');
${selection}${cursor}
}
Couple templates give you really quick declaration and you have to type the parameters' names only once.
If you are adding these macros later, you might want to have a look at this doc and implement your desired behavior (even though that might be quite tricky).
Hope this helps!
Why don't you just use get_defined_vars() to pass them all in one shot? This way, your macro only needs to be a single static line.
function dsm($func, array $args)
{
foreach ($args as $name => $value) {
echo "in $func, arg '$name' is $value\n";
}
}
function testModule_theme($existing, $type, $theme, $path) {
dsm(__FUNCTION__, get_defined_vars());
}
testModule_theme(1, 2, 3, 4);
Output:
in testModule_theme, arg 'existing' is 1
in testModule_theme, arg 'type' is 2
in testModule_theme, arg 'theme' is 3
in testModule_theme, arg 'path' is 4

Is there an easier/shorter way to get geographic coordinates from GoogleMaps?

I'm currently using the following method to get coordinates from GoogleMaps.
Can I possibly write this shorter/more efficient?
EDIT 21.06.2013
As of now the old Google Geocoding API is off. This is my modified code that works with the most recent version. I've updated this post, if someone stumbles over it and finds it useful.
public function getGeographicCoordinatesFromGoogle()
{
// create address string
$value = $this->address_line_1 . ' ' .
$this->postal_code . ' ' .
$this->city . ' ' .
$this->country;
$value = preg_replace('!\s+!', '+', $value);
// create request
$request = 'http://maps.googleapis.com/maps/api/geocode/xml?address=' .
$value . '&sensor=false';
// get value from xml request
$xml = file_get_contents($request);
$doc = new \DOMDocument('1.0', 'UTF-8');
#$doc->loadXML($xml);
// fetch result
$result = $doc->getElementsByTagName('lat')->item(0)->nodeValue . ',' .
$doc->getElementsByTagName('lng')->item(0)->nodeValue;
// check result
if (!preg_match('/(-?\d+\.\d+),(-?\d+\.\d+)/', $result) ) {
$result = null;
}
// assign value
$this->setGeographicCoordinates($result);
}
You can use json instead of xml. json is newer, lightweight and object orientated.
I'll recommend you to use http_build_query() instead of trying to build the SearchQuery with Regex. There are other chars which need to be escaped.
This is a quite long method. Maybe it would make sense to have one Class which only handles the communication with GoogleMaps (Class GeoBackend with methods getGeoDataForAddress(), which returns a GeoData-Object, which could be asked for Cordinates etc.)

How to create a string taking empty variables into consideration?

I'm trying to build a placeholder meta description for a page, in case the user hasn't included a description in the CMS.
I have started with the following code, but of course it fails if any of the other variables are empty too, such as $phone, $location['zip'] and so on.
<?php
if (!empty($description)) {
echo '<meta name="description" content="' .$description . '">';
}
else {
// Should return: Apple is a business located in Palo Alto, 95014. Call 408.996.1010...
$description = $name . ' is a ' . strtolower($category) . ' located in ' . $location['city'] . ', ';
$description .= $location['zip'] . '. Call ' . $phone . ' for more details today.';
echo '<meta name="description" content="' . $description . '">';
} ?>
What's the most efficient way to build a description in this way? Currently I can only think of nested if statements which sounds messy and I'm sure there must be a clean way to do this.
add a function to check if value is set?
i.e.
function checkData($data) {
if(!empty($data)) {
return $data;
} else {
return '';
}
}
$description = checkData($name) . ' is a ' . strtolower(checkData($category)) . ' located in ' . checkData($location['city']) . ', ';
As the description is something that varies based on the input, put it into a function or class of it's own to encapsulate it:
/**
* build a description based on various input variables
* #return string
*/
function build_description($description, $name, $category, array location, $phone) {
// build the description as you see fit.
}
$description = build_description(compact('description', 'name', 'category'));
$metaDescription = sprintf('<meta name="description" content="%s"', htmlspecialchars($description));
that done, the concrete implementation within build_description can contain a lot of complex statements, while the rest of the program can deal with it as if it is something simple.
However, this does not answer how you could code it inside that function. But as the data of the output of that function heavily depends on the input of that function, you can only deal with all aspects the arguments do impose.
The other variables defined shouldn't be string but part of an object such as... Description.
In this case, it would be easier, calling a Description->isEmpty() that returns true if one of those variables are empty.
If you are stuck with this configuration, you still can make an array:
$myArray=array($name, $category,...);
and check in a loop or maybe the return of in_array('',$myArray)

Categories