Instantiating class by string - php

i have this code.
$contrl = stripslashes($this->params['controller'].'Controller'); //PostController
$obj = new $contrl(); // What's won't work
//this don't work too
$contrl = 'PostController';
$obj = new $contrl();
//but this work good
$obj = new PostController();
I dont understand why it happen and how I can fix it?

I haven't tested it, but I'm pretty sure it should be done like this (as per the doc):
$obj = new $contrl;

Related

How to get smarty file tokens?

How to get smarty(test.tpl) file tokens using the smarty-php/smarty-lexer package. From the documentation, I can’t understand how to do this, since I don’t have experience in parsing a file into tokens.
use Smarty_Internal_SmartyTemplateCompiler;
use Smarty_Internal_Templatelexer;
use Smarty;
use Smarty_Internal_Templateparser;
$smarty = new Smarty();
$templateSource = file_get_contents('path/to/template.tpl');
$lexer = new Smarty_Internal_Templatelexer();
$parser = new Smarty_Internal_Templateparser();
$compiler = new Smarty_Internal_SmartyTemplateCompiler($lexer, $parser, $smarty);
$lexer = new Smarty_Internal_Templatelexer($templateSource, $compiler);
$tokens = $lexer->tokenize();
This is one of the methods that I tried, I tried different approaches, nothing works.

How can you use the ResourceWatcher bundle from YoSymfony?

I am trying to make a file watcher where, when you add, update or delete a file, you can see the files updates in a database. I'm using the framework Symfony4 and a bundle from it called ResourceWatcher from YoSymfony. This bundle uses the Finder bundle from Symfony to find files in the directories specified and then, the watcher compares the cache and the new file to see if there are any changes. When I use a method with the watcher which returns a path array, when I try to see the array, it returns null. How am I suppose to use these methods and their returns?
I put the var_dump everywhere to see that the problem comes from the findChanges()->getUpdatedFiles() and getNewFiles();
//OLD CODE
$finder = new Finder();
$finder->files()
->name('*.csv')
->in('%kernel.root_dir%/../src/data/');
//watcher
$hashContent = new Crc32ContentHash();
$resourceCache = new ResourceCachePhpFile('cache-key.php');
$watcher = new ResourceWatcher($resourceCache, $finder, $hashContent);
$watcher->initialize();
if($watcher->findChanges()->hasChanges()){
if($watcher->findChanges()->getNewFiles() === null){
$paths = $watcher->findChanges()->getUpdatedFiles();
}
else{
$paths = $watcher->findChanges()->getNewFiles();
}
$propertyAccessor = PropertyAccess::createPropertyAccessor();
var_dump($propertyAccessor->getValue($paths, '[first_name]'));
die();
}
I'd like to be able to see the paths, convert them into string and use that into my other method to make the data appear in my database.
In my var_dump, I get NULL in terminal.
EDIT:[first_name] is in my csv-file, you can dump $paths directly.
//NEW CODE
$finder = new Finder();
$finder->files()
->name('*.csv')
->in('%kernel.root_dir%/../src/data/');
//watcher
$hashContent = new Crc32ContentHash();
$resourceCache = new ResourceCachePhpFile('cache-key.php');
$watcher = new ResourceWatcher($resourceCache, $finder, $hashContent);
$watcher->initialize();
$changes = $watcher->findChanges();
if(!empty($changes->getUpdatedFiles())){
$updatedFilesPath = $changes->getUpdatedFiles();
$pathString = implode($updatedFilesPath);
$reader = Reader::createFromPath($pathString);
}
elseif(!empty($changes->getNewFiles())){
$newFilesPath = $changes->getNewFiles();
$pathString = implode($newFilesPath);
$reader = Reader::createFromPath($pathString);
}
else{
return;
}
$results = $reader->fetchAssoc();
So it looks like that as soon as you use the method findChanges()->hasChanges(), it tells the watcher that there is some changes but then it resets and there's no changes anymore in the watcher so it's pointless to use
$paths = $watcher->findChanges()->getUpdatedFiles();
since it will always return nothing because of the reset. I had to make a variable with the changes inside so that I could re-use the changes further down.
Details in code...

Can I use a string variable to initialize a class in PHP?

I'd like to use a string variable to initialize an object. Is something like this possible?
$class = "MyClass";
$x = new $class();
return $x;
Edit: Ha, so when I tried to test this and it didn't work I had a syntax error somewhere else in my script. Apparently this works just fine. Neat.
Yes. Its possible in PHP.
$className = 'MyClass';
$object = new $className;
Attaching PHP documentation snippet on new operator

PHP Calling dynamic functions

Im trying to figure out how to call functions based on what a user clicks on a form. But im not sure if im doing it right.
I have a number of classes, lets say 3 for different ways to connect to a site, the user clicks on which one they would like.
FTP
SFTP
SSH
Which i have named 'service' in my code.
I don't want to run a whole bunch of IF statements, i would rather try and build the call dynamically.
What i have at the moment is as follows
$ftp_backup = new FTPBackup;
$sftp_backup = new SFTPBackup;
$ssh_backup = new SSHBackup;
$service = $request->input('service') . '_backup';
$service->testConn($request);
Im getting the following error
Call to a member function testConn() on string
Im not sure im doing this right.
Any help would be greatly appreciated.
Thanks
First of all $service is a string on which You cannot call method, because it is not an object (class instance).
I think it is a great example of where You can use Strategy Pattern which look like that:
class BackupStrategy {
private $strategy = null;
public function __construct($service_name)
{
switch ($service_name) {
case "ftp":
$this->strategy = new FTPBackup();
break;
case "sftp":
$this->strategy = new SFTPBackup();
break;
case "ssh":
$this->strategy = new SSHBackup();
break;
}
}
public function testConn()
{
return $this->strategy->testConn();
}
}
And then in place where You want to call it You call it by:
$service = new BackupStrategy($request->input('service'));
$service->testConn($request);
I suggest You to read about Design Patterns in OOP - it will help You a lot in the future.
How about this:
$ftp_backup = new FTPBackup;
$sftp_backup = new SFTPBackup;
$ssh_backup = new SSHBackup;
$service = $request->input('service') . '_backup';
${$service}->testConn($request);
This is called "Variables variable": http://php.net/manual/en/language.variables.variable.php
// Create class name
$className = $request->get('service') . '_backup';
// Create class instance
$service = new $className();
// Use it as you want
$service->testConn($request);

SplObjectStorage and sugary syntax in PHP

Quick one; I doubt it's possible, but is there any way to take advantage of the array($key => $value); syntax of PHP with regard to SplObjectStorage objects?
What I mean is, is there any such way to achieve:
$store = // ?
new KeyObject() => new ValueObject(),
new KeyObject() => new ValueObject(),
// ...
In the context initializing an object store? As of the moment I'm simply using: (and will probably continue, considering the sheer unlikeliness of this being a possibility)
$store = new SplObjectStorage();
$store[new KeyObject()] = new ValueObject();
$store[new KeyObject()] = new ValueObject();
// ...
Would be nice, highly doubting it, but maybe someone knows better.
While it would be a more concise syntax, unfortunately it's not possible. The best you can do is either:
$store[new KeyObject()] = new ValueObject();
or
$store->append( new KeyObject(), new ValueObject());
When adding object to an SplObjectStorage.
Why not do something like that:
$store = new SplObjectStorage();
$data = array(
array(new KeyObject, new ValueObject),
array(new KeyObject, new ValueObject),
array(new KeyObject, new ValueObject),
);
foreach($data as $item) {
list($key, $value) = $item;
$store->attach($key, $value);
}
It's not beautiful but it's at least concise.

Categories