In php, how to set a define-d value in a const? - php

Lets say in the very first script, which always executes first, I defined something:
define ('ROOTDIR', dirname(__FILE__));
define ('ROOTDIR_ASSETS', ROOTDIR.'/assets');
now a class:
class PictureGallery
{
const PATH = ROOTDIR.'/imgs';
php say: syntax error, unexpected '.' expecting ' ' or ';'.
How to work it around?

you can't have a class constant defined with string concatenation.
You'll need to use a member variable. If you don't want this changed, I would suggest making it private and only creating a getter to access it.
class PictureGallery
{
private $_path;
public function __construct()
{
$this->_path = ROOTDIR.'/imgs';
}
public function getPath()
{
return $this->_path;
}
}
OR
You could also calculate the value before defining the class, however this is a messy solution.
define('IMGDIR', ROOTDIR.'/imgs');
class PictureGallery
{
const PATH = IMGDIR;
...
}

Class constants is PHP must be a constant expression. So you either have to create another defined constant with the full path or you have to inject the path into the constructor of the class. Or just set in in the constructor.

Related

php filter_input parse error inside class

Configuration of a project in dev mode with WAMP.
PHP vers 5 and 7 are available.
Just trying to set the project root using filter_input. Could someone please explain why filter input for the protected and private vars inside the class reports a PARSE ERROR? However if used outside the class or inside a function of the class it works.
Is there a better way to do this so that it can be used globally? I find this is called a lot and would prefer to do it once.
$test = filter_input(INPUT_SERVER,'DOCUMENT_ROOT');
echo $test; //good
class FooBar{
protected $_test = filter_input(INPUT_SERVER,'DOCUMENT_ROOT'); //bad - Parse error: syntax error, unexpected '(', expecting ',' or ';'
private $_test2 = filter_input(INPUT_SERVER,'DOCUMENT_ROOT'); //bad - Parse error: syntax error, unexpected '(', expecting ',' or ';'
function __construct() {
}
public function getProducts(){
include_once
(filter_input(INPUT_SERVER,'DOCUMENT_ROOT').'/obj/user.php'); //good
}
}
You can not directly assign a function return value to a property in the class definition.
This is because the function could return different return values, and the class is only a blueprint which you must instantiate as an object to use.
For the objects that are created from your class definition you can initialize any property in the constructor:
class FooBar {
protected $var = null;
private $var2 = null;
function __construct() {
$this->var = func1();
$this->var2 = func2();
}
}
// no parse error
Despite of that, why do you use filter_input on an internal constant? You only need to filter input from the outside, i.e. GET/POST/SESSION content (user input), input read from files, from external APIs etc. But you don't need to use that on internal constants like the DOCUMENT_ROOT:
class FooBar {
private $_docroot = $_SERVER['DOCUMENT_ROOT'];
}
// no parse error

How to use private property of controller as static property?

So, the question pretty much explains what i want. Here is the minimum code of what i am doing.
class AuthorizeController extends Controller
{
private $aNetEnvironment;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->aNetEnvironment = env('ANetEnvironment');
}
public function setEnvironment()
{
$controller = new AnetController\GetCustomerProfileController($request);
// $this->aNetEnvironment = SANDBOX
$response = $controller->executeWithApiResponse(
\net\authorize\api\constants\ANetEnvironment::$this->aNetEnvironment
);
}
}
Searching stackoverflow i got two options, have tried both with no luck.
Trying, {$this->aNetEnvironment} gives
syntax error, unexpected ')', expecting '('
Trying, $$this->aNetEnvironment gives
Object of class App\Http\Controllers\AuthorizeController could not be
converted to string
Edit:
Trying, ${$this->aNetEnvironment} gives
Access to undeclared static property:
net\authorize\api\constants\ANetEnvironment::$SANDBOX
Is there any other option ?
You could make use of the PHP's constant() helper. From the docs:
Signature:
constant ( string $name ) : mixed
Return the value of the constant indicated by name.
constant() is useful if you need to retrieve the value of a
constant, but do not know its name. I.e. it is stored in a variable or
returned by a function.
This function works also with class constants.
So in your case:
$response = $controller->executeWithApiResponse(
constant('\net\authorize\api\constants\ANetEnvironment::' . $this->aNetEnvironment)
);
To use class properties as variable variables in this way you need to start with a $ and wrap the property in {} e.g. ${$this->property} so you should be able to use the following in your controller:
\net\authorize\api\constants\ANetEnvironment::${$this->aNetEnvironment}

Incorrect access to static class member

I have following code
class DataMapperFactoryBeta
{
static private $configClassName = 'ConfigBeta';
static private $client;
static private $mapper = [];
static public function initClient()
{
$className = 'Models\\DataMappers\\Clients\\'.self::$configClassName::$db_type;
}
}
The Interpretor throws me a fatal error: 'incorrect access to static class member'. I wish to have the config class name accessed dynamicly, because I will change it in the future and I don't wanna change it in many places in the code, only once, through $configClassName. Is this even possible with statics?
Split your line into two, and it should work for you as you expect:
$className = 'Models\\DataMappers\\Clients\\' . self::$configClassName;
$className = $className::$db_type;
On a side note, I couldn't find in the PHP docs whether the scope resolution operator (::) is left or right associative. It could be it's trying to interpret the line as follows:
('Models\\DataMappers\\Clients\\'.self::($configClassName::$db_type));
Without an update from the docs the code is ambiguous as to what exactly should be happening the way you have it written.

Parse error when calling a static method on an object that's referenced by an instance property

Here's my test:
<?php
require __DIR__ . '/vendor/autoload.php';
class HasStatic {
public static function static_method() {
return true;
}
}
class SUT {
public $has_static;
public function __construct() {
$this->has_static = new HasStatic();
}
public function call_static() {
// A parse error :<
// $this->has_static::static_method();
$has_static = $this->has_static;
return $has_static::static_method();
}
}
class PhpStaticCallOnProperty extends PHPUnit_Framework_TestCase {
public function testPhpStaticCallOnProperty() {
$sut = new SUT();
$this->assertTrue($sut->call_static(), 'call_static() succeeded');
}
}
As you can see, I discovered that $this->has_static::static_method(); yields a parse error.
Is there a clean way to make this call without the extra assignment?
Static methods are black boxes of functionality where you explicitly define everything going in (parameters) and out (return value). As such, they are not tied to an object - and you shouldn't call them using an object reference. static_method() should only ever be called using HasStatic::static_method(), or self::static_method() from within the HasStatic class.
There's nothing inherently wrong with static methods - I strongly disagree with tereško saying they should be avoided. If a method doesn't need an object's context, it may as well be static.
The parse error occurs because there's no reason to use the scope resolution operator (::) on a property. Variable class names do mean the following will work:
$foo = 'HasStatic';
$foo::static_method(); // equivalent to HasStatic::static_method()
However that variable cannot be a property - you'll have to assign it to a temporary variable if you want to call the method in this way.

Is a global PHP CONSTANT available inside of a Class file?

Is a global PHP CONSTANT available inside of a Class file?
define('SITE_PATH', 'C:/webserver/htdocs/somefolder/');
Then in my class file I try this
public $debug_file = SITE_PATH. 'debug/debug.sql';
This does not seem to work though,
Parse error: parse error, expecting
','' or';'' in
C:\webserver\htdocs\somefolder\includes\classes\Database.class.php
on line 21
I second what the others said. Since $debugFile seems an optional dependency, I'd suggest to initialize a sane default on creation of the class and then allow changing it by setter injection when needed, e.g.
define('SITE_PATH', 'C:/webserver/htdocs/somefolder/');
class Klass
{
protected $_debugFile;
public function __construct()
{
$this->_debugFile = SITE_PATH. 'debug/debug.sql' // default
}
public function setDebugFile($path)
{
$this->_debugFile = $path // custom
}
}
Note that injecting SITE_PATH, instead of hardcoding it, would be even better practice.
You cannot have an expression in a class declaration.
I would suggest passing the path in:
public function __construct($path)
{
$this->debug_path = $path;
}
This gives you more flexibility if you ever want to change the path, you don't have to change a constant, just what you pass in.
Or you could create multiple objects that all have different paths. This is useful if it is an autoloader class, as you might want to have it load multiple directories.
$autoloader = new Autoload(dirname(SYS_PATH));
$autoloader->register_loader();
class Autoload
{
public $include_path = "";
public function __construct($include_path="")
{
// Set the Include Path
// TODO: Sanitize Include Path (Remove Trailing Slash)
if(!empty($include_path))
{
$this->include_path = $include_path;
}
else
{
$this->include_path = get_include_path();
}
// Check the directory exists.
if(!file_exists($this->include_path))
{
throw new Exception("Bad Include Path Given");
}
}
// .... more stuff ....
}
You can't use expression (.) in field initializer. See example one in PHP manual
Yes, however, property values defined at compile time cannot be expressions.
See http://php.net/manual/en/language.oop5.static.php

Categories