I need to use method from Nette library, that I'm including by use command. But it doesn't work as I want to, throws fatal error, that I am calling undefined method.
How should I approach that method to make it work? Stupid question, but I am kinda new to OOP...
Method from class PresenterComponent.php
public function getPresenter($need = TRUE)
{
return $this->lookup('Nette\Application\UI\Presenter', $need);
}
And my code, where I need to use that method:
use Nette\Application\UI\PresenterComponent;
class DatabaseCollectionAdapter extends ArrayDataAdapter
{
// ..... some code......
$this->user = $this->getPresenter()->getUser();
Error:
Fatal Error
Call to undefined method Ctech\Gridator\DataAdapter\DatabaseCollectionAdapter::getPresenter()
change this
$this->user = $this->getPresenter()->getUser();
to this:
$object = new yourObject(); // yourObject extends PresenterComponent
$this->user = $object->getPresenter()->getUser();
use Nette\Application\UI\PresenterComponent; does not include or do any kind of magic to make it's functions available on the fly.
https://secure.php.net/manual/de/language.namespaces.importing.php
It's just a shorthand that helps you to use PresenterComponent directly without specifying the whole namespace.
Your DatabaseCollectionAdapter or ArrayDataAdapter has to have a function that looks like this:
class AdapterClass
public function getPresenter() {
return new Nette\Application\UI\PresenterComponent;
}
}
or something like this
use Nette\Application\UI\PresenterComponent;
class AdapterClass
public function getPresenter() {
return new PresenterComponent;
}
}
Related
I am new in flight php.
I need some help, I create two classes client.class.php and deliveryServiceConnector.class.php and i have index.php. I want to use function from deliveryServiceConnector.class.php in client.class.php so I write this code:
public function __construct() {
$this->connector = new deliveryServiceConnector(DOLIBARR_API_KEY,DOLIBARR_ROOT_URL,NuLL, $this->nodeName);
$connector->testDisplayDev();
}
I got this error:
Undefined variable: connector (8)
Any idea how can i fix my error, Thanks
You're not using the same thing for the deliveryServiceConnector. In the first line, inside the function, you use $this->connector, but in the second line you use $connector. Therefore it is undefined. Try to use the same thing twice. Either:
public function __construct() {
$this->connector = new deliveryServiceConnector(DOLIBARR_API_KEY,DOLIBARR_ROOT_URL,NuLL, $this->nodeName);
$this->connector->testDisplayDev();
}
or
public function __construct() {
$connector = new deliveryServiceConnector(DOLIBARR_API_KEY,DOLIBARR_ROOT_URL,NuLL, $this->nodeName);
$connector->testDisplayDev();
}
I have a called class called ClientPolicy which is like this
class ClientPolicy {
var $serverHost="www.example.com";
var $httpPort = 80;
var $httpsPort = 443;
var $appKey;
var $secKey;
var $defaultContentCharset = "UTF-8";
}
and another class file name SyncAPIClient which looks like this
class SyncAPIClient{
function SyncAPIClient(ClientPolicy $clientPolicy) {
$this->clientPolicy = $clientPolicy;
}
function SyncAPIClient($appKey, $appSecret) {
$this->clientPolicy = new ClientPolicy();
$this->clientPolicy->appKey=$appKey;
$this->clientPolicy->secKey=$appSecret;
}
}
My questions are
1.) If you check the function in SyncAPIClient, you will notice that the ClientPolicy class was passed as a parameter before a variable, what does it really mean? What is the essence of passing a class in function parameter?
2.) I am getting an error "Cannot redeclare SyncAPIClient::SyncAPIClient()" in my script log and the reason is that SyncAPIClient function was called twice in SyncAPIClient class. How can I solve this issue? Is there any better way to write this SyncAPIClient function instead of passing it twice?
The author of this script is nowhere to be found and I am left to fix it.
1) Here the $clientPolicy variable that is passed to this function, needs be a ClientPolicy instance.
In this way, if the argument that is passed is different from an instance of ClientPolice class, an error is generated.
function SyncAPIClient(ClientPolicy $clientPolicy) {
$this->clientPolicy = $clientPolicy;
}
https://wiki.php.net/rfc/typed_properties_v2
https://laravel-news.com/php7-typed-properties
2) The error Cannot redeclare SyncAPIClient::SyncAPIClient() is caused because you are trying to declare two functions called SyncAPIClient ().
If in first SyncAPIClient() method you just want save the $clientPolicy in $this->clientPolicy, you can use the magic method __construct. Or just try changing the name of one of the functions, and the problem should be a problem.
class SyncAPIClient{
__construct(ClientPolicy $clientPolicy) {
$this->clientPolicy = $clientPolicy;
}
function SyncAPIClient($appKey, $appSecret) {
$this->clientPolicy = new ClientPolicy();
$this->clientPolicy->appKey=$appKey;
$this->clientPolicy->secKey=$appSecret;
}
}
https://www.php.net/manual/en/language.oop5.decon.php
http://www.zentut.com/php-tutorial/php-constructor-and-destructor/
Hope this helps!
I would've fix the code you have like this:
class SyncAPIClient
{
private $clientPolicy = null;
function SyncAPIClient(ClientPolicy $clientPolicy = null)
{
if($clientPolicy instanceof ClientPolicy){
$this->clientPolicy = $clientPolicy;
}else{
$this->clientPolicy = new ClientPolicy();
}
}
public function setAuthParams($appKey, $appSecret) {
$this->clientPolicy->appKey=$appKey;
$this->clientPolicy->secKey=$appSecret;
}
}
This way you can instantiate a SyncAPIClient with or without a ClientPolicy.
Without ClientPolicy:
$syncAPI = new SyncAPIClient();
$syncAPI->setAuthParams($apiKey, $apiSecret);
With ClientPolicy:
$clientPolicy = new ClientPolicy();
$clientPolicy->appKey=$appKey;
$clientPolicy->secKey=$appSecret;
$syncAPI = new SyncAPIClient($clientPolicy);
When using class and functions in combination like
Rtin::
Functions nested inside that class Rtin should have different names than that class name
So you shouldn't have function called rtin
However you can call function from outside the class with it's name
From the error you have may be due to:
function you nested in the class or the function outside the class has a duplicate outside the script itself. Like having function mentioned in included function.php file and also mentioned in the script itself so php get confused because function name is written in two php files at the same time
Example of class
class Rtin{
private $data;
private $results;
public function getResultsType(){
return ........
}
}
To call class use
$q = Rtin::getResultsType($data['name']);
In your example. Adapt it to the example I have provide and review the included files for duplicate function .
I have a class, that has a constructor that looks like this:
use App\Libraries\Content\ContentInterface;
use EllipseSynergie\ApiResponse\Laravel\Response;
class ImportController extends Controller
{
private $indexable;
function __construct(Response $response, ContentInterface $contentInterface) {
$this->indexable = \Config::get('middleton.wp.content.indexable_types');
$this->response = $response;
$this->contentInterface = $contentInterface;
}
public function all() {
$include = array_diff($this->indexable, ['folder']);
$importResult = $this->import($include);
$this->deleteOldContent($importResult['publishedPostsIDs']);
return $importResult['imported'];
}
How can I instantiate this class from another class and call the method all() from it?
I have tried with something like this:
use EllipseSynergie\ApiResponse\Laravel\Response;
use App\Libraries\Content\ContentInterface;
class ContentImport extend Command {
public function handle() {
(new ImportController(new Response, new ContentInterface))->all();
}
But, that doesn't work, I get the error that I should pass the arguments to the Response class too:
[Symfony\Component\Debug\Exception\FatalThrowableError]
Type error: Too few arguments to function EllipseSynergie\ApiResponse\AbstractResponse::__construct(), 0 passed in /home/
vagrant/Projects/middleton/app/Console/Commands/ContentImport.php on line 43 and exactly 1 expected
What is the correct way of doing this?
I believe this should work
use EllipseSynergie\ApiResponse\Laravel\Response;
use App\Libraries\Content\ContentInterface;
class ContentImport extend Command {
public function handle(ImportController $importController) {
$importController->all();
}
I've got an Object Oriented library I wanted to add a method to, and while I'm fairly certain I could just go into the source of that library and add it, I imagine this is what's generally known as A Bad Idea.
How would I go about adding my own method to a PHP object correctly?
UPDATE ** editing **
The library I'm trying to add a method to is simpleHTML, nothing fancy, just a method to improve readability. So I tried adding to my code:
class simpleHTMLDOM extends simple_html_dom {
public function remove_node() {
$this->outertext = "";
}
}
which got me: Fatal error: Call to undefined method simple_html_dom_node::remove_node(). So obviously, when you grab an element in simpleHTML it returns an object of type simple_html_dom_node.
If I add the method to simple_html_dom_node my subclass isn't what will be created by simplHTML ... so stuck as to where to go next.
A solution would be to create a new class, that extends the one from your library -- and, then, use your class, which have have all methods of the original one, plus yours.
Here's a (very quick and simple) example :
class YourClass extends TheLibraryClass {
public function yourNewMethod() {
// do what you want here
}
}
And, then, you use your class :
$obj = new YourClass();
$obj->yourNewMethod();
And you can call the methods of the TheLibraryClass class, as yours inherits the properties and methods of that one :
$obj->aMethodFromTheLibrary();
About that, you can take a look at the Object Inheritance section of the manual.
And, as you guessed, modifying a library is definitly a bad idea : you'll have to re-do that modification each time you update the library !
(One day or another, you'll forget -- or one of your colleagues will forget ^^ )
You could do it with inheritance, but you could also use a decorator pattern if you do not need access to any protected members from SimpleHtml. This is a somewhat more flexible approach. See the linked page for details.
class MySimpleHtmlExtension
{
protected $_dom;
public function __construct(simple_html_dom $simpleHtml)
{
$this->_dom = $simpleHtml;
}
public function removeNode(simple_html_dom_node $node)
{
$node->outertext = '';
return $this;
}
public function __call($method, $args)
{
if(method_exists($this->_dom, $method)) {
return call_user_func_array(array($this->_dom , $method), $args));
}
throw new BadMethodCallException("$method does not exist");
}
}
You'd use the above like this
$ext = new MySimpleHtmlExtension( new simple_html_dom );
$ext->load('<html><body>Hello <span>World</span>!</body></html>');
$ext->removeNode( $ext->find('span', 0) );
I don't why adding the method would be bad, however if you want to so without editing the library, your best bet would be to extend the class like so:
class NewClass extends OldClass {
function newMethod() {
//do stuff
}
}
class myExtenstionClass extends SomeClassInLibrary
{
public function myMethod()
{
// your function definition
}
}
As Pascal suggests... read the manual :-)
I tried these two ways:
(new NewsForm())->getWidgetSchema();
{new NewsForm()}->getWidgetSchema();
With no luck...
PHP does not allow you to do this. Try:
function giveback($class)
{
return $class;
}
giveback(new NewsForm())->getWidgetSchema();
It is a rather weird quirk with the language.
You can't an instanciation and a method call in one instruction... But a way to "cheat" is to create a function that returns an instance of the class you're working with -- and, then, call a method on that function which returns an object :
function my_function() {
return new MyClass();
}
my_function()->myMethod();
And, in this kind of situation, there is a useful trick : names of classes and names of functions don't belong to the same namespace -- which means you can have a class and a function that have the same name : they won't conflict !
So, you can create a function which has the same name as your class, instanciates it, and returns that instance :
class MyClass {
public function myMethod() {
echo 'glop';
}
}
function MyClass() {
return new MyClass();
}
MyClass()->myMethod();
(Yeah, the name of the function is not that pretty, in this example -- but you see the point ;-) )
If it is a static method you can just do this:
NewsForm::getWidgetSchema();
A better option in my opinion would be to use a factory method:
class factory_demo {
public static function factory()
{
return new self;
}
public function getWidgetSchema()
{ }
}
then
factory_demo::factory()->getWidgetSchema()
Of course, you get all the benefits of the factory pattern as well. Unfortunately this only works if you have access to the code, and are willing to change it.