Reputation: 129
Maybe I'm not getting the whole trait system so I thought I'd ask StackOverFlow.
I made my first trait...
<?php
trait MY_Stat
{
var $dex;
var $int;
var $str;
}
?>
I can't manage to make it work with my class whatsoever ( in another file ) ....
class MY_Mobile
{
use MY_Stat;
public function __construct($params = NULL)
{
var_dump($this);
}
}
I'm always hitting this wall :
Fatal error: Trait 'MY_Trait' not found in ...\wamp\www\game\application\libraries\MY_Mobile.php
I would like to have this trait in many classes, namely, Mobiles, Items, etc... Am I supposed to have the definition of the trait in the same file as the class ?
On a sidenote, if you're using codeigniter, how did you manage to make it load, are you setting your traits into a helper file, library file... ?
Upvotes: 0
Views: 2307
Reputation: 81
Taking advantage of spl_autoload_register
I had to make a small modification in the codeigniter index.php file
Codeigniter index.php
function load_traits($traits)
{
$traits_found = [];
$traitsBasePath = APPPATH .'traits';
find_trait($traitsBasePath, $traits, $traits_found);
foreach ($traits_found as $found)
include_once $found;
}
function find_trait($dir, $searchForTrait, &$found)
{
if(is_string($searchForTrait))
{
$dirHandle = opendir($dir);
if($dirHandle !== FALSE)
{
while (false !== ($entry = readdir($dirHandle)))
if($entry != '.' && $entry != '..')
if(is_dir($dir. '/' .$entry))
find_trait($dir. DIRECTORY_SEPARATOR .$entry, $searchForTrait, $found);
else
if(strpos($dir. DIRECTORY_SEPARATOR .$entry,
str_replace("/", DIRECTORY_SEPARATOR, $searchForTrait . '.php')) !== FALSE)
array_push($found, $dir. DIRECTORY_SEPARATOR .$entry);
}
else
die("Traits directory does not exists");
}
else if(is_array($searchForTrait))
{
$dirHandle = opendir($dir);
if($dirHandle !== FALSE)
{
while (false !== ($entry = readdir($dirHandle)))
if($entry != '.' && $entry != '..')
foreach ($searchForTrait as $sTrait) {
if(is_dir($dir. '/' .$entry))
find_trait($dir. DIRECTORY_SEPARATOR .$entry, $sTrait, $found);
else
if(strpos($dir. DIRECTORY_SEPARATOR .$entry,
str_replace("/",
DIRECTORY_SEPARATOR,
$sTrait . '.php')) !== FALSE)
array_push($found, $dir. DIRECTORY_SEPARATOR .$entry);
}
}
else
die("Traits directory does not exists");
}
else
die("Parameter must be string or array");
}
spl_autoload_register(function($traitname) {
load_traits($traitname);
});
Having saying that, you must to create a traits
folder into codeigniter application
directory and create your traits there.
How do i use this?
In any controller you just use it as follows
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Store extends CI_Controller {
use test_trait;
}
When use test_trait
the file test_trait.php
will be searched in traits directory. If the file is found will be automatically included
Upvotes: 0
Reputation: 127
I got this answer from somewhere, now I don't remember from where. anyway
in models folder, create a file named trait_autoloader.php
<?php
defined('BASEPATH') OR exit('No direct access to script is allowed');
class trait_autoloader{
public function __construct(){
return $this->init_autoloader();
}
private function init_autoloader(){
spl_autoload_register(function($classname){
if(strpos($classname, 'trait') !== false){
strtolower($classname);
require('application/traits/'.$classname.'.php');
}
});
}
}
Now that you are done with it open autoload file in config folder in applications folder and put 'trait_autoloader' in the following line,
autoload['model'] = array( 'trait_autoloader' );
In applications folder, create a folder named traits and put your traits in that folder, caution: do use 'trait' prefix for all the files in that folder. In this case I used a simple file with name traitFunction.php
<?php
defined('BASEPATH') OR exit('No direct access to script is allowed');
trait traitFunction{
public function FunctionName(){
//Function Body
}
}
Now that you are done with it. put the following line in any model class you want and they will work fine.
use traitFunction;
Do remember, that this function only works with models.
Upvotes: 0
Reputation: 560
Another alternative that works for me.. where model_base is in the model folder
@include_once ('model_base.php');
class device_token extends CI_Model {
// PHP 5.4 Traits
use model_base;
Upvotes: 0
Reputation: 10132
Well you can workout this problem by doing something like this:
Path:
application/helpers/your-trait-class.php
Contents:
<?php
if (!trait_exists('MY_Stat')) {
trait MY_Stat
{
public $dex;
public $int;
public $str;
}
}
In your library just include the trait class (as i said) manually. After the !defined('BASEPATH');
line.
Your Library:
include APPPATH . 'helpers/your-trait-class.php';
class YourLibrary {
use MY_Stat;
and use trait class properties within your library methods like this:
$this->dex = 0.1;
$this->int = 1;
$this->str = 'Hello';
Upvotes: 2