Maybe PHP eval scope thing? - php

I'm having an issue with the following code. I'm just guessing it's a scope problem.
public function run() {
return eval('$this->config();');
// This will return null.
return $this->config();
// This will return my config array right.
}
Before anyone asks:
Not both return are 'active' when testing.
I know eval is evil, but i'm building some kind of terminal for admins to run PHP code.
Do anyone have any suggestions about this terminal thing? (My basic problem is still with the eval...)

eval is returning NULL because that is what it is suppose to do. Right from the documentation page:
eval() returns NULL unless return is called in the evaluated code, in which case the value passed to return is returned.

Related

I am getting: "Non-static method Inflector::singularize() should not be called statically" when running MySQLConnector.php

I am trying to setup OData connection to MySQL database .. when I run the MySQLConnector.php , I am getting the above error.. can someone please direct me towards a solution.
The statement that gives the error is:
public function getEntityTypeName($entity)
{
return \Inflector::singularize($entity);
}
Following is the code in Inflector.php:
function singularize($word) {
$_this =& Inflector::getInstance();
if (isset($_this->_singularized[$word])) {
return $_this->_singularized[$word];
}
Please let me know if you would need any further information. Thanks in advance.
The short answer is: you need to update both of them. It looks like you have an older Inflector which is relying on deprecated PHP behaviour, and it's likely that your MySQLConnector.php is also old. If you don't update, you'll likely hit further problems.
In this case, PHP is complaining that you're using a static call to a method which is missing the "static" keyword. It's very likely that this message is a warning not an error, so it probably isn't causing whatever end problem you're experiencing. If you really want to address this message, you can just write static public function singularize($word) { instead, but like I said you will have more problems.

PHP: call a function from another function (out of scope?)

I'm having a problem creating webservices through nuSOAP (although i believe my problem has nothing to do with it)
What i'm trying to do:
function loadActiveItems() {
$list = Item::loadActive();
$ret = array();
foreach ($list as $val){
//two tests to check if i really have an object and if the toDTO method is callable
echo var_dump($val);
echo is_callable(array($val, 'toDTO'));
array_push($ret, $val->toDTO());
}
unset($val);
return $ret;
}
I'm getting the following error:
Call to a member function toDTO() on a non-object
and both var_dump($val) and is_callable are returning the expected (the object and true, respectively) from what i've been seeing online, it appears i have a out of scope problem... but for some reason i don't seem to get my head around it :P
Thanks in advance
EDIT: well just check that apparently i don't understand is_callable either because i always get 1 as the result...
EDIT2: i'm using php-activerecord if that helps in any way
toDTO() may be undefined in your class Item.
Another reason may be that the method isn't public or as #Grep said` static.
This error never happens on an object that defines the method but it is static or protected/private:
Call to a member function toDTO() on a non-object
That error only happens if $val is not an object. Usually a NULL, FALSE or other scalar.
It's usually a FALSE when the object came for a db_fetch() function but the fetch or the query before it failed.
It's usually a NULL when you have an array that may have NULLs in it.
var_dump($list) and see what's in there and if there are any NULLs. Also change your foreach to have a $key and var_dump($key) as well to see which key is dumped last before the error is issued.
Okay so i figured out the problem... thanks for all the help!
I was calling toDTO of another object inside toDTO... problem was that object could be a null!
So a simple if(object==null) solved the problem!
Thanks again!

Strange behavior in a codeigniter library

I've made an incredibly basic library, with a single function to check if the user is logged in now or not.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Lib {
public function is_logged_in()
{
$CI =& get_instance();
if($CI->session->userdata('uid') === FALSE)
{
return FALSE;
}
else
{
return TRUE;
}
}
}
/* End of file Lib.php */
If I call the function from a controller, the code is definitely run and when not logged in it makes it into the if statement. I can add an echo to test that the code is definitely executed, but never is anything returned. If I change the return to a number, nothing is returned. If I change the return to a string, then and only then is stuff actually returned. I'm calling the function like $this->lib->is_logged_in(), and have added the library to the autoload.php file.
The return is definitely executed as the function is exited. error reporting is set to E_ALL. Why in the heck won't this work?
(also yes I do realize the function isn't complete and secure yet.)
How are you determining that the return is executed? – NullUserException
#NullUserException: The code block exits. I can echo prior to either return and it will run, I can echo after either and it will not. – Cyclone
If you are trying to echo something after the return in your function, it will not work by design, I think this is probably universal to all languages. Anything after the return will not be executed. It will be parsed, but not executed.
var_dump($this->lib->is_logged_in()) should give you bool(true) or bool(false), or a "Trying to get property of non-object" error if lib is not loaded correctly.
Unless there is something you aren't sharing with us, the function should work as expected.
If you're still in doubt, assign the return value to a variable, then var_dump() the variable before you return it. Should be the same result.
EDIT: Sorry, I missed this in the long stream of comments:
var_dump() reveals that false is indeed being returned, why can't I simply echo it
I don't believe that echo'ing FALSE should give you any output, but echoing TRUE should give you 1.
This also has nothing to do specifically with Codeigniter.
For all practical purposes, there's no good reason to echo the return value of this function, or really anything where you expect a boolean return value. If it is returning the value you expect, then it is working.

UnitTests fail, manual test passes

There is something weird going on in my code so i have to ask.
I have a part of a test:
public function testGetAddresses()
{
//$this->markTestIncomplete('Not implemented yet');
$this->assertTrue($this->_prs->getAddresses() instanceof Crm_Collection);
}
This test fails.
But when I do this:
if ($entity->getAddresses() instanceof Crm_Collection) {
echo "TRUE!";
} else {
echo "FALSE!";
}
It outputs TRUE!
Anybody knows what is going on or might this be a bug in phpunit?
Thanks!
I doubt this is a PHPUnit's bug.
Since you call getAddresses() method on two different objects I guess that in test that fails this method really returns something which is not Crm_Collection.
Is there a chance that getAddresses() method could return null or throw an exception?
Why vadimbelyaev said:
I don't think it's an issue with phpunit, doublecheck your code.
Additionally you can use:
$this->assertType("Classname", $object)
so you get a nice error in case it fails.
(Phpunit will tell you "expected class, got null" instead of "expected true, got false" with helps a lot while debugging :) )
Are other tests OK? Do you run the tests from a browser?
When you run PHP code from commandline I strongly recommend to set a correct path to php.ini. Otherwise PHP will use default values which might be different from your current php.ini
Not sure if this will solve your trouble but it's good to know. Once I spend couple of hours before I found this out.
php -c "c:/program files/apache software foundation/Apache2.2/" -f /path/to/your/script.php

Multiple return values to indicate success/failure.

I'm kind of interested in getting some feedback about this technique I picked up from somewhere.
I use this when a function can either succeed or fail, but you'd like to get more information about why it failed. A standard way to do this same thing would be with exception handling, but I often find it a bit over the top for this sort of thing, plus PHP4 does not offer this.
Basically the technique involves returning true for success, and something which equates to false for failure. Here's an example to show what I mean:
define ('DUPLICATE_USERNAME', false);
define ('DATABASE_ERROR', 0);
define ('INSUFFICIENT_DETAILS', 0.0);
define ('OK', true);
function createUser($username) {
// create the user and return the appropriate constant from the above
}
The beauty of this is that in your calling code, if you don't care WHY the user creation failed, you can write simple and readable code:
if (createUser('fred')) {
// yay, it worked!
} else {
// aww, it didn't work.
}
If you particularly want to check why it didn't work (for logging, display to the user, or do whatever), use identity comparison with ===
$status = createUser('fred');
if ($status) {
// yay, it worked!
} else if ($status === DUPLICATE_USERNAME) {
// tell the user about it and get them to try again.
} else {
// aww, it didn't work. log it and show a generic error message? whatever.
}
The way I see it, the benefits of this are that it is a normal expectation that a successful execution of a function like that would return true, and failure return false.
The downside is that you can only have 7 "error" return values: false, 0, 0.0, "0", null, "", and (object) null. If you forget to use identity checking you could get your program flow all wrong. Someone else has told me that using constants like an enum where they all equate to false is "ick".
So, to restate the question: how acceptable is a practise like this? Would you recommend a different way to achieve the same thing?
I agree with the others who have stated that this is a little on the WTFy side. If it's clearly documented functionality, then it's less of an issue, but I think it'd be safer to take an alternate route of returning 0 for success and integers for error codes. If you don't like that idea or the idea of a global last error variable, consider redefining your function as:
function createUser($username, &$error)
Then you can use:
if (createUser('fred', $error)) {
echo 'success';
}
else {
echo $error;
}
Inside createUser, just populate $error with any error you encounter and it'll be accessible outside of the function scope due to the reference.
As long as it's documented and contracted, and not too WTFy, then there shouldn't be a problem.
Then again, I would recommend using exceptions for something like this. It makes more sense. If you can use PHP5, then that would be the way to go. Otherwise you don't have much choice.
A more common approach I have seen when exceptions aren't available is to store the error type in a 'last_error' variable somewhere and then when a failure happens (ie it returns false) look up the error.
Another approach is to use the venerable unix tool approach numbered error codes - return 0 for success and any integer (that maps to some error) for the various error conditions.
Most of these suffer in comparison to exceptions when I've seen them used however.
Just to respond to Andrew's comment -
I agree that the last_error should not be a global and perhaps the 'somewhere' in my answer was a little vague - other people have suggested better places already so I won't bother to repeat them
how acceptable is a practice like this?
I'd say it's unacceptable.
Requires the === operator, which is very dangerous. If the user used ==, it leads to a very hard to find bug.
Using "0" and "" to denote false may change in future PHP versions. Plus in a lot of other languages "0" and "" does not evaluate to false which leads to great confusion
Using getLastError() type of global function is probably the best practice in PHP because it ties in well with the language, since PHP is still mostly a procedural langauge. I think another problem with the approach you just gave is that very few other systems work like that. The programmer has to learn this way of error checking which is the source of errors. It's best to make things work like how most people expect.
if ( makeClient() )
{ // happy scenario goes here }
else
{
// error handling all goes inside this block
switch ( getMakeClientError() )
{ case: // .. }
}
Often you will return 0 to indicate success, and 1, 2, 3, etc. to indicate different failures. Your way of doing it is kind of hackish, because you can only have so many errors, and this kind of coding will bite you sooner or later.
I like defining a struct/object that includes a Boolean to indicate success, and an error message or other value indicate what kind of error occurred. You can also include other fields to indicate what kind of action was executed.
This makes logging very easy, since you can then just pass the status-struct into the logger, and it will then insert the appropriate log entry.
Reinventing the wheel here. Using squares.
OK, you don't have exceptions in PHP 4. Welcome in the year 1982, take a look at C.
You can have error codes. Consider negative values, they seem more intuitive, so you would just have to check if (createUser() > 0).
You can have an error log if you want, with error messages (or just arbitrary error codes) pushed onto an array, dealt with elegance afterwards.
But PHP is a loosely typed language for a reason, and throwing error codes that have different types but evaluate to the same "false" is something that shouldn't be done.
What happens when you run out of built-in types?
What happens when you get a new coder and have to explain how this thing works? Say, in 6 months, you won't remember.
Is PHP === operator fast enough to get through it? Is it faster than error codes? or any other method?
Just drop it.
When exceptions aren't available, I'd use the PEAR model and provide isError() functionality in all your classes.
Ick.
In Unix pre-exception this is done with errno. You return 0 for success or -1 for failure, then you have a value you can retrieve with an integer error code to get the actual error. This works in all cases, because you don't have a (realistic) limit to the number of error codes. INT_MAX is certainly more than 7, and you don't have to worry about the type (errno).
I vote against the solution proposed in the question.
It does make sense that a successful execution returns true. Handling generic errors will be much easier:
if (!createUser($username)) {
// the dingo ate my user.
// deal with it.
}
But it doesn't make sense at all to associate meaning with different types of false. False should mean one thing and one thing only, regardless of the type or how the programming language treats it. If you're going to define error status constants anyway, better stick with switch/case
define(DUPLICATE_USERNAME, 4)
define(USERNAME_NOT_ALPHANUM, 8)
switch ($status) {
case DUPLICATE_USERNAME:
// sorry hun, there's someone else
break;
case USERNAME_NOT_ALPHANUM:
break;
default:
// yay, it worked
}
Also with this technique, you'll be able to bitwise AND and OR status messages, so you can return status messages that carry more than one meaning like DUPLICATE_USERNAME & USERNAME_NOT_ALPHANUM and treat it appropriately. This isn't always a good idea, it depends on how you use it.
I like the way COM can handle both exception and non-exception capable callers. The example below show how a HRESULT is tested and an exception is thrown in case of failure. (usually autogenerated in tli files)
inline _bstr_t IMyClass::GetName ( ) {
BSTR _result;
HRESULT _hr = get_name(&_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _bstr_t(_result, false);
}
Using return values will affect readability by having error handling scattered and worst case, the return values are never checked by the code. That's why I prefer exception when a contract is breached.
If you really want to do this kind of thing, you should have different values for each error, and check for success. Something like
define ('OK', 0);
define ('DUPLICATE_USERNAME', 1);
define ('DATABASE_ERROR', 2);
define ('INSUFFICIENT_DETAILS', 3);
And check:
if (createUser('fred') == OK) {
//OK
}
else {
//Fail
}
Other ways include exceptions:
throw new Validation_Exception_SQLDuplicate("There's someone else, hun");),
returning structures,
return new Result($status, $stuff);
if ($result->status == 0) {
$stuff = $result->data;
}
else {
die('Oh hell');
}
I would hate to be the person who came after you for using the code pattern you suggested originally.
And I mean "Came after you" as in "followed you in employment and had to maintain the code" rather than "came after you" "with a wedgiematic", though both are options.
In my opinion, you should use this technique only if failure is a "normal part of operation" of your method / function. For example, it's as probable that a call suceeds as that it fails. If failure is a exceptional event, then you should use exception handling so your program can terminate as early and gracefully as possible.
As for your use of different "false" values, I'd better return an instance of a custom "Result"-class with an proper error code. Something like:
class Result
{
var $_result;
var $_errormsg;
function Result($res, $error)
{
$this->_result = $res;
$ths->_errorMsg = $error
}
function getResult()
{
return $this->_result;
}
function isError()
{
return ! ((boolean) $this->_result);
}
function getErrorMessage()
{
return $this->_errorMsg;
}
Look at COM HRESULT for a correct way to do it.
But exceptions are generally better.
Update: the correct way is: define as many error values as you want, not only "false" ones. Use function succeeded() to check if function succeeded.
if (succeeded(result = MyFunction()))
...
else
...

Categories