php 特性使用另一个特性

问题描述 投票:0回答:2

我有一个特征正在使用另一个特征,现在我收到了有关类中不存在的函数的错误。

我简化了代码:

settings.php

<?php

trait settings {
    // read setting from config.ini
    protected function getSetting($type, $setting){
        try {
            $configFile = dirname(__FILE__)."/../config.ini";
            if (!file_exists($configFile) || !is_file($configFile))
                throw new Exception("Config file was not found. ");

            $configContents = parse_ini_file($configFile,true);
            if (is_array($configContents) && array_key_exists($type, $configContents) && is_array($configContents[$type]) && array_key_exists($setting, $configContents[$type]))
                return $configContents[$type][$setting];
            else
                throw new Exception("Setting ".$setting." could not be found in ".$type.".");
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }
}

database.php

<?php
trait database {
    use settings, session;

    private $pdo;

    // connect to database
    protected function connect() {
        try {
            $this->pdo = new PDO(
                "mysql:host=".$this->getSetting("db", "host").";dbname=".$this->getSetting("db", "database"),
                $this->getSetting("db", "user"),
                $this->getSetting("db","password")
            );

            $this->init();
        } catch (PDOException $e) {
            throw new Exception($e->getMessage());
        }
    }
}

users.php

<?php

class users {
    use database;

    public function __construct() {
        try {
            $this->connect();
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    public function __destruct() {
        unset($this);
    }

    public function isAdmin() {
        try {
            if ($this->loginStatus() === true) {
            } else
                return false;
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    public function loginStatus() {
        if (!$this->getSession("tysus") || !$this->getSession("tyspw"))
            // user is not logged in because we couldn't find session with username and/or password
            return false;

        if (!$this->userExists($this->getSession("tysus"), $this->getSession("tyspw")))
            // user is unknown to database
            return false;

        // other checks failed, user must be logged in
        return true;
    }
}

现在我收到此错误:

致命错误:在第 18 行 /home/deb2371/domains/nonamenohistory.com/public_html/include/classes/class.database.php 中调用未定义的方法 users::readSetting()

我以为会发生这样的事情: 类

users
使用
database
特征,并且该特征将使用
settings
session
特征。

如果是这样的话,我就不会收到任何错误,但不幸的是,事实并非如此。

有人知道如何解决这个问题吗?

php class oop traits
2个回答
40
投票

代码重用是面向对象编程最重要的方面之一。

一个简单的

Multiple Traits
Composing Multiple Traits
示例,您可以通过它轻松分析您的情况。

  1. 使用多个特征

一个类可以使用多个特征。以下示例演示了如何在 IDE 类中使用多个特征。为了演示,它在 PHP 中模拟了 C 编译模型。

<?php

 trait Preprocessor{
 function preprocess() {
    echo 'Preprocess...done'. '<br/>';
  }
}
trait Compiler{
function compile() {
   echo 'Compile code... done'. '<br/>';
  }
}

trait Assembler{
function createObjCode() {
   echo 'Create the object code files... done.' . '<br/>';
 }
}

trait Linker{
function createExec(){
   echo 'Create the executable file...done' . '<br/>';
  }
}

class IDE{
use Preprocessor, Compiler, Assembler, Linker;

function run() {
 $this->preprocess();
 $this->compile();
 $this->createObjCode();
 $this->createExec();

  echo 'Execute the file...done' . '<br/>';
 }
}
$ide = new IDE();
$ide->run();
  1. 组合多个特征

通过在特征声明中使用 use 语句,特征可以由其他特征组成。请参阅以下示例:

<?php

trait Reader{
public function read($source){
   echo sprintf("Read from %s <br/>",$source);
  }
}

trait Writer{
public function write($destination){
   echo sprintf("Write to %s <br/>",$destination);
  }
}

trait Copier{
use Reader, Writer;
public function copy($source,$destination){
   $this->read($source);
   $this->write($destination);
 }
}

class FileUtil{
use Copier;
public function copyFile($source,$destination){
   $this->copy($source, $destination);
 }
}

22
投票

您的问题可能是由于您使用了

readSetting
但它实际上被称为
getSetting

© www.soinside.com 2019 - 2024. All rights reserved.