I want to use php in console mode and create an environment to test my functions.
I do not want to be forced to use a web browser and create a new file each time I want to test a function.
I want to access the function in the console and then it return the result.
How do I do this?
Update:
Perhaps I have explained this badly. I only want to see what result the function's return.
Maybe I have to learn unit testing but for the moment I only want an interactive console which allows me to test all functions one by one.
In my case I have to load the wordpress functions (I know how do it with a regular .php file and then a browser to parse the file) but i don't if it is possible to do it with php from the command line.
I have used phpsh in the past and found it very useful. Once you start it you will need to chdir() to where your files are and then obviously require() any files containing functions you need to test. You can then just test your function calls by typing them into the shell e.g. var_dump(some_function(1, 2));
I guess you've to be more specific what kind of functions exactly. Wordpress does not provide something like that out of the box, most PHP apps won't.
I also think you're calling for trouble here when such apps aren't developed in mind for such environments.
Here's an example trying to call "current_time()" from functions.php and the attempts I had to do just to realize it won't work that way:
php -r 'require "functions.php"; var_dump(current_time("mysql"));'
gives
Fatal error: Call to undefined function apply_filters() in functions.php on line 346
Trying
php -r 'require "functions.php"; require "plugin.php"; var_dump(current_time("mysql"));'
gives
Fatal error: Call to undefined function wp_cache_get() in functions.php on line 351
Trying
php -r 'require "functions.php"; require "plugin.php"; require "cache.php"; var_dump(current_time("mysql"));'
gives
Fatal error: Call to a member function get() on a non-object in cache.php on line 93
Looking at the last error in the source I see
function wp_cache_get($id, $flag = '') {
global $wp_object_cache;
return $wp_object_cache->get($id, $flag);
}
Using global variables makes testing in other environments a PITA if not impossible.
If this is not what you're trying to do, you've to be more specific/detailed in your question.
You are going to want to read up on "Unit Testing" in a generic sense and then try and apply them to PHP.
The framework you are using (if any), the style of code, and the tests you want to run are going to determine the exact methods you need to use. Only by first understanding the concept of Unit Tests and implementing them into your coding best-practices will you be able to make progress in this regard.
How about:
php -a
And if you compile php with readline support it'll be more fancy.
Related
Are there any methods to catch the php commands instead of executing them?
There's a backdoor which is encoded in my server, I was able to get declared classes and methods names, of the backdoor, but I need to find out the real code.
I can think of 2 things.
1. Use a profiler tool.
2. In your own code define a class with the same name. Then when the backdoor class is loaded, it will give a fatal error ('class name already defined') and tell you where the other class resides. Do enable stacktraces in case the backdoor is obfuscated/eval'd/remote included.
I have two PHP scripts that include the same include file. Also, for testing purposes, I declared the same function that performs SOAP operations in both scripts. In other words, my scripts look like this:
#script1.php
include('include.php');
someFn();
function someFn() {
//SOAP code here
}
#script2.php
include('include.php');
someFn();
function someFn() {
//SOAP code here
}
Whenever I try to run one script and then the other, I get the following error:
PHP Fatal error: Cannot redeclare someFn() (previously declared in script1.php) in script2.php
I cannot understand why I'm getting this error. I've coded similar situations before, but never gotten this error, so I suspect that the executing of the SOAP code (specifically, the new SoapClient constructor and $client->__setSoapHeaders method) is causing this error.
What's also interesting is if I comment out the include file (which, by the way, does not have someFn defined in it) and then rerun the script, I don't get any errors and everything is fine.
What is happening here?
Thank you.
Edit: After playing around some more, I found out that if I have the following situation:
#script1.php
include('include.php'); //someFn defined in include.php
someFn();
#script2.php
someFn();
function someFn() {
//SOAP code here
}
And then run script2.php and then script1.php after that, I get the same error. It's almost as if after I run script2.php and close it, the process continues in PHP so that when I run script1.php, I get the error.
Any help would be greatly appreciated.
Thank you.
Edit #2: This is honestly the most confusing thing ever. I started over by creating two brand new files in the same directory as the other files and then all I added to both files was the following code:
<?php
include('include.php');
And when I run either file, I get all the SOAP output that was generated from the other files in the directory. I haven't bothered trying to restart the server, but at this point, I can only assume that something really weird is cached on the server.
Anyway, I resolved the issue by simply creating a new directory and then moving the file I wanted to that directory and re-executing it. By doing that, I got no errors and everything is fine.
Thanks everyone for your assistance.
I've tried testing my commands in Laravel 4, as they are significant part of my system, but it seems like the documentation coverage is so poor, that they only explain basic testing of controllers and some models.
In Commands, you can pass arguments via command line to the class and it's received via $this->input property, something I don't know how to emulate.
Whenever I try to run the test for my command, when it expects an argument in "fire" method, I get this error:
Fatal error: Call to a member function getArgument() on a non-object in /var/www/html/project/vendor/laravel/framework/src/Illuminate/Console/Command.php on line 153
Which is logical, there's no argument passed. Is there a way to test this functionality?...
Thanks
Most of it can be done using Symfony Command Tester (since Command is based on Symfony Console), example: http://alexandre-salome.fr/blog/Test-your-commands-in-Symfony2. However this would start to fail if you have to call another artisan command such as $this->call('db:seed'); or etc because this is actually Illuminate\Console\Application specific syntax.
I'm all open if there anyone that have a solution for above scenario.
I have recently made a post about Testing Laravel commands.
If you have a specific part of code that you want to use in multiple commands then you have to move that part of the code somewhere where both commands can use it (Event handler, trait, another class ...) and then in your command reference that code instead of using $this->call('db:seed');
After following the user guide instructions found here: http://ellislab.com/codeigniter/user-guide/general/cli.html I'm unable to run the test script via command line.
My controller located at /var/www/mysite/application/controllers/
class Tools extends CI_Controller {
public function message($to = 'World')
{
echo "Hello {$to}!".PHP_EOL;
}
}
In my browser I can access
http://mysite/tools/message/ben
And the function correctly outputs "Hello ben"
From terminal I should be able to run:
$ php index.php tools message "Ben"
My terminal should print: "Hello Ben"
However I get the following error:
PHP Fatal error: Class 'CI_Controller' not found in /var/www/mysite/system/core/CodeIgniter.php on line 233
My server is pretty standard; ubuntu LAMP. Codeigniter is pretty standard too and I have no problem running non CI scripts via command line
My PHP binary is only located in /usr/bin/php <-- This post suggests an issue running CI directly from usr/bin/php, however I'm not operating a shared PHP service, and I don't see why this would make a difference to how PHP executes a CI script.
Any help or just an indication on how to debug this would be greatly appreciated.
Thanks in advance.
Solved! (partly) the issue was CodeIgniters error logging.
In application/config/config.php, I modified the following config property:
$config['log_threshold'] = 0;
This disables logging, and allows $ php index.php to execute.
If anyone can explain why CI only shows this error on CLI PHP - might help anyone else who has this issue and needs it resolved with error logging on.
To solve error "Class 'CI_Controller' not found" try going to Application -> Config -> database.php then check the database details like hostname, username, password and database.
To Mijahn:
I had this same problem, and after about two hours of tracing through code to figure out the problem, it seems that there is some sort of conflict with loading the CI_Controller when utilizing the native PHP load_class function.
I worked around this issue by making the following changes to the Common.php file (hack, I know).
//$_log =& load_class('Log');
require_once('system/libraries/Log.php');
$_log = new CI_Log();
My logs then where created exactly like I wanted. Hope this hack helps.
This site says to run codeigniter from the command line, one must set the $_SERVER['PATH_INFO'] variable.
$_SERVER['PATH_INFO'] is usually supplied by php when a web request is made. However, since we are calling this script from the command line, we need to emulate this small part of the environment as a web request.
The answer provided in this Stack Overflow post worked for me.
Within system/core/CodeIgniter.php, on around line 75, change:
set_error_handler('_exception_handler');
to...
set_exception_handler('_exception_handler');
Other users have reported that this gave them a better backtrace with which to debug the underlying issue, but for me, this actually removed the problem altogether.
I would like to try some code snippets (about to make a script) which uses Magento's models and classes.
The problem is that I get the following error:
fdr#fderose-gtrade:/var/www/globaltrade$
fdr#fderose-gtrade:/var/www/globaltrade$ php -a
Interactive shell
php > require './app/Mage.php';
Fatal error: Class 'Mage' not found in /var/www/globaltrade/app/Mage.php on line 31
Line 31 of Mage.php is the following:
Mage::register('original_include_path', get_include_path());
Does anybody have an idea about what could be the cause? Thank you!
According to php.net
Autoloading is not available if using
PHP in CLI interactive mode.
see http://php.net/manual/en/features.commandline.interactive.php for more info (its a note towards the bottom of the description)
At first glance it seems that your issue stems from autoload. When you include your Mage.php file it appears that it then tries to run a php autoload and use the Mage class, but is failing in doing so. It's possible that the way that their autoload is functioning, the paths may not be correct when run from an interactive shell.