如何在php中获取给定函数的名称?

时间:2013-12-19 02:11:35

标签: php design-patterns user-defined-functions

tl; dr:我需要获取给定函数的名称,但不是我当前的函数。

例如,代码中的“getFunctionName()”如下:

$listFieldNames = array(
    getFunctionName($country->getName()) => 'Name',
    getFunctionName($country->getAcronym()) => 'Acronym'
);

您可能想知道我为什么要这样做。好吧,当我考虑如何在我的应用程序中处理用户输入时,我提出了这个问题。在阅读了很多关于使用或不使用异常来验证用户输入的讨论后,我最终选择使用Notification类(我使用的是Zend Framework 1.12):

class Application_Model_Notification
{
    protected $message;
    protected $fieldName;
    protected $code;

    public function __construct($message, $fieldName = NULL, $code = NULL)
    {
        return $this->setMessage($message)
            ->setFieldName($fieldName)
            ->setCode($code);
    }

    // getters and setters;
}

当我验证用户发送的数据时,对于输入错误的每个字段,我将通知推送到数组中。每个通知都使用$ fieldName属性来标识包含有问题信息的字段。

这样,我可以向用户显示输入错误的字段,并将消息放在匹配字段附近。因为Model中的属性可以与UI表单名称具有不同的名称(特别是当webdesigner和webdeveloper不是同一个人时),我需要构建一个匹配它们的列表。这就是问题所在:我想避免使用普通字符串构建该列表。原因是我可以在模型中更改属性的名称,在列表中更改它也会很痛苦。否则,如果我使用其getter的名称,我可以使用IDE的refactor命令轻松更改它。我只是不知道如何得到它!它不是通过使用魔术常量,因为它们只适用于当前的函数/方法,而我的情况是关于给出的任何方法......

我不知道我所做的事情是否是一种好习惯,所以我正在贬低我打算做的事情:

在国家/地区控制器中

public function insertAction()
{
    $country = new Application_Model_Country();
    $country->setName($this->getParam('Name'))
        ->setAcronym($this->getParam('Acronym'));

    $bloCountry = new Application_Model_Business_Country();
    try {
        // The aforementioned list
        $listFieldNames = array(
            getFunctionName($country->getName()) => 'Name',
            getFunctionName($country->getAcronym()) => 'Acronym'
        );

        $bloCountry->insert($country, $listFieldNames);
        if ($bloCountry->countNotifications() > 0) {
            $this->view->notifications = $bloCountry->getNotifications();
        } else {
            $this->view->success = 'Country saved succesfuly.';
        }
    } catch (Exception $e) {
        $this->view->error = $e->getMessage();
    }
}

在模型中的国家业务对象

protected $_country;
protected $_notifications;

// Constructor, getters, setters and other methods
// (...)

protected function validate($country, $listFieldNames)
{
    if (trim($country->getName()) == '') {
        $_notifications[] = new Application_Model_Notification(
            'The country name must be specified',
            $listFieldNames[getFunctionName($country->getName())]
        );
    } else {
        $_country->setName(trim($country->getName()));
    }
}

public function insert($country, $listFieldNames)
{
    $this->validate($country, $listFieldNames);
    if (countNotifications() > 0) {
        return 0;
    } else {
        $daoCountry = new Application_Model_DbTables_Country();
        return $daoCountry->save($this->_country);
    }
}

提前致谢!

1 个答案:

答案 0 :(得分:3)

因此,对于来自Web的每个自定义字段,您将需要一个在其上调用的验证函数。您可以在模型级别执行此操作。你将不得不自己定义;你将不得不做一些工作。

定义接口提供了一个合同,每个模型都不能破解。这意味着您可以期望实现它的每个类/模型都定义了这些函数。

interface FieldValidationInterface
{
    public function isValid();
    public function getNotifications();
}

class Country implements FieldValidationInterface
{
    /**
     * Check to see if the model is valid 
     * by checking every field
     */
    public function isValid()
    {
        $valid = true;

        // go through each private member
        if (!$this->name) {
            $this->notifications['name'] = 
                'The country name must be specified';
            $valid = false;
        }

        return $valid;
    }

    public function getNotifications()
    {
        return $this->notifications;
    }
}

// The logic for insertAction()
if (!$coutry->isValid()) {
    foreach ($country->getNotifications() as $field => $msg) {
        // do something to report to the web: 
        // which field was bad ($field), and why ($msg)
    }
}