Strict standards non static method - php

I want to fix this error:
Strict Standards: Non-static method
Gpf_Settings_Regional::getInstance() should not be called statically,
assuming $this from incompatible context on line 39
The code producing it:
$this->addValue(Gpf_Settings_Gpf::REGIONAL_SETTINGS_DECIMAL_SEPARATOR,
Gpf_Settings_Regional::getInstance()->getDecimalSeparator());
I know this is method for PHP 5.3, but I have 5.4 on shared hosting and need to call static on PHP 5.4

Problem:
You are accessing a non-static method statically with strict standards error reporting switched on.
Solutions:
You can update Gpf_Settings_Regional class
change
public function getInstance()
to
public static function getInstance()
If you are unable to change that class you can change error reporting and switch of reporting of strict standards errors, but it would be better to improve the code.
How to eliminate php5 Strict standards errors?

if i see good it's already made it by script
*/
private static $instance;
public static function create(Gpf_Application $application) {
setlocale(LC_ALL, 'en.UTF-8');
self::$instance = $application;
self::$instance->registerRolePrivileges();
self::$instance->initLogger();
self::$instance->addSmartyPluginsDir();
$timezone = Gpf_Settings_Gpf::DEFAULT_TIMEZONE;
try {
$timezone = Gpf_Settings::get(Gpf_Settings_Gpf::TIMEZONE_NAME);
} catch (Gpf_Exception $e) {
Gpf_Log::error('Unable to load timezone: %s - using default one.', $e->getMessage());
}
if(false === #date_default_timezone_set($timezone)) {
Gpf_Log::error('Unable to set timezone %s:', $timezone);
}
}
public function getDefaultLanguage() {
return 'en-US';
}
/**
* #return Gpf_Application
*/
public static function getInstance() {
if(self::$instance === null) {
throw new Gpf_Exception('Application not initialize');
}
return self::$instance;
}
and this is part where problem is
abstract class Gpf_ApplicationSettings extends Gpf_Object {
/**
* #var Gpf_Data_RecordSet
*/
private $recordSet;
const CODE = "code";
const VALUE = "value";
protected function loadSetting() {
$this->addValue("theme", Gpf_Session::getAuthUser()->getTheme());
$this->addValue("date_time_format", 'MM/d/yyyy HH:mm:ss');
$this->addValue("programVersion", Gpf_Application::getInstance()->getVersion());
$this->addValue(Gpf_Settings_Gpf::NOT_FORCE_EMAIL_USERNAMES, Gpf_Settings::get(Gpf_Settings_Gpf::NOT_FORCE_EMAIL_USERNAMES));
$quickLaunchSettings = new Gpf_Desktop_QuickLaunch();
$this->addValue(Gpf_Desktop_QuickLaunch::SHOW_QUICK_LAUNCH, $quickLaunchSettings->getShowQuickLaunch());
$this->addValue(Gpf_Settings_Gpf::REGIONAL_SETTINGS_THOUSANDS_SEPARATOR,
Gpf_Settings_Regional::getinstance()->getThousandsSeparator());
$this->addValue(Gpf_Settings_Gpf::REGIONAL_SETTINGS_DECIMAL_SEPARATOR, Gpf_Settings_Regional::getInstance()->getDecimalSeparator());
$this->addValue(Gpf_Settings_Gpf::REGIONAL_SETTINGS_DATE_FORMAT, Gpf_Settings_Regional::getInstance()->getDateFormat());
$this->addValue(Gpf_Settings_Gpf::REGIONAL_SETTINGS_TIME_FORMAT, Gpf_Settings_Regional::getInstance()->getTimeFormat());
Gpf_Plugins_Engine::extensionPoint('Core.loadSetting', $this);
}

Related

PHP 8 migration Fatal error: Declaration must be compatible

We are moving forward to PHP 8 from PHP 7.4, we are facing Declaration must be compatible Fatal error in our code to custom parameter type, we need a proper solution with less code changes.
Kindly refer below code snippet
ERROR
Fatal error: Declaration of ClientReactieView::getUrlAddData(?ClientReactie $clientReactie = null) must be compatible with Overview\BaseView::getUrlAddData(?Storm\Model $model = null) in /var/www/html/system/tmp/class_client_reactie_view.php on line 102
abstract class file : abstract_class_base_view.php
<?php
namespace Overview;
use Storm;
abstract class BaseView {
public static function getUrlAddData(Storm\Model $model = null){
// ...
return $urlAddData;
}
}
Child class file : class_client_reactie_view.php
<?php
class ClientReactieView extends Overview\BaseView {
public static function getUrlAddData(ClientReactie $clientReactie = null){
// ...
return $urlAddData;
}
}
Custom parameter type class_client_reactie.php
class ClientReactie extends Storm\Model {
// ...
}
Our application is already developed & working fine with PHP 7.4, We require solution to resolve this fatal error with less code changes
The error is telling your code is illogical.
The definition of BaseView makes a promise: you can call getUrlAddData and pass any instance of Storm\Model, or null.
The definition of ClientReactieView says that it extends BaseView, so inherits that promise. But then it changes that promise: you can call getUrlAddData, but you're not allowed to pass anything that's not a ClientReactie.
This is "covariance of input", and has always been forbidden for non-static methods - if $foo instanceof BaseView is true, then $foo->getUrlAddData(...) would have to accept all values that the definition in BaseView allowed.
What's new in PHP 8 is that this is enforced for static methods as well, so that the same guarantee applies to "late static binding" calls such as this:
abstract class BaseView {
public static function getUrlAddData(Storm\Model $model = null){
// ...
return $urlAddData;
}
public static function doSomethingElse(Storm\Model $model = null){
$urlAddData = static::getUrlAddData($model);
// ...
}
}
class ClientReactieView extends Overview\BaseView {
public static function getUrlAddData(ClientReactie $clientReactie = null){
// ...
return $urlAddData;
}
}
ClientReactieView::doSomethingElse(new Storm\Model);
// ERROR! The call goes to BaseView::doSomethingElse, which accepts any Model
// But static::getUrlAddData resolves to ClientReactieView::getUrlAddData
// and that has an incompatible signature
So the correct fix is to honour the promise made by the parent class:
class ClientReactieView extends Overview\BaseView {
public static function getUrlAddData(Storm\Model $model = null){
if ( ! $model instanceof ClientReactie ) {
// Figure out what to do with such calls
}
// ...
return $urlAddData;
}
}

PHPUnit - ReturnValueMap of Mocks not finding Mocked Class Methods

I'm new to unit testing and have come across something I don't understand when using returnValueMap() in PHPUnit. I've been googling for days now ...
Consider this code under test;
public function __construct(EntityManager $entityManager, AuditLog $auditLog) {
$this->entityManager = $entityManager;
$this->auditLog = $auditLog;
}
public function updateSomeId($oldId, $newId)
{
$repositories = ['repo1', 'repo2', 'repo3'];
foreach ($repositories as $repository) {
try {
$this->entityManager->getRepository($repository)
->updateSomeId($oldId, $newId);
} catch (RepositoryException $e) {
throw new SomeOtherException($e->getMessage(), $e->getCode(), $e);
}
}
}
The unit test code;
... code removed for brevity
$repoMaintenance = new RepoMaintenance(
$this->getEntityManagerMock(),
$this->getAuditLogMock()
);
$this->assertTrue($repoMaintenance->updateSomeId(
$this->oldId,
$this->newId
));
/**
* #return EntityManager
*/
private function getEntityManagerMock()
{
$entityManagerMock = $this->getMockBuilder(EntityManager::class)
->disableOriginalConstructor()
->getMock();
$entityManagerMock
->method('getRepository')
->willReturn($this->returnValueMap($this->getEntityManagerReturnValueMap()));
return $entityManagerMock;
}
/**
* #return array
*/
private function getEntityManagerReturnValueMap()
{
return [
['repo1', $this->getRepo1Mock()],
['repo2', $this->getRepo2Mock()],
['repo3', $this->getRepo3Mock()],
];
}
/**
* #return Repo1
*/
private function getRepo1Mock()
{
return $this->getMockBuilder(Repo1::class)
->disableOriginalConstructor()
->getMock();
}
... Code removed for brevity
When the unit test is run, the following fatal error is returned;
PHP Fatal error: Call to undefined method PHPUnit_Framework_MockObject_Stub_ReturnValueMap::updateSomeId()
I've previously used mocks in return value maps with no issue accessing methods in a public context. The difference is I'm attempting to mock __construct() variables, which are set to private access within the SUT.
What am I missing? The problem (I would naively guess) is with the private access level of the members being mocked.
Is there a way to unit test this code? I don't want to hit the database at any point and this is the reason for mocking the calls to it.
You should have will($this->returnValueMap... instead of willReturn($this->returnValueMap...

Cannot override final method Exception::getPrevious()

I got CMS and trying to install it, but when i try to login i got error
Cannot override final method Exception::getPrevious()
Fatal error: Cannot override final method Exception::getPrevious() in C:\wamp\www\uis-online\application\exceptions\applicationException.php on line 41
Does anyboy have idea what cause this error
code in this file is
class ApplicationException extends Exception
{
protected $innerException;
/**
* Konstruktor
* #return unknown_type
*/
public function __construct($message, $code = 0, Exception $innerException = null)
{
parent::__construct($message, $code);
if (!is_null($innerException))
{
$this->innerException = $innerException;
}
}
public function getPrevious()
{
return $this->innerException;
}
// custom string representation of object
public function __toString() {
$exceptions_message = "";
if($this->innerException != null && $this->innerException->getMessage() != "") {
$exceptions_message = $this->innerException->__toString();
}
return $exceptions_message .__CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
}
As shown in the documentation the method you're trying to override is a final one.
final public Exception Exception::getPrevious ( void )
http://php.net/manual/en/exception.getprevious.php
According to the PHP manual you can't override final methods.
PHP 5 introduces the final keyword, which prevents child classes from overriding a method by prefixing the definition with final. If the class itself is being defined final then it cannot be extended.
http://php.net/manual/en/language.oop5.final.php

Strict standards warning: Singleton implementation with PHP

I have created a logger as a singleton for my PHP application with Zend framework.
Implementation is pretty straight-forward:
class Logger
{
protected static $_logger;
private function __construct()
{
// initialize logger
$writer = new Zend_Log_Writer_Stream(LOG_PATH);
$this->_logger = new Zend_Log($writer);
}
public static function getLogger()
{
if (null === self::$_logger)
{
self::$_logger = new self();
}
return self::$_logger;
}
public static function Log($message, $logType)
{
if ($logType <= LOG_MAX)
{
$logger = self::getLogger();
$logger->_logger->log($message, $logType);
}
}
}
To ad an entry to the log, I just call static method:
Logger::Log('message', Zend_Log::ERR);
Logger works as supposed to, but since I have upgraded my PHP version to 5.4.3 I get an error:
Strict standards: Accessing static property Logger::$_logger as non static in Z:\Software\PHP\EA Game\application\classes\Logger.php on line 28
Line 28 is in function __construct(): $this->_logger = new Zend_Log($writer);
I can always disable E_STRICT, but it is not a preferable option.
I would like to implement Singleton pattern without getting Strict standards warning.
I would be grateful if some could point me in the right direction to implementing Singleton pattern without getting String standards warning.
EDIT:
I used jValdrons advice and replaced $this->_logger to self::$_logger.
I still was getting strict standards warning and I changed Log function to be as follows:
public static function Log($message, $logType)
{
if ($logType <= LOG_MAX)
{
self::getLogger()->log($message, $logType);
}
}
But now I have another problem.
Code does not throw Strict standards warning, but it does not works as supposed to.
I have 2 separate loggers, 1 for application and 1 for crons.
Basically it's just the same code:
2 static variables:
protected static $_logger;
protected static $_cronLogger;
constructor initializes both of them:
private function __construct()
{
// initialize all loggers
$writer = new Zend_Log_Writer_Stream(LOG_PATH);
self::$_logger = new Zend_Log($writer);
$writerCron = new Zend_Log_Writer_Stream(CRON_LOG_PATH);
self::$_cronLogger = new Zend_Log($writerCron);
}
and 2 methods GetCronLogger() and LogCron():
public static function getCronLogger()
{
if (null === self::$_cronLogger)
{
self::$_cronLogger = new self();
}
return self::$_cronLogger;
}
public static function LogCron($message, $logType)
{
if ($logType <= CRON_LOG_MAX)
{
self::getCronLogger()->log($message, $logType);
}
}
But now self::getCronLogger()->log($message, $logType); calls my method Log(), not Zend_log->log() and it will always add records to my main logger, not crons logger.
Am I missing something or calling something in incorrect way?
You're accessing the logger using $this->logger, which is not a static way to access it. Since it's a static variable, you got to use self:: just like you did got getLogger, so:
private function __construct()
{
// initialize logger
$writer = new Zend_Log_Writer_Stream(LOG_PATH);
self::$_logger = new Zend_Log($writer);
}

Using $this when not in object context

maybe it is to early in the morning or I'm totally blind, but why to I get a 'Fatal error: Using $this when not in object context' in the following code. There is nothing static in there.
The class:
<?php
class Property
{
/**
* #var string[]
*/
private $values;
public function __contruct($file)
{
$this->values = parse_ini_file($file, false);
}
/**
* #return string
*/
public function get($key, $default = null)
{
if (key_exists($key, $this->values)) { //<-- error
return $this->values[$key];
}
return $default;
}
}
The test:
<?php
class PropertyTest extends Test
{
public function testGet()
{
$prop = new Property($this->getResource('test.properties'));
$this->assertEquals('foo', $prop->get('test.entry', 'xyz'));
$this->assertEquals('bar', $prop->get('test.entry2', 'xyz'));
$this->assertEquals('xyz', $prop->get('test.entry3', 'xyz'));
$this->assertEquals(null, $prop->get('test.entry3'));
}
}
Edit
The error comments indicating the trace. The error occures while running the PropertyTest->testGet() on the the first $prop->get() caused by the first line of the Property->get() method.
Solution
Beside the typo xdazz found, and the deprecation Phil pointed at, user985935 was right. :)
To make it short, my class loader used the static get and the phpUnit error mislead my investigations and my information I offer you for finding my problem. Sorry.
There is a typo in your code.
public function __contruct($file)
which should be
public function __construct($file)
'Fatal error: Using $this when not in object context'
The $this keyword points to methods that are inside an object only you can't use $this outside an object I think this is what causing your problem

Categories