I am quite new to programming, when I develop my program I use a simple strategy to debug it: I write the program to print along the debugging messages as it operate the significant statements, for example
function foo1($number)
{
//foo_print("I am function foo1({$number}). <br/>");
//foo_print("I am going to increase 'count' by {$number}. <br/>");
$GLOBALS["count"] = $GLOBALS["count'] + $number;
//foo_print("Now 'count' = {$GLOBALS["count"]}, I finished my task, BYE BYE. <br/>");
}
function isFoo($number)
{
//foo_print("I am function isFoo({$number}). <br/>");
//foo_print("I am checking if the number < 3 or not, if so, it is Foo, if not, it is not Foo. <br/>");
if($number <= 3)
{
//foo_print("Found that number = {$number} <= 3, I return true, BYE BYE. <br/>");
return true;
}
//foo_print("Found that number = {$number} > 3, I return false, BYE BYE. <br/>");
return false;
}
I call them debugging messages but, as you see, they're actually the thoroughly comments describing what does the program do on each line. I just write the function foo_print() to print them out when I am debugging the program. And comment them out in real use.
Instead of inserting and removing the comment sign '//' line by line in and out when switch between real run mode and debugging mode, I have the function foo_print to do the work: It can be set to turn on or off.
define(FOO_PRINT, 1)
function foo_print($message)
{
if(FOO_PRINT) print $message;
// if FOO_PRINT == 0 then do nothing.
}
But I think this method is ineffective, it has to check FOO_PRINT every time before printing a message.
My question is either or both of the following
Can I do something to tell php to ignore my foo_print() function when I don't want to use it?
Perhaps, instead of using foo_print function, I should write the messages in plain comment style using '//' sign and then tell php interpreter to print those comment messages when in debugging mode. Can I do that?
I think, other than debugging ease, this method will be of advantage that it can help me understand the program when I come back to see it in later days. (It very long and complicated for me that I believe I will forget it soon.)
I found it very complicated for me now to use advanced IDEs and debugging tools to develop my program. I believe some of these advanced debugging tools can do something similar to what I want, but I've tried on PHP-eclipse and xdebug for a week and it got me nowhere. thank you very much.
You could define two functions, one of which outputs the debug data and the other one doesn't. Then use a variable name to contain the name of the function you want to call and do your debugging by calling the function in the variable. Like this:
function debug_print($data) {
echo $data;
}
function debug_none($data) {
}
$debug = 'debug_print';
$debug('Testing one'); // This prints out 'Testing one'
$debug = 'debug_none';
$debug('Testing two'); // This doesn't print out anything
If you do this, don't forget to add global $debug to any functions that want to use the function.
EDIT: There is also a more object oriented way to achieve the same result. You could define an interface and write a couple of implementations for it, allowing you to choose which one to use at runtime.
$debugmode = true;
interface Debugger {
public function out($data);
}
class EchoDebugger implements Debugger {
public function out($data) {
echo $data;
}
}
class NullDebugger implements Debugger {
public function out($data) {
// Do nothing
}
}
if($debugmode)
$debugger = new EchoDebugger();
else
$debugger = new NullDebugger();
$debugger->out('This will be output if $debugmode is true');
No bud,
there is no such thing possible, and you have to define a condition every time.
This cannot be done in code of php
Related
I am wondering if there is any real benefit to using this...
function getSomeContent() {
ob_start(function($content) {
// ... modify content ...
return $content;
}
// ... output stuff ...
return ob_get_clean();
}
...as opposed to this...
function getSomeContent() {
ob_start();
// ... output stuff ...
$result = ob_get_clean();
// ... modify content ...
return $result;
}
...?
Assume the "output stuff" and "modify content" parts are the same in each case. The key point is that the "modify content" has changed its location, being in a callback in the first case, and being "inline" in the second case.
Is there a performance benefit of one over the other? For example, does the second form make two copies of the buffer contents when the first uses only one? Or is it purely a coding style decision? Why would you choose one form over the other?
I can see there are differences in scope access, because any variables in the enclosing scope will be available in the "modify content" part of the second example, where they would have to be "passed in" with a use clause in the first example. In fact this is exactly why I would normally choose the second form.
Now your code is clear yes, in your first samples you given a case where you used $result twice (that wasn't a good idea).
My main idea is : you call ob_start with a callback only if you do not need to use your $result in your current scope. Your first example becomes :
ob_start(function($content) {
// ... modify content ...
return $content;
}
// ... output stuff ...
ob_end_clean();
In this case, the job with $result is made in a new scope and this can make your code cleaner (example: you call ob_start(array($this, 'method'));), and you don't need to unset your $result to free it from your main scope at the end of your job (I assume you're doing something else of course).
Just to clarify Ninsuo's correct answer a bit.
My two code samples actually do not produce the same result. In fact, using the callback in combination with ob_get_clean() is completely useless.
This is because the callback is applied when cleaning or flushing the buffer.
However ob_get_clean() retrieves the contents first, and then cleans the buffer. Which means that the contents returned are not the result returned by the callback, but the input passed to the callback.
I wrote these two simple (and hacky) scripts to demonstrate.
This one uses ob_get_clean() and does not produce the correct result:
// Tests the use of callbacks with ob_get_clean().
class TestWithGetClean {
// This variable is set when obcallback is called.
public $foo = null;
// The output buffer callback.
public function obcallback($value) {
$this->foo = 'set';
return $value . '(modified)';
}
// Main method.
public function run() {
ob_start(array($this, 'obcallback'));
echo 'this is the output', PHP_EOL;
return ob_get_clean();
}
}
// Run the test with ob_get_clean().
$t = new TestWithGetClean();
echo $t->run(); // This method returns a value in this test. (But not the correct value!)
echo $t->foo, PHP_EOL;
The output from running this is:
this is the output
set
The text '(modified)' does not appear anywhere. Note however that the instance variable $foo is set, so the callback is definitely called, however the output is not as I originally expected.
Compare to this one which uses ob_end_flush():
// Tests the use of callbacks with ob_end_flush().
class TestWithEndFlush {
// This variable is set when obcallback is called.
public $foo = null;
// The output buffer callback.
public function obcallback($value) {
$this->foo = 'set';
return $value . '(modified)' . PHP_EOL;
}
// Main method.
public function run() {
ob_start(array($this, 'obcallback'));
echo 'this is the output', PHP_EOL;
ob_end_flush();
}
}
// Run the test with ob_end_flush().
$t2 = new TestWithEndFlush();
$t2->run(); // This method produces output in this test.
echo $t2->foo, PHP_EOL;
This one produces the following output:
this is the output
(modified)
set
However, this is of course not as useful because the output goes directly to the client, so we cannot further manipulate the result. (For example, wrapping the text in a Symfony HttpFoundation Component Request object).
I am trying to grasp the concept of PHP functions. I know how to create one.
function functionName()
{
//code to be executed;
}
I also know how to call a function. I am just a little confused as to what a parameter is for. I have read the php manual and w3schools.com's tutorial. From my understanding, you need a parameter to pass a value to the function? If that is correct why not just create it within the function? Why use a parameter?
Like this:
<?php
function num()
{
$s=14;
echo $s;
}
num();
?>
I know you can do:
<?php
function num($s=14)
{
echo $s;
}
num();
?>
or:
<?php
function num($s)
{
echo $s;
}
num($s=14);
?>
Could someone give me a real application of using a parameter, for say maybe a user based dynamic content website? I think it would help me understand it better.
Passing a parameter allows you to use one function numerous times. For example:
If you wanted to write ONE function that sent mail - you could pass the following parameters:
$to = $_POST['to'];
$from = $_POST['from'];
$subject = $_POST['subject'];
Then, in your function:
function sendmail($to, $from, $subject){
//code to be executed
}
Now you can reuse your send function at various points in your web app.
Here is an example, say you have numbers representing colors (this is common in storing data in a database) and you want to output what number represent's what color.
Say you had to do this a hundrend times for a hundred numbers.
You'd get pretty tired writing 100 if statments 100 times.
Here is a function example...
function colorType($type) {
if ($type == 1) {
return "Green";
}
elseif ($type == 2) {
return "Blue";
}
elseif ($type == 3) {
return "Red";
}
// etc
}
echo colorType(1) . "<br>"; // Green
echo colorType(2) . "<br>"; // Blue
echo colorType(3) . "<br>"; // Red
A function does something, and gives a result. It may accept parameters to arrive at that result, it may not. The simple calculator, as aforementioned, is a good one.
The easiest way to understand functions and parameters is to just read the PHP manual—most of the functions in the core PHP language take parameters of some sort. These functions are no different to the functions you write.
Let's assume you want to create a function that will allow people to sum numbers, you can't write needed variables in functions because you want others to input it and your function shows output:
function add($num1, $num2){
return $num1 + $num2;
}
Now anyone can call/use your function to sum numbers:
echo add(5,1); // 6
echo add(2,1); // 3
echo add(15,1); // 16
That's the most simplest example one can give to explain why you need parameters :)
When you specify function name($var=VALUE), you are setting a default.
function doit($s=14) {
return $s + 5;
}
doit(); // returns 19
doit(3); // returns 8
it makes your functions flexible to be reused in various situations, otherwise you would have to write many functions, one for each scenario. this is not only tedious, but becomes a nightmare if you have to fix something in those functions. instead of fixing it in one place, you would have to fix it in many places. you basically never want to have to copy paste code you have already written, instead you use arguments to make one set of the code flexible enough to handle each situation.
Paramaters allow your function to see the value of variables that exist outside of itself.
For example:
function F_to_C($temp) {
$temp = ($temp - 32) / 1.8;
return $temp;
}
$temperature = 32;
$new_temperature = F_to_C($temperature); // 0
echo $temperature;
$temperature2 = F_to_C(212); // 100
echo $temperature2;
Here we take $temperature, which we define in the code, but could be user input as from a form, and then send it to the function F_to_C. This allows us to convert it to Celsius, so we can then display it thereafter. In the next section, we then re-use the function to convert the boiling point, which is sent directly this time as the value 212. If we had embedded $temperature = 32 in the function the first time, then we would still get 0 as a result. However since we're using parameters, we instead get 100 back, because it's processing the value we specified when we invoked the function.
function mainFunction() {
functionA(5, "blah");
functionB("ok", "whatever");
}
How to write a function GetFunctions that returns the functions within mainFunction?
How to call them with the parameters given in mainFunction?
How to call them as follows?
foreach (GetFunctions(mainFunction) as $function) {
print "Calling function $function: ";
call($functionA); // called with parameters(5, "blah")
}
Working in PHP 5.2.8
EDIT: OK, here's a more complete explanation. I tried to keep it simple to make it easy to understand, but apparently that wasn't a good idea.
The goal is to call each assertion within a given static method. I am writing a testing framework. Each assertion returns true or false.
I am calling the methods as follows.
$methods = get_class_methods('LibraryTests');
foreach ($methods as $method) {
if ( StartsWith($method, 'Test') ) {
print "calling: " . $method . ": ";
call_user_func('LibraryTests::' . $method);
}
}
The above code calls each method within the class, but I want to call each assertion individually and track the result (true/false). CallAssertion is supposed to call each assertion (such as TestUnit::AssertEqual(GetFormattedHour(5), "5 PM");). This is the method that I am asking about.
Here is the class:
class LibraryTests extends TestUnit {
static $success = 0;
static $failure = 0;
static $total = 0;
static function CallAssertion($assertion) {
self::$total += 1;
if ($assertion) { self::$success += 1; }
else { self::$failure += 1; }
}
static function TestGetFormattedHour() {
TestUnit::AssertEqual(GetFormattedHour(5), "5 PM");
TestUnit::AssertEqual(GetFormattedHour(16), "4 PM");
}
So, the question is, how to write CallAssertion?
You can't.
Instead, create a class and use reflection to get its methods.
Regardless, you'll want to figure out why this is necessary and see if there is an entirely different approach you can use.
(If this is for debugging purposes, you can use debug_backtrace to inspect but its purpose is not for calling functions as you have described in your question.)
Hmm, what problem are you actually trying to solve. To me it sounds like you're trying to inspect the call stack at runtime. If so, I'd suggest just using debug_backtrace() (src).
I wouldn't suggest using that function in production as much though, as it's a rather heavy hit on your code.
One possibility would be to do a file_get_contents on the PHP file that contains main_function, then go through it to parse out main_function and the functions it calls. Of course, I don't know your situation so that might not work.
You can do this with:
http://php.net/manual/en/function.token-get-all.php
Probably a bad idea, but good luck!
I'm writing a unit testing platform and I want to be able to dynamically generate a function based off of each function in the web service I am testing. The dynamic function would be generated with default(correct) values for each argument in the web service and allow them to be easily traded out with incorrect values for error testing.
$arrayOfDefVals = array(123, 'foo');
testFunctionGenerator('function1', $arrayOfDefVals);
//resulting php code:
function1Test($expectedOutput, $arg1=123, $arg2='foo')
{
try
{
$out = function1($arg1, $arg2);
if($expectedOutput === $out)
return true;
else
return $out;
}
catch ($e)
{
return $e;
}
}
This would allow me to quickly and cleanly pass one bad argument, or any number of bad arguments, at a time to test all of the error catching in the web service.
My main question is:
Is this even possible with php?
If it's not possible, is there an alternative?
EDIT: I'm not looking for a unit test, I'm trying to learn by doing. I'm not looking for advice on this code example, it's just a quick example of what I would like to do. I just want to know if it's possible.
I would not try that first as PHP has not build-in macro support. But probably something in that direction:
function function1($param1, $param2)
{
return sprintf("param1: %d, param2: '%s'\n", $param1, $param2);
}
/* Macro: basically a port of your macro as a function */
$testFunctionGenerator = function($callback, array $defVals = array())
{
$defVals = array_values($defVals); // list, not hash
return function() use ($callback, $defVals)
{
$callArgs = func_get_args();
$expectedOutput = array_shift($callArgs);
$callArgs += $defVals;
return $expectedOutput == call_user_func_array($callback, $callArgs);
};
};
/* Use */
$arrayOfDefVals = array(123, 'foo');
$function1Test = $testFunctionGenerator('function1', $arrayOfDefVals);
var_dump($function1Test("param1: 456, param2: 'foo'\n", 456)); # bool(true)
Probably this is helpful, see Anonymous functionsDocs, func_get_argsDocs, the Union array operatorDocs and call_user_func_arrayDocs.
Well, for starters, you can set default parameters in functions:
function function1Test($expectedOutput, $testArg1=123, $testArg2='foo') {
...
}
Beyond that, I'm not really sure what you're trying to achieve with this "function generator"...
Read about call_user_func and func_get_args
This example from the manual should get you on the right track:
<?php
call_user_func(function($arg) { print "[$arg]\n"; }, 'test'); /* As of PHP 5.3.0 */
?>
If it's a function you have file access to (i.e., it's not a part of the PHP standard library and you have permissions to read from the file), you could do something like this:
Assume we have a function like this located in some file. The file will have to be included (i.e., the function will have to be in PHP's internal symbol table):
function my_original_function($param1, $param2)
{
echo "$param1 $param2 \n";
}
Use the ReflectionFunction class to get details about that function and where it's defined: http://us2.php.net/manual/en/class.reflectionfunction.php.
$reflection = new ReflectionFunction('my_original_function');
Next, you can use the reflection instance to get the path to that file, the first/last line number of the function, and the parameters to the function:
$file_path = $reflection->getFileName();
$start_line = $reflection->getStartLine();
$end_line = $reflection->getEndLine();
$params = $reflection->getParameters();
Using these, you could:
read the function out of the file into a string
rewrite the first line to change the function name, using the known function name as a reference
rewrite the first line to alter the parameter defaults, using $params as a reference
write the altered function string to a file
include the file
Voila! You now have the new function available.
Depending on what it is you're actually trying to accomplish, you could also potentially just use ReflectionFunction::getClosure() to get an closure copy of the function, assign it to whatever variable you want, and define the parameters there. See: http://us.php.net/manual/en/functions.anonymous.php. Or you could instantiate multiple ReflectionFunctions and call ReflectionFunction::invoke()/invokeArgs() with the parameter set you want. See: http://us2.php.net/manual/en/reflectionfunction.invokeargs.php or http://us2.php.net/manual/en/reflectionfunction.invoke.php
I am trying to insert messages to a function
function addMessage($item) {
if ($result) {
$message = '<p class="ok">
<span> Item added </span>
</p>
';
header("Refresh: 2; url=?page=$item");
}
else{
$message = '<p class=not><span>There is an error blah blah</span></p>';
}
return $message;
}
When I use it : addMessage('contents') it only returns to second condition. How can I fix this?
You are checking $result inside the if but its neither been assigned any value before that nor been declared as global . I think you meant to check $item:
if ($item) {
Hi jasmine
Your function always returns the second condition because you haven't assigned a value to $result, eider inside the function or when you call the function (like unicornaddict mentioned by other words).
To get your code working the way you probably want, your function should be like this:
function addMessage($item, $result) {
if ($result) { // It will return this condition, case $result has any value assigned and is different from FALSE (boolean)
$message = '<p class="ok">
<span> Item added </span>
</p>
';
header("Refresh: 2; url=?page=$item");
}
else{ // It will return this condition, case $result doesn't has any value assigned or is equal to FALSE (boolean)
$message = '<p class="not"><span>There is an error blah blah</span></p>';
}
return $message;
}
And then you can call the function like you where already calling it, but don't forget to include a variable or a value that should be handled as the $result variable inside the function
addMessage('contents', $result);
Note:
In your $message variable you have <p class=not> and should be <p class="not">.
Remember that header() must be called before any actual output is sent to the browser.
Hope it Helps.
Is $result defined in your script? Use if ($item) instead.
Be very careful that PHP allows the usage of undefined variables.
what they said :-)
Btw, a decent IDE (like Zend) will analyze your code and warn you about things like that.
Such static code analysis is known as "linting", so google for "PHP lint" or see questions like Is there a static code analyzer [like Lint] for PHP files?
But this code sample is so small that I guess you are a beginner (no offence interned - we all had to start somewhere), so do a lot of reading and gather a lot of tools and experience.
For instance, a decent IDE (like Zend or Eclipse PDT) would let you step through your code, line nby line, and examine the value of each variable and then you ought to have seen the problem.
Welcome to PHP and good luck!