I need to define a class in many classes and i should use all of this class in one class ! And $this dosn't work on this way .
Undefined variable
class main extends Controller{
//some codes
}
In another file
class site{
function test(){
include main.php;
$obj = new main();
class first{
function name(){
$obj->somefunction();
}
}
class second{
function family(){
$obj->somefunction();
}
}
}
}
First of all, class declaration cannot be nested: You can't declare a class within a class, nor within a function.
As per your second question, if you want to have different classes with the same name, you should use namespacing to differentiate them.
Also, you should follow the PSR coding style convention (http://www.php-fig.org/psr/psr-2/)
Have a look at : http://php.net/manual/en/language.namespaces.php
Related
Normally I have a question about something not working, now I have a question about something that IS working, I am just confused as to why. This is the structure that I have in Laravel:
ExampleController
use App\Http\Traits\Trait1;
use App\Http\Traits\Trait2;
ExampleController extends Controller {
use Trait1, Trait2;
public function index()
{
// I can use methods from Trait1 and Trait2 here, works fine
}
}
Trait1
namespace App\Http\Traits;
trait Trait1 {
exampleMethodTrait1()
{
}
}
Trait2
namespace App\Http\Traits;
trait Trait2 {
$test = $this->exampleMethodTrait1();
}
Calling a method defined in Trait1 from Trait2 actually works, while I have not added use App\Http\Traits\Trait1; in Trait2. Is that because they are both loaded in the controller?
Okay, Let me put same code and explain you why it is working.
Trait1
<?php
namespace App\Http\Traits;
trait Trait1 {
public function exampleMethodTrait1()
{
echo 'okay';
}
}
?>
Trait 2
<?php
namespace App\Http\Traits;
trait Trait2 {
public function bar() {
var_dump(get_class($this));
$test = $this->exampleMethodTrait1();
}
}
?>
MyController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Traits\Trait1;
use App\Http\Traits\Trait2;
class MyController extends Controller
{
use Trait1, Trait2;
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$this->bar();
}
}
Now, if you will notice in Trait 2, var_dump(get_class($this)); $this is instance of MyController and not instance of trait 2, that is how it is working and it is expected behavior.
Now if you want to know if you can use one trait in side another
YES
You can do like
TaraitA
Trait A {
}
TraitB
Trait B {
use A;
}
And it will work fine.
Yes, they are both loaded in your controller as a part of it therefore they have access between them also controller methods
See the example 4
https://www.php.net/manual/en/language.oop5.traits.php
Regards
I think your confusion comes from believing that the $this inside a trait corresponds to the trait itself. But it is not.
Traits are nothing by themselves: they exists only in the context of a real class, as a helper to copy-paste methods around but not visually polluting your actual classes.
The $this you use to call exampleMethodTrait1 is not an instance of Trait2 (nor Trait1) but an instance of ExampleController, that has copied the methods over from the traits.
This doesn't happen only with traits, though, but also with parent classes in the hierarchy:
Example
abstract class Base {} // First level of inheritance
class Building extends Base {} // Second level of inheritance
class House extends Building {} // Last level of inheritance
$this (and static) always corresponds to an instance of the most concrete class of the hierarchy (the last level of inheritance).
self instead refers to the actual class instance (the same level of inheritance where the method is defined). Still never a trait, they cannot be instantiated by themselves.
the traits are not part of the hierarchy, but blindly pasted where you use them.
I'm trying to place a trait inside a class called Page. I also need to rename a trait function so that it doesn't clash with an existing class function. I thought I did all this successfully however I get an error that points to the wrong location?!
Call to undefined function App\Pages\Models\myTraitDefaultScope()
I've also tried: MyTrait\defaultScope($query) instead of trying to rename the conflicting function. But I then get the following error:
Call to undefined function App\MyTrait\defaultScope()
Below is the trait and class contained in separate files.
<?php
namespace App;
use Illuminate\Support\Facades\Auth;
trait MyTrait{
public function defaultScope($query){
return $query->where('active', '1')
}
}
.
<?php namespace Modules\Pages\Models;
use Illuminate\Database\Eloquent\Model;
use App\MyTrait;
class Page extends Model {
use MyTrait{
MyTrait::defaultScope as myTraitDefaultScope;
}
public function defaultScope($query){
return myTraitDefaultScope($query);
}
}
I'm not all that awesome at this so please don't shoot if I've got something badly wrong :)
When you 'use' a trait in your class, the class inherits all the methods and properties of the trait, like if it was extending an abstract class or an interface
So, this method of MyTrait:
public function defaultScope($query){
return $query->where('active', '1')
}
will be inherited by your Page class
As you have aliased this method as: myTraitDefaultScope, to call the method you should call it in the same way you would call every other method of the Page class:
public function defaultScope($query){
//call the method of the class
return $this->myTraitDefaultScope($query);
}
As you're using trait. So it points to the current or parent class. Thus, calling any method should be like $this->method($params); syntax.
I am creating a plugin for a CMS that provides a few base classes (let's say one of these classes is called Base). This class has a few helper methods that must be overwritten in the extending class. We should note that the base methods have default parameters/values provided. In one version of the LMS these values are provided by reference in the next version just by value.
For example (CMS v1.0):
function prepareTable(&$table){...
CMS v1.1:
function prepareTable($table){...
When you extend the Base class and overwrite the prepareTable method you have to declare it with the same default parameters/values as well, otherwise a STRICT PHP warning is displayed (on by default in PHP 5.4).
My question is, how do I conditionally overwrite the method from the parent class in a working way, knowing the version of the parent CMS?
Here's what I have currently (not working at the moment):
class Base{
function prepareTable(&$table){
}
}
class Extending extends Base{
if(CMS_VERSION=='1.0')
function prepareTable(&$table){
else
function prepareTable($table){
echo $table;
}
}
Obviously, I can not edit the Base and its method directly.
EDIT: Here's the exact error message:
Strict standards: Declaration of Extending::prepareTable() should be compatible with Base::prepareTable($table) in.
the only way I can think of achieving this without duplicating the code inside prepareTable is to create a pseudo function that gets called inside prepareTable and then declare that in the final extended class
if(CMS_VERSION=='1.0') {
class Base2 extends Base{
function prepareTable(&$table){
return $this->prepareTable2($table);
}
function prepareTable2(&$table){
}
}
} else {
class Base2 extends Base{
function prepareTable($table){
return $this->prepareTable2($table);
}
function prepareTable2(&$table){
}
}
}
class Extending extends Base2{
function prepareTable2(&$table){
echo $table;
}
}
if(CMS_VERSION=='1.0') {
class Extending extends Base{
function prepareTable(&$table){
}
}
} else {
class Extending extends Base{
function prepareTable($table){
}
}
}
Note that the if/else check must be done before the class is defined, not inside the class. Essentially, you are building two different versions of the class.
Side Note: If you need to include shared methods, that won't be changed between the two versions of the class, you can define a new class that will extend Extending, create the shared methods there and use this new class.
For example (place this after the code above):
class ExtendingFull extends Extending{
// Here you may include your shared methods
// e.g:
public function sharedMethod(){
echo 'test';
}
}
I've got a TopLevelClass that calls AnotherClass which has functions. From inside functions, how do you access some_other_methods() for TopLevelClass?
If it were JavaScript-esque my problem would look like:
$this->parent()->parent()->do_something()
and it would be equivalent to
$this_function->AnotherClass()->LevelClass()->some_other_methods()
if you are using proper inheritance, you just need the parent keyword.
class foo {
protected function fooMethod() {}
}
class bar extends foo {
public function barMethod() {
parent::fooMethod();
// technically, you could do the same thing with $this->fooMethod()
// but this way you also know how to do it with methods that might have
// the same name as one another, such as parent::__construct()
}
}
Out the top of my head:
parent::some_other_methods();
You could make AnotherClass extend TopLevelClass with:
class AnotherClass extends TopLevelClass {
// class stuff in here
}
This would give AnotherClass access to all the methods in TopLevelClass as well as it's own (subject to Private scope status).
I'm trying to find out weather I can do this or not. I have a class called Template. and I want to extend that classes functionality in another file, but I don't want to change the name.
Do I declare it as
class template extends template
{
// code here
function foo()
{
}
}
or do I just declare it like this?
class template
{
// write function
function foo()
{
}
}
Only if the parent class is in another namespace.
use SomeNamespace\Template as BaseTemplate;
class Template extends BaseTemplate
{
//...
}
If you wanted to use a method/property of the original class you can extend it but you must use a different name, otherwise you'll get an error about redeclaring the class.
Basically:
class template {}
/* both fail with "cannot redeclare class template */
class template extends template {}
class template {}
I am pretty sure you can not. I would suggest you do the following:
class Template extends TemplateBase
{
// code
}
read more at: http://www.php.net/manual/en/language.oop5.php
You might want to check out classkit