PHPUnit: Fatal error Class ClassName not found - php

I'm trying to build a Unit Testing environment for a CodeIgniter application. I'm following this book and got PHPUnit to work.
I'm at a point where I'm testing some code in a model:
public function testPresent()
{
$tracker = new Tracker_model();
$tableObj = (object)array( 'type' => $this->expectedConstants['TABLE']);
$visitsObj = (object)array( 'type' => $this->expectedConstants['VISITS']);
$tableObj = $tracker->present($tableObj);
$visitsObj = $tracker->present($visitsObj);
$this->assertThat($tableObj, $this->isInstanceOf('Tracker_TablePresenter'));
$this->assertThat($visitsObj, $this->isInstanceOf('Tracker_VisitsPresenter'));
}
The code being tested is this:
public function present($obj)
{
if( isset($obj->type) )
{
switch($obj->type)
{
case self::VISITS: $type = 'Visits'; break;
case self::TABLE:
default: $type = 'Table'; break;
}
$className = 'Tracker_'.$type.'Presenter';
$obj = new $className($obj, 'tracker');
}
return $obj;
}
It should load the class Tracker_TablePresenter which is in the file presenters/tracker/TablePresenter.php. I can't explain all the logic behind this mechanism because it would be too long and complex, but I know it works, because on another computer with the exact same code it's passing the test. On my computer, instead, I get this error:
.......PHP Fatal error: Class 'Tracker_TablePresenter' not found in /home/.../application/models/tracker_model.php on line 42
More information on the error:
PHP Stack trace:
PHP 1. {main}() /.../vendor/phpunit/phpunit/composer/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main() /.../vendor/phpunit/phpunit/composer/bin/phpunit:63
PHP 3. PHPUnit_TextUI_Command->run() /.../vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:129
PHP 4. PHPUnit_TextUI_TestRunner->doRun() /.../vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:176
PHP 5. PHPUnit_Framework_TestSuite->run() /.../vendor/phpunit/phpunit/PHPUnit/TextUI/TestRunner.php:349
PHP 6. PHPUnit_Framework_TestSuite->run() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:705
PHP 7. PHPUnit_Framework_TestSuite->runTest() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:745
PHP 8. PHPUnit_Framework_TestCase->run() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:775
PHP 9. PHPUnit_Framework_TestResult->run() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:776
PHP 10. PHPUnit_Framework_TestCase->runBare() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestResult.php:648
PHP 11. PHPUnit_Framework_TestCase->runTest() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:831
PHP 12. ReflectionMethod->invokeArgs() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:976
PHP 13. Tracker_modelTest->testPresent() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:976
PHP 14. Tracker_model->present() /.../application/tests/models/Tracker_modelTest.php:38
I'm working on Ubuntu, while the other guy who has the code working is using a Mac. This is the output of my php -v
PHP 5.4.9-4ubuntu2 (cli) (built: Mar 11 2013 16:09:26)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
with Xdebug v2.3.0dev, Copyright (c) 2002-2013, by Derick Rethans
I also tried downgrading php to 5.3, since he is using the 5.3, but nothing. Same error.
Can you help me understanding what's going on?
Edit:
This is the content of the file TablePresenter.php
<?php
class Tracker_TablePresenter extends Presenter
{
public function values()
{
$this->ci =& get_instance();
if (!isset($this->values)) {
$this->ci->load->model('value_model', 'value');
$this->values = $this->ci->value->getManyForTracker($this->tracker->id);
}
return $this->values;
}
}
?>
Edit 2:
I changed the code in the present function as suggested by JoDev like this:
public function present($obj)
{
if( isset($obj->type) )
{
switch($obj->type)
{
case self::VISITS: $type = 'Visits'; break;
case self::TABLE:
default: $type = 'Table'; break;
}
//use include, but require is to force an internal error if the file isn't founded!
require_once('presenters/tracker/'.$type.'Presenter.php');
$className = 'Tracker_'.$type.'Presenter';
$obj = new $className($obj, 'tracker');
}
return $obj;
}
Now I get this error:
PHPUnit 3.7.21 by Sebastian Bergmann.
Configuration read from .../phpunit.xml
.......PHP Fatal error: Class 'Tracker_TablePresenter' not found in .../application/models/tracker_model.php on line 61
PHP Stack trace:
PHP 1. {main}() .../vendor/phpunit/phpunit/composer/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main() .../vendor/phpunit/phpunit/composer/bin/phpunit:63
PHP 3. PHPUnit_TextUI_Command->run() .../vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:129
PHP 4. PHPUnit_TextUI_TestRunner->doRun() .../vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:176
PHP 5. PHPUnit_Framework_TestSuite->run() .../vendor/phpunit/phpunit/PHPUnit/TextUI/TestRunner.php:349
PHP 6. PHPUnit_Framework_TestSuite->run() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:705
PHP 7. PHPUnit_Framework_TestSuite->runTest() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:745
PHP 8. PHPUnit_Framework_TestCase->run() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:775
PHP 9. PHPUnit_Framework_TestResult->run() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:776
PHP 10. PHPUnit_Framework_TestCase->runBare() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestResult.php:648
PHP 11. PHPUnit_Framework_TestCase->runTest() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:831
PHP 12. ReflectionMethod->invokeArgs() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:976
PHP 13. Tracker_modelTest->testPresent() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:976
PHP 14. Tracker_model->present() .../application/tests/models/Tracker_modelTest.php:37
<h4>A PHP Error was encountered</h4>
<p>Severity: Warning</p>
<p>Message: include(presenters/tracker/TablePresenter.php): failed to open stream: No such file or directory</p>
<p>Filename: models/tracker_model.php</p>
<p>Line Number: 58</p>
</div><div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">
<h4>A PHP Error was encountered</h4>
<p>Severity: Warning</p>
<p>Message: include(): Failed opening 'presenters/tracker/TablePresenter.php' for inclusion (include_path='.../vendor/phpunit/php-text-template:.../vendor/phpunit/phpunit-mock-objects:.../vendor/phpunit/php-timer:.../vendor/phpunit/php-token-stream:.../vendor/phpunit/php-file-iterator:.../vendor/phpunit/php-code-coverage:.../vendor/phpunit/phpunit:.../vendor/symfony/yaml:.../vendor/pdepend/pdepend/src/main/php:.../vendor/phpmd/phpmd/src/main/php:.:/usr/share/php:/usr/share/pear')</p>
<p>Filename: models/tracker_model.php</p>
<p>Line Number: 58</p>
</div>%

Please, can you try to include the class manualy by using :
public function present($obj)
{
if( isset($obj->type) )
{
switch($obj->type)
{
case self::VISITS: $type = 'Visits'; break;
case self::TABLE:
default: $type = 'Table'; break;
}
//use include, but require is to force an internal error if the file isn't founded!
require_once('Presenters/Tracker/'.$type.'Presenter.php');
$className = 'Tracker_'.$type.'Presenter';
$obj = new $className($obj, 'tracker');
}
return $obj;
}
Thank's to this test, you will be able to know if the error is in the autoloader or anywhere else!
And tell me what appends...
[EDIT #13/06/2013 10:00]
Where is the file calling TablePresenter in the tree?
To fix the problem, you have (in my opinion) three possibilities :
-1) Add parent directory of Presenter in the include_path of the serveur!
(to retrieve actual includings, use get_include_path())
-2) Be sure to use good URL to include the file
-3) Use absolute URL

I bet it has to do with file permissions on your machine. The script can't find the file because Apache can't open it.

Sounds like a case-sensitiveness issue (#jospratik 's question). As far as i know OSX is not case sensitive. So this is an issue you would have when working on linux vs mac/win.
Change the folder names to start with uppercase char like
Presenters/Tracker/VisitsPresenter.php

seems to me like a problem with Class 'Tracker_TablePresenter' which couldnt be found. did you use the correct namespace?

Related

PHP str_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated

I'm getting this error while running my app:
PHP str_replace(): Passing null to parameter #3 ($subject) of type
array|string is deprecated
I am Using CodeIgniter Version : V4.1.8 PHP Version : 8.1.2, full error output below:
{"data":[
["omron","<span class=\"label label-success\">Active<\/span>",
"<button type=\"button\" class=\"btn btn-default\" onclick=\"editBrand(4)\" data-toggle=\"modal\" data-target=\"#editBrandModal\"><i class=\"fa fa-pencil\"><\/i><\/button> <button type=\"button\" class=\"btn btn-default\" onclick=\"removeBrand(4)\" data-toggle=\"modal\" data-target=\"#removeBrandModal\"><i class=\"fa fa-trash\"><\/i><\/button>\n\t\t\t\t"]
]
}
<div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">
<h4>A PHP Error was encountered</h4>
<p>Severity: 8192</p>
<p>Message: str_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated</p>
<p>Filename: core/Output.php</p>
<p>Line Number: 457</p>
<p>Backtrace:</p>
UPDATE: Code
if ($this->parse_exec_vars === TRUE)
{
$memory = round(memory_get_usage() / 1024 / 1024, 2).'MB';
// below is line 457
$output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
}
Using a ternary operator will fix this error.
Before Codeigniter existing code:
$output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
Hopefully, it's will work fine as we will escape str_replace for a null value.
After Using Ternary Operator:
$output = $output ? str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output): "";
This error message can show up if you have not loaded any views. Codeigniter's internal output buffer is never initialized thus being null. The output buffer is the third parameter to str_replace(). There might be other ways to trigger this error message.
You probably want to load a valid view, at some point.
PHP 7 and lower just would ignore the missing parameter, while PHP 8+ displays the warning. It may also vary with your environment / debug settings.
I also faced same issue just used these lines in your Controller constructor method
public function __construct()
{
parent::__construct();
error_reporting(0);
$this->load->library("session");
$this->load->helper('url');
}
i think i found the issue , it is not a direct problem from str_replace() function , codeigniter written this perfectly , but you are using strip_quotes() function somewhere , and you are passing directly something to it like :
$d= strip_quotes($this->input->post('thusnder'));
if it is , then you must update your code by adding this :
$d= strip_quotes($this->input->post('thusnder') ?? '');
this will prevent data to be null and then it will not be passed to the strip_quotes() function which uses str_replace()
hope it will be helpful for someone.
Another option is to check $output in the existing if statement. That will skip the entire block of code that isn't needed when $output is NULL or empty.
if ($this->parse_exec_vars === TRUE && !empty($output))
{
$memory = round(memory_get_usage() / 1024 / 1024, 2).'MB';
// below is line 457
$output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
}
You can user this code to get rid of it:
$output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), (string) $output );
I have had such an error
This is the only way to get rid of the error. That you PHP 7 & 8 install you'r System
php install in c/:xampp & c/:xampp2 installed.
beacuse difrant drive in error occuerd
And
Benefit in other programs
Multiple xampp installations windows
I Have downgraded my CI version to 3 and PHP verison to 7.3
Its working now

PHP Deprecated: Automatic conversion of false to array is deprecated adodb-mssqlnative.inc.php on line 154

We are upgrading PHP to version 8.1. Using MS Sql Server DB. It all seems to work correctly but I see repeated messages in the log file:
[03-Feb-2022 11:51:18 America/New_York] PHP Deprecated: Automatic conversion of false to array is deprecated in C:...\includes\adodb\drivers\adodb-mssqlnative.inc.php on line 154
I've updated adodb to version version 5.22 but that did not stop the messges from logging. The ini file has
extension=php_sqlsrv_81_nts_x64.dll
extension=php_pdo_sqlsrv_81_nts_x64.dll
Does anyone know how to fix this problem?
This is a known issue of backwards incompatibility, affecting the ADOdb library version 5.22.1 and older. PHP 8.1 warns you on autovivification of false-y values and some future version of PHP will throw an error when you do it.
PHP natively allows for autovivification (auto-creation of arrays from falsey values). This feature is very useful and used in a lot of PHP projects, especially if the variable is undefined. However, there is a little oddity that allows creating an array from a false and null value.
And they give this example
// From false
$arr = false;
$arr[] = 2;
I went and found the file in question and this is the function it's in
function ServerInfo() {
global $ADODB_FETCH_MODE;
static $arr = false;
if (is_array($arr))
return $arr;
if ($this->fetchMode === false) {
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
} elseif ($this->fetchMode >=0 && $this->fetchMode <=2) {
$savem = $this->fetchMode;
} else
$savem = $this->SetFetchMode(ADODB_FETCH_NUM);
$arrServerInfo = sqlsrv_server_info($this->_connectionID);
$ADODB_FETCH_MODE = $savem;
$arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];
$arr['version'] = $arrServerInfo['SQLServerVersion'];//ADOConnection::_findvers($arr['description']);
return $arr;
}
The problem is that it starts with
static $arr = false;
and then tries to autovivificate a non-array (line 154 in your error)
$arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];
You should be able to fix it (in theory) by making sure it's an array (something they should have done anyways). Add this above that line to make it one before it tries to append
if(!is_array($arr)) $arr = [];

PHP Fatal error: Class 'SmartySecurity' not found

Been pulling my hair for 2 hours on this Smarty 2.6 to Smarty 3.1 upgrade task for that old website. The reason is that the host is now PHP 7 only. No more PHP 5. I thought it would be a 1 hour deal, but it's quickly turning into a nightmare. I remember using Smarty back in 2005 and I've never used it ever again, but today, nearly 15 years later, this monstrosity of a template engine is haunting me back!
Here's the init PHP file's contents:
<?php
#Load Smarty library
#require_once("php/Smarty-2.6.26/libs/Smarty.class.php");
#require_once("php/smarty-3.1.34/libs/Smarty.class.php");
require_once("php/smarty-3.1.34/libs/SmartyBC.class.php");
require_once("php/smarty-3.1.34/libs/sysplugins/smarty_security.php");
class class_init extends SmartyBC {
function __construct(){
#Init
parent::__construct();
#Directories
$this->template_dir = "skin/".SKIN."/public/";
$this->compile_dir = "skin/".SKIN."/compile/";
$this->config_dir = "skin/".SKIN."/config/";
$this->cache_dir = "skin/".SKIN."/cache/";
#Caching
$this->caching = (boolean)SMARTY_CACHING;
$this->cache_lifetime = (int)SMARTY_CACHE_LIFETIME;
$this->debugging = true;
}
function is_cached($str_tpl, $cache_id = NULL, $compile_id = NULL){
return $this->isCached($str_tpl, $cache_id, $compile_id);
}
}
class MySecurity extends SmartySecurity {
public $secure_dir = array('/home/lesclownsducarro/public_html/');
public function __construct(Smarty $smarty){
parent::__construct($smarty);
}
}
?>
Here's the controller file's contents:
require_once("./php/class/init.php");
$_ENV['class_init'] = new class_init();
$securityPolicy = new Smarty_Security($_ENV['class_init']);
$securityPolicy->php_handling = \Smarty::PHP_ALLOW;
$_ENV['class_init']->enableSecurity($securityPolicy);
Getting a completely blank page and the error_log simply states:
[30-Dec-2019 22:22:40 UTC] PHP Fatal error: Class 'SmartySecurity' not found in /home/xxxxx/public_html/php/class/init.php on line 32
FOR BACKWARDS COMPATIBILITY, I need to use SmartyBC because the template is including PHP files all over the place. inb4 yes I know, and this is not my website.
Any ideas ?
DOH. Welp, I'm just too tired, it seems.
It should obviously be: $securityPolicy = new Smarty_Security($_ENV['class_init']);
...with the underscore. I don't know, I copy/pasted the example from smarty.net without paying any attention at all. "new SmartySecurity" as seen here: https://www.smarty.net/forums/viewtopic.php?p=72741
JFC.

Illegal string offset in PHP 5.4

The following code works in a computer with PHP 5.3 and it doesn't in PHP 5.4:
function __clone() {
$this->changed = TRUE;
foreach ($this->conditions as $key => $condition) {
if (
$condition['field']
instanceOf QueryConditionInterface) {
$this->conditions[$key]['field'] = clone($condition['field']);
}
}
}
$condition in both cases doesn't have the 'field' offset, but in PHP 5.3 the library continues working without complain, however in PHP 5.4 gives this warning message:
Warning: Illegal string offset 'field' in DatabaseCondition->__clone()
And short after, the library (from Drupal6), stops working.
Any idea how to fix this?
Should I use an isset($condition['field']) even if it's a core library of the framework?

CakePHP cakeshell errors "A Notice: Uninitialized string offset: 0 in"

I am trying to run my cake shell script but the output looks like the following:
-bash-3.2$ ../cake/console/cake audit
../cake/console/cake: line 30:/root/site/app: is a directory
Array
(
[0] => /root/site/cake/console/cake.php
[1] => -working
[2] =>
[3] => audit
)
Notice: Uninitialized string offset: 0 in /root/site/cake/console/cake.php on line 550
What am I doing wrong? Here are the contents of this file:
cake.php
function __parseParams($params) {
$count = count($params);
for ($i = 0; $i < $count; $i++) {
if (isset($params[$i])) {
if ($params[$i]{0} === '-') {
$key = substr($params[$i], 1);
$this->params[$key] = true;
unset($params[$i]);
if (isset($params[++$i])) {
if ($params[$i]{0} !== '-') {//This is line 550
$this->params[$key] = str_replace('"', '', $params[$i]);
unset($params[$i]);
} else {
$i--;
$this->__parseParams($params);
}
}
} else {
$this->args[] = $params[$i];
unset($params[$i]);
}
}
}
}
Focus on the first error
Whenever debugging something that's broken, it's a good idea to focus on the first error and not the fallout from it. The first error message is this line:
line 30:/root/site/app: is a directory
It comes from the cake bash script, before calling php. That line in the most recent 1.3 version is blank, so it's not obvious what specific version of cake you are using, but it isn't the latest 1.3 release.
The consequence of the above error is that the following is the command called:
exec php -q "/root/site/cake/console/"cake.php -working "" "audit"
^^
The parameters passed to cake.php specify that the working directory is an empty string, something which is abnormal and later causes an undefined index error.
Upgrading cures all ailes
Most likely, this specific error can be solved by copying cake.php from the latest version of the same release cycle you are using.
Also consider simply upgrading CakePHP itself to the latest release (from the same major version in use) which will likely fix this specific problem, and others - especially relevant if there have been security releases, which recently there have been.

Categories