I have recently done an update to PHP 5.4, and I get an error about static and non-static code.
This is the error:
PHP Strict Standards: Non-static method VTimer::get()
should not be called statically in /home/jaco/public_html/include/function_smarty.php on line 371
This is the line 371:
$timer = VTimer::get($options['magic']);
I hope somebody can help.
asked Oct 30, 2013 at 21:15
0
That means it should be called like:
$timer = (new VTimer)->get($options['magic']);
The difference between static
and non-static
is that the first one doesn’t need instantiation so you can call the classname
then append ::
to it and call the method immediately.
Like so:
ClassName::method();
and if the method is not static you need to initialize it like so:
$var = new ClassName();
$var->method();
However, in PHP >=5.4 you can use this syntax instead as a shorthand:
(new ClassName)->method();
ESP32
7,8432 gold badges39 silver badges59 bronze badges
answered Oct 30, 2013 at 21:23
5
You can also change the method to be static like so:
class Handler {
public static function helloWorld() {
echo "Hello world!";
}
}
answered Jun 21, 2016 at 4:42
The most elegant way would be :
(new ClassName)->method();
You can also convert your function to static function call() {}
, but that depends on your function and what you’re doing with it.
If you need to instantiate a class then avoid doing so, treat static functions like constants, they can not have objects and require predefined variables.
answered May 1, 2020 at 11:53
public function functionName($variable)
Change to
public static function functionName($variable)
answered Jun 3, 2022 at 11:51
<? // Cache functions // Tagged cache. After add/delete/update cached objects need to clear tag cache. This events see farther // (C) Konstantin Chechetkin - ASPRO if(!class_exists("CCache")){ class CCache { static public $arIBlocks = NULL; static public $arIBlocksInfo = NULL; static public $bEnabled = true; function CIBlock_GetList($arOrder = array("SORT" => "ASC", "CACHE" => array("MULTI" => "Y", "GROUP" => array(), "RESULT" => array(), "TAG" => "", "PATH" => "", "TIME" => 36000000)), $arFilter = array(), $bIncCnt = false){ list($cacheTag, $cachePath, $cacheTime) = self::_InitCacheParams("iblock", __FUNCTION__, $arOrder["CACHE"]); $obCache = new CPHPCache(); $cacheID = __FUNCTION__."_".$cacheTag.md5(serialize(array_merge((array)$arOrder, (array)$arFilter, (array)$bIncCnt))); if(self::$bEnabled && $obCache->InitCache($cacheTime, $cacheID, $cachePath)){ $res = $obCache->GetVars(); $arRes = $res["arRes"]; } else{ $arRes = array(); $arResultGroupBy = array("GROUP" => $arOrder["CACHE"]["GROUP"], "MULTI" => $arOrder["CACHE"]["MULTI"], "RESULT" => $arOrder["CACHE"]["RESULT"]); unset($arOrder["CACHE"]); $dbRes = CIBlock::GetList($arOrder, $arFilter, $bIncCnt); while($item = $dbRes->Fetch()){ if($item['ID']){ $item['LID'] = array(); $dbIBlockSites = CIBlock::GetSite($item['ID']); while($arIBlockSite = $dbIBlockSites->Fetch()){ $item['LID'][] = $arIBlockSite['SITE_ID']; } } $arRes[] = $item; } if($arResultGroupBy["MULTI"] || $arResultGroupBy["GROUP"] || $arResultGroupBy["RESULT"]){ $arRes = self::GroupArrayBy($arRes, $arResultGroupBy); } self::_SaveDataCache($obCache, $arRes, $cacheTag, $cachePath, $cacheTime, $cacheID); } return $arRes; } function CIBlockElement_GetList($arOrder = array("SORT" => "ASC", "CACHE" => array("MULTI" => "Y", "GROUP" => array(), "RESULT" => array(), "TAG" => "", "PATH" => "", "TIME" => 36000000, "URL_TEMPLATE" => "")), $arFilter = array(), $arGroupBy = false, $arNavStartParams = false, $arSelectFields = array()){ // check filter by IBLOCK_ID === false if(array_key_exists("IBLOCK_ID", ($arFilter = (array)$arFilter)) && !$arFilter["IBLOCK_ID"]){ return false; } list($cacheTag, $cachePath, $cacheTime) = self::_InitCacheParams("iblock", __FUNCTION__, $arOrder["CACHE"]); if(is_array($arSelectFields) && $arSelectFields){ $arSelectFields[] = "ID"; } $obCache = new CPHPCache(); $cacheID = __FUNCTION__."_".$cacheTag.md5(serialize(array_merge((array)$arOrder, $arFilter, (array)$arGroupBy, (array)$arNavStartParams, (array)$arSelectFields))); if(self::$bEnabled && $obCache->InitCache($cacheTime, $cacheID, $cachePath)){ $res = $obCache->GetVars(); $arRes = $res["arRes"]; } else{ $arRes = array(); $arResultGroupBy = array("GROUP" => $arOrder["CACHE"]["GROUP"], "MULTI" => $arOrder["CACHE"]["MULTI"], "RESULT" => $arOrder["CACHE"]["RESULT"]); $urlTemplate = $arOrder["CACHE"]["URL_TEMPLATE"]; unset($arOrder["CACHE"]); $dbRes = CIBlockElement::GetList($arOrder, $arFilter, $arGroupBy, $arNavStartParams, $arSelectFields); if($arGroupBy === array()){ // only count $arRes = $dbRes; } else{ if(strlen($urlTemplate)){ $dbRes->SetUrlTemplates($urlTemplate, ''); } $arResultIDsIndexes = array(); $bGetSectionIDsArray = (in_array("IBLOCK_SECTION_ID", $arSelectFields) || !$arSelectFields); if($bGetDetailPageUrlsArray = (in_array("DETAIL_PAGE_URL", $arSelectFields) || !$arSelectFields)){ if($arSelectFields){ if(!in_array("IBLOCK_ID", $arSelectFields)){ $arSelectFields[] = "IBLOCK_ID"; } if(!in_array("IBLOCK_SECTION_ID", $arSelectFields)){ $arSelectFields[] = "IBLOCK_SECTION_ID"; } if(!in_array("ID", $arSelectFields)){ $arSelectFields[] = "ID"; } if(!in_array("CANONICAL_PAGE_URL", $arSelectFields)){ $arSelectFields[] = "CANONICAL_PAGE_URL"; } } $bGetSectionIDsArray = true; } // fields and properties $arRes = self::_GetFieldsAndProps($dbRes, $arSelectFields, $bGetSectionIDsArray); if($bGetDetailPageUrlsArray){ $arBySectionID = $arNewDetailPageUrls = $arCanonicalPageUrls = $arByIBlock = array(); $FilterIblockID = $arFilter["IBLOCK_ID"]; $FilterSectionID = $arFilter["SECTION_ID"]; foreach($arRes as $arItem){ if($IBLOCK_ID = ($arItem["IBLOCK_ID"] ? $arItem["IBLOCK_ID"] : $FilterIblockID)){ if($arSectionIDs = ($arItem["IBLOCK_SECTION_ID"] ? $arItem["IBLOCK_SECTION_ID"] : $FilterSectionID)){ if(!is_array($arSectionIDs)){ $arSectionIDs = array($arSectionIDs); } foreach($arSectionIDs as $SID){ $arByIBlock[$IBLOCK_ID][$SID][] = $arItem["ID"]; } } } else{ $arNewDetailPageUrls[$arItem["ID"]] = array($arItem["DETAIL_PAGE_URL"]); if(strlen($arItem["CANONICAL_PAGE_URL"])){ $arCanonicalPageUrls[$arItem["ID"]] = $arItem["CANONICAL_PAGE_URL"]; } } } foreach($arByIBlock as $IBLOCK_ID => $arIB){ $arSectionIDs = $arSections = array(); foreach($arIB as $SECTION_ID => $arIDs){ $arSectionIDs[] = $SECTION_ID; } if($arSectionIDs){ $arSections = CCache::CIBlockSection_GetList(array("CACHE" => array("TAG" => CCache::GetIBlockCacheTag($IBLOCK_ID), "MULTI" => "N", "GROUP" => array("ID"))), array("ID" => $arSectionIDs), false, array("ID", "CODE", "EXTERNAL_ID", "IBLOCK_ID")); } foreach($arIB as $SECTION_ID => $arIDs){ if($arIDs){ $rsElements = CIBlockElement::GetList(array(), array("ID" => $arIDs), false, false, array("ID", "DETAIL_PAGE_URL", "CANONICAL_PAGE_URL")); $rsElements->SetUrlTemplates(CCache::$arIBlocksInfo[$IBLOCK_ID]["DETAIL_PAGE_URL"]); $rsElements->SetSectionContext($arSections[$SECTION_ID]); while($arElement = $rsElements->GetNext()){ $arNewDetailPageUrls[$arElement["ID"]][$SECTION_ID] = $arElement["DETAIL_PAGE_URL"]; if(strlen($arElement["CANONICAL_PAGE_URL"])){ $arCanonicalPageUrls[$arElement["ID"]] = $arElement["CANONICAL_PAGE_URL"]; } } } } } foreach($arRes as $i => $arItem){ if(count($arNewDetailPageUrls[$arItem["ID"]]) > 1){ if(isset($arCanonicalPageUrls[$arItem["ID"]]) && strlen($arCanonicalPageUrls[$arItem["ID"]])){ $arRes[$i]["DETAIL_PAGE_URL"] = $arCanonicalPageUrls[$arItem["ID"]]; } else{ $arRes[$i]["DETAIL_PAGE_URL"] = $arNewDetailPageUrls[$arItem["ID"]]; } } unset($arRes[$i]["~DETAIL_PAGE_URL"]); } } if($arResultGroupBy["MULTI"] || $arResultGroupBy["GROUP"] || $arResultGroupBy["RESULT"]){ $arRes = self::GroupArrayBy($arRes, $arResultGroupBy); } } self::_SaveDataCache($obCache, $arRes, $cacheTag, $cachePath, $cacheTime, $cacheID); } return $arRes; } function CIBlockSection_GetList($arOrder = array("SORT" => "ASC", "CACHE" => array("MULTI" => "Y", "GROUP" => array(), "RESULT" => array(), "TAG" => "", "PATH" => "", "TIME" => 36000000, "URL_TEMPLATE" => "")), $arFilter = array(), $bIncCnt = false, $arSelectFields = array(), $arNavStartParams = false){ // check filter by IBLOCK_ID === false if(array_key_exists("IBLOCK_ID", ($arFilter = (array)$arFilter)) && !$arFilter["IBLOCK_ID"]){ return false; } list($cacheTag, $cachePath, $cacheTime) = self::_InitCacheParams("iblock", __FUNCTION__, $arOrder["CACHE"]); if(is_array($arSelectFields) && $arSelectFields){ $arSelectFields[] = "ID"; } $obCache = new CPHPCache(); $cacheID = __FUNCTION__."_".$cacheTag.md5(serialize(array_merge((array)$arOrder, (array)$arFilter, (array)$bIncCnt, (array)$arNavStartParams, (array)$arSelectFields))); if(self::$bEnabled && $obCache->InitCache($cacheTime, $cacheID, $cachePath)){ $res = $obCache->GetVars(); $arRes = $res["arRes"]; } else{ $arRes = array(); $arResultGroupBy = array("GROUP" => $arOrder["CACHE"]["GROUP"], "MULTI" => $arOrder["CACHE"]["MULTI"], "RESULT" => $arOrder["CACHE"]["RESULT"]); $urlTemplate = $arOrder["CACHE"]["URL_TEMPLATE"]; unset($arOrder["CACHE"]); $dbRes = CIBlockSection::GetList($arOrder, $arFilter, $bIncCnt, $arSelectFields, $arNavStartParams); if(strlen($urlTemplate)){ $dbRes->SetUrlTemplates('', $urlTemplate); } // fields and properties $arRes = self::_GetFieldsAndProps($dbRes, $arSelectFields); if($arResultGroupBy["MULTI"] || $arResultGroupBy["GROUP"] || $arResultGroupBy["RESULT"]){ $arRes = self::GroupArrayBy($arRes, $arResultGroupBy); } self::_SaveDataCache($obCache, $arRes, $cacheTag, $cachePath, $cacheTime, $cacheID); } return $arRes; } function CSaleBasket_GetList($arOrder = array("SORT" => "ASC"), $arFilter = array(), $arGroupBy = false, $arNavStartParams = false, $arSelectFields = array(), $cacheTag = "", $cacheTime = 36000000, $cachePath = ""){ CModule::IncludeModule('sale'); if(!strlen($cacheTag)){ $cacheTag = "_notag"; } if(!strlen($cachePath)){ $cachePath = "/ccache/sale/CSaleBasket_GetList/".$cacheTag."/"; } $obCache = new CPHPCache(); $cacheID = 'CSaleBasket_GetList_'.$cacheTag.md5(serialize(array_merge((array)$arOrder, (array)$arFilter, (array)$arGroupBy, (array)$arNavStartParams, (array)$arSelectFields))); if(self::$bEnabled && $obCache->InitCache($cacheTime, $cacheID, $cachePath)){ $res = $obCache->GetVars(); $arRes = $res["arRes"]; } else{ $arRes = array(); $arResultGroupBy = array("GROUP" => $arGroupBy["GROUP"], "MULTI" => $arGroupBy["MULTI"], "RESULT" => $arSelectFields["RESULT"]); $arGroupBy = (isset($arGroupBy["BX"]) ? $arGroupBy["BX"] : $arGroupBy); $dbRes = CSaleBasket::GetList($arOrder, $arFilter, $arGroupBy, $arNavStartParams, $arSelectFields); if(in_array("DETAIL_PAGE_URL", $arSelectFields) === false){ while($item = $dbRes->Fetch()){ $arRes[] = $item; } } else{ while($item = $dbRes->GetNext()){ $arRes[] = $item; } } if($arResultGroupBy["MULTI"] || $arResultGroupBy["GROUP"] || $arResultGroupBy["RESULT"]){ $arRes = self::GroupArrayBy($arRes, $arResultGroupBy); } self::_SaveDataCache($obCache, $arRes, $cacheTag, $cachePath, $cacheTime, $cacheID); } return $arRes; } function CForumMessage_GetListEx($arOrder = array("SORT" => "ASC"), $arFilter = array(), $arGroupBy = false, $iNum = 0, $arSelectFields = array(), $cacheTag = "", $cacheTime = 36000000, $cachePath = ""){ CModule::IncludeModule('forum'); if(!strlen($cacheTag)){ $cacheTag = "_notag"; } if(!strlen($cachePath)){ $cachePath = "/ccache/forum/CForumMessage_GetListEx/".$cacheTag."/"; } $obCache = new CPHPCache(); $cacheID = 'CForumMessage_GetListEx_'.$cacheTag.md5(serialize(array_merge((array)$arOrder, (array)$arFilter, (array)$arGroupBy, (array)$iNum, (array)$arSelectFields))); if(self::$bEnabled && $obCache->InitCache($cacheTime, $cacheID, $cachePath)){ $res = $obCache->GetVars(); $arRes = $res["arRes"]; } else{ $arRes = array(); $arResultGroupBy = array("GROUP" => $arGroupBy["GROUP"], "MULTI" => $arGroupBy["MULTI"], "RESULT" => $arSelectFields["RESULT"]); $bCount = (isset($arGroupBy["BX"]) ? $arGroupBy["BX"] : $arGroupBy); $dbRes = CForumMessage::GetListEx($arOrder, $arFilter, $bCount, $iNum, $arSelectFields); if($bCount){ $arRes = $dbRes; } else{ while($item = $dbRes->Fetch()){ $arRes[] = $item; } if($arResultGroupBy["MULTI"] || $arResultGroupBy["GROUP"] || $arResultGroupBy["RESULT"]){ $arRes = self::GroupArrayBy($arRes, $arResultGroupBy); } } self::_SaveDataCache($obCache, $arRes, $cacheTag, $cachePath, $cacheTime, $cacheID); } return $arRes; } private function _MakeResultTreeArray($arParams, &$arItem, &$arItemResval, &$to){ if($arParams["GROUP"]){ $newto = $to; $FieldID = array_shift($arParams["GROUP"]); $arFieldValue = (is_array($arItem[$FieldID]) ? $arItem[$FieldID] : array($arItem[$FieldID])); foreach($arFieldValue as $FieldValue){ if(!isset($to[$FieldValue])){ $to[$FieldValue] = false; } $newto = &$to[$FieldValue]; self::_MakeResultTreeArray($arParams, $arItem, $arItemResval, $newto); } } else{ if($arParams["MULTI"] == "Y"){ $to[] = $arItemResval; } elseif($arParams["MULTI"] == "YM"){ if($to){ $to = array_merge((array)$to, (array)$arItemResval); } else{ $to = $arItemResval; } } else{ $to = $arItemResval; } } } function GroupArrayBy($arItems, $arParams){ $arRes = array(); $resultIDsCount = count($arParams["RESULT"]); $arParams["RESULT"] = array_diff((array)$arParams["RESULT"], array(null)); $arParams["GROUP"] = array_diff((array)$arParams["GROUP"], array(null)); foreach($arItems as $arItem){ $val = false; if($resultIDsCount){ if($resultIDsCount > 1){ foreach($arParams["RESULT"] as $ID){ $val[$ID] = $arItem[$ID]; } } else{ $val = $arItem[current($arParams["RESULT"])]; } } else{ $val = $arItem; } self::_MakeResultTreeArray($arParams, $arItem, $val, $arRes); } return $arRes; } private function _InitCacheParams($moduleName, $functionName, $arCache){ CModule::IncludeModule($moduleName); $cacheTag = $arCache["TAG"]; $cachePath = $arCache["PATH"]; $cacheTime = ($arCache["TIME"] > 0 ? $arCache["TIME"] : 36000000); if(!strlen($cacheTag)){ $cacheTag = "_notag"; } if(!strlen($cachePath)){ $cachePath = "/CCache/".$moduleName."/".$functionName."/".$cacheTag."/"; } return array($cacheTag, $cachePath, $cacheTime); } private function _GetElementSectionsArray($ID){ $arSections = array(); $resGroups = CIBlockElement::GetElementGroups($ID, true, array("ID")); while($arGroup = $resGroups->Fetch()){ $arSections[] = $arGroup["ID"]; } return (!$arSections ? false : (count($arSections) == 1 ? current($arSections) : $arSections)); } private function _GetFieldsAndProps($dbRes, $arSelectFields, $bIsIblockElement = false){ $arRes = $arResultIDsIndexes = array(); if($arSelectFields && (in_array("DETAIL_PAGE_URL", $arSelectFields) === false && in_array("SECTION_PAGE_URL", $arSelectFields) === false)){ $func = "Fetch"; } else{ $func = "GetNext"; } while($item = $dbRes->$func()){ if(($existKey = ($arResultIDsIndexes[$item["ID"]] ? $arResultIDsIndexes[$item["ID"]] : ($arResultIDsIndexes[$item["ID"]] !== null ? false : null))) !== null){ $existItem = &$arRes[$existKey]; if($bIsIblockElement){ unset($item["IBLOCK_SECTION_ID"]); unset($item["~IBLOCK_SECTION_ID"]); } foreach($item as $key => $val){ if($key == "ID") { continue; } if(isset($existItem[$key])){ if(is_array($existItem[$key])){ if(!in_array($val, $existItem[$key])){ $existItem[$key][] = $val; } } else{ if($existItem[$key] != $val){ $existItem[$key] = array($existItem[$key], $val); } } } else{ $existItem[$key] = $val; } } } else{ if($bIsIblockElement){ $item["IBLOCK_SECTION_ID_SELECTED"] = $item["IBLOCK_SECTION_ID"]; $item["IBLOCK_SECTION_ID"] = self::_GetElementSectionsArray($item["ID"]); unset($item["~IBLOCK_SECTION_ID"]); } if(in_array("ElementValues", $arSelectFields) && isset($item["IBLOCK_ID"])) { $ipropValues = new BitrixIblockInheritedPropertyElementValues($item["IBLOCK_ID"], $item["ID"]); $item["IPROPERTY_VALUES"] = $ipropValues->getValues(); } $arResultIDsIndexes[$item["ID"]] = count($arRes); $arRes[] = $item; } } return $arRes; } private function _SaveDataCache($obCache, $arRes, $cacheTag, $cachePath, $cacheTime, $cacheID){ if(self::$bEnabled && $cacheTime > 0){ $obCache->StartDataCache($cacheTime, $cacheID, $cachePath); if(strlen($cacheTag)){ global $CACHE_MANAGER; $CACHE_MANAGER->StartTagCache($cachePath); $CACHE_MANAGER->RegisterTag($cacheTag); $CACHE_MANAGER->EndTagCache(); } $obCache->EndDataCache(array("arRes" => $arRes)); } } function GetIBlockCacheTag($IBLOCK_ID){ if(!$IBLOCK_ID){ return false; } else{ return @CCache::$arIBlocksInfo[$IBLOCK_ID]["CODE"].$IBLOCK_ID; } } function ClearTagIBlock($arFields){ global $CACHE_MANAGER; $CACHE_MANAGER->ClearByTag("iblocks"); } function ClearTagIBlockBeforeDelete($ID){ global $CACHE_MANAGER; $CACHE_MANAGER->ClearByTag("iblocks"); } function ClearTagIBlockElement($arFields){ global $CACHE_MANAGER; if($arFields["IBLOCK_ID"]){ $CACHE_MANAGER->ClearByTag(CCache::GetIBlockCacheTag($arFields["IBLOCK_ID"])); } } function ClearTagIBlockSection($arFields){ global $CACHE_MANAGER; if($arFields["IBLOCK_ID"]){ $CACHE_MANAGER->ClearByTag(CCache::GetIBlockCacheTag($arFields["IBLOCK_ID"])); } } function ClearTagIBlockSectionBeforeDelete($ID){ global $CACHE_MANAGER; if($ID > 0){ if($IBLOCK_ID = CCache::CIBlockSection_GetList(array("CACHE" => array("MULTI" => "N")), array("ID" => $ID), false, array("IBLOCK_ID"), true)){ $CACHE_MANAGER->ClearByTag(CCache::GetIBlockCacheTag($IBLOCK_ID)); } } } } // initialize CCache::$arIBlocks array if(CCache::$arIBlocks === NULL){ CCache::$bEnabled = COption::GetOptionString('main', 'component_managed_cache_on', 'Y') === 'Y'; $arIBlocksTmp = CCache::CIBlock_GetList(array("CACHE" => array("TAG" => "iblocks")), array("ACTIVE" => "Y", "CHECK_PERMISSIONS" => "N")); CCache::$arIBlocks = CCache::GroupArrayBy($arIBlocksTmp, array("GROUP" => array("LID", "IBLOCK_TYPE_ID", "CODE"), "MULTI" => "Y", "RESULT" => array("ID"))); CCache::$arIBlocksInfo = CCache::GroupArrayBy($arIBlocksTmp, array("GROUP" => array("ID"))); } } ?>
PHP 8.0 no longer allows to call non-static class methods with the static call operator (::
).
Calling non-static methods statically raised a PHP deprecation notice in all PHP 7 versions, and raised a Strict Standards notice in PHP 5 versions.
class Foo {
public function bar() {}
}
Foo::bar();
// Deprecated: Non-static method Foo::bar() should not be called statically in ... on line ...
In PHP 8.0 and later, this results in a fatal error:
class Foo {
public function bar() {}
}
Foo::bar();
// Fatal error: Uncaught Error: Call to undefined method Foo::bar() in ...:...
Note that this only affects calling non-static methods statically. Although discouraged, calling a static method non-statically (
$this->staticMethod()
) is allowed.
This change is implemented throughout the engine.
Variable Functions
class Foo {
public function bar() {}
}
['Foo', 'bar']();
// Fatal error: Uncaught Error: Non-static method Foo::bar() cannot be called statically in ...:...
Callables
PHP no longer considers an array with class name and a method (['Foo', 'bar']
) as a valid callable, and results in a fatal error. This includes PHP core functions that expect a callable. If such callable is passed to a function that expects a valid callable, a TypeError
will be thrown instead of a fatal error at call-time.
class Foo {
public function bar() {}
}
call_user_func(['Foo', 'bar']);
call_user_func_array(['Foo', 'bar'], []);
// Fatal error: Uncaught TypeError: call_user_func(): Argument #1 ($function) must be a valid callback, non-static method Foo::bar() cannot be called statically in ...:...
This affects all functions ranging from call_user_func
and call_user_func_array
to register_shutdown_function
, set_error_handler
, set_error_handler
.
register_shutdown_function
function in PHP 8.0 versions until beta3 raised a PHP warning at the timeregister_shutdown_function
function is called instead of the current behavior of throwing aTypeError
exception. This was corrected in PHP beta4.
is_callable
is_callable
function returns false
on callable that calls non-static methods statically. It returned true
prior to PHP 8.0.
class Foo {
public function bar() {}
}
is_callable(['Foo', 'bar']); // false
static
, self
, and parent
static
, self
, and and parent
pointers can continue to use the static call syntax inside a class.
class Test extends UpperTest{
public function foo(): {}
public function bar() {
static::foo();
self::foo();
parent::foo();
}
}
The call above is still allowed because static
, self
, and parent
are used inside the class scope.
static::
and self::
calls are identical to $this->
calls on non-static methods, and improves readability. In the example above, static::foo()
and self::foo()
calls can be safely replaced with $this->foo()
to improve readability because foo
is not a static method.
Backwards Compatibility Impact
For existing code that get fatal errors in PHP 8.0, the fix can as simple as using the correct syntax if there is a class instance in the same scope.
class Foo {
public function bar() {}
}
$foo = new Foo();
- Foo::bar();
+ $foo->bar();
If there is no instantiated class object, and if the class can be instantiated without any parameters or side effects, it will be simple replacement as well.
class Foo {
public function bar() {}
}
- Foo::bar();
+ (new Foo())->bar();
If the class constructor requires parameters, or tends to make any state changes, the fix can be more complicated. The instance needs to be injected to the scope the static call is made.
Note that functions that expect a callable
parameter no longer accept callables with a non-static method as static method. A TypeError
exception will be thrown when the callable is passed, as opposed to when the callable is invoked.
class Foo {
public function bar() {}
}
function takeCallable(callable $func) {}
- takeCallable(['Foo', 'bar']);
+ takeCallable([new Foo(), 'bar']);
is_callable
function no longer returns true
for such callables either.
Implementation
Many programmers face the error message ‘Non static method cannot be referenced from a static context’ when they are coding. This error message isn’t specific and can occur in any IDE if the conditions for the error are true.
This is a very common mistake for beginners where the programmer tries to use a class ‘statically’ without making an instance of the class. There are several conditions which must be met when you are using a class which is static. In this article, we will go through several different cases and guide you on how to use a static class.
What is a Static Method?
Adding the keyword ‘static’ to any method makes the method known as a static method. A static method belongs to the class rather than belonging to an object (which is the norm). A static method can be easily invoked without the condition of creating an instance of a class.
There are several different uses of Static methods for example, using it, you can change a static data member and its value. However, there are still some limitations when using a Static method. For example, if you want to access non-static fields of your class, you must use a non-static method. So to sum up, Static methods are used very sparely but they do have their benefits.
Here is a short example of how a static method can be made to change the property of all objects.
class Students{ int roll_no; String name; static String college = "InformationTech"; static void change(){ college = “Management"; } Students (int number, String name_self){ roll_no = number; name = name_self; } void display (){System.out.println(rollno+" "+name+" "+college);} public static void main(String args[]){ Students.change(); Students stu_1 = new Students (100,"Mexican"); Students stu_2 = new Students (202,"American"); Students stu_3 = new Students (309,"British"); stu_1.display(); stu_2.display(); stu_3.display(); } }
The output of the program will be:
100 Mexican Management 202 American Management 309 British Management
What is the Difference between a class and instance of a class?
Think you are walking on the street and you see a car. Now you immediately know that this is a car even if you don’t know what is its model or type. This is because you know that this belongs to the class of ‘cars’ which you already know of. Think of class here as a template or an idea.
Now as you move closer, you see the model and make of the car. Here you are recognizing the ‘instance’ of the class ‘car’. Here all the properties will be present in detail; the wheels, the horsepower, the rims etc.
An example of properties can be that the class ‘car’ states that all cars should have wheels. The car which you are seeing (an instance of the car class) has alloy rims.
In object-oriented programming, you define the class yourself and inside the class, you define a field of the type ‘color’. Whenever the class is instantiated, memory is automatically reserved for the color at the backend and later on, you can give this a specific value (for example red). Since attributes like these are specific, they are non-static.
In contrast, static methods and fields are shared with all the instances. These are made for value or items which are specific to the class and not the instance itself. For methods, there can be global methods (for example, stringtoInt converter) and for fields, they are usually constants according to your code (for example, the car type can be static if you are only manufacturing normal cars).
Now, we will look at all the different cases where your coding can go wrong and see the workarounds to fix them.
Issue 1: You are calling something which doesn’t exist
We came across some cases where users were using both static and non-static methods with each other. When we do this, you should be careful of what method is calling what (in terms of static or not). Take a look at the following code:
private java.util.List<String> someMethod(){ /* Some Code */ return someList; } public static void main(String[] strArgs){ // The following statement causes the error. You know why.. java.util.List<String> someList = someMethod(); }
Here, the static method is calling someMethod. In object-oriented programming, we encapsulate the data together with the data which we want to operate on. Here, without an object, there is no instance data and while the instance methods exist as part of the class definition, there should always be an object instance to provide data to them.
So to sum up, you cannot call something which doesn’t exist. Since you might not have created an object, the non-static method doesn’t exist yet. However, on the other hand, a static method will always exist (because of definition).
Issue 2: Methods aren’t made Static
If you are invoking methods from your Static main method without creating an instance of the methods, you will get an error message. Here, the same principle applies; you cannot access something that doesn’t exist.
public class BookStoreApp2 { //constants for options Scanner input = new Scanner (System.in); public static void main(String[] args) { BookStoreItem[] item;//declaring array item = new BookStoreItem[10];//initializing array int itemType = -1; printMenu(); getUserChoice(); for (int i = 0; i < item.length; i++){ }//end of switch statement }//end of for loop for (int i = 0; i < item.length; i++) { }//end of for }//end of main method
Here in this code, you need to convert both the methods printMenu() and getUserChoice() into static methods.
Hence if you want to get around a situation like this, you can use a constructor instead. For example, you can take the contents of your main() method and place them inside a constructor.
public BookStoreApp2() { // Put contents of main method here} After doing this, do the following inside your main() method: public void main( String[] args ) { new BookStoreApp2(); }
If these tips don’t work on your or your code is different, you should keep in mind the basic principles of Static classes and methods and recheck your code to make sure that the basic principle is not being violated.