ASP.NET/C#属性特性类的PHP版本

5

有这样的东西吗?

我想在PHP中做类似的事情,但我无法从PHP文档中看到如何实现:

public class User : ValidationBase
{  
  [NotNullOrEmpty(Message = "Please enter a user name.")] 
  public string UserName { get; set; } 
}

我需要的是 PHP 中等价于 ASP.NET/C# 属性标记的功能,上面的示例中通过属性声明之前的 [NotNullOrEmpty(Message = "Please enter a user name.")] 行来表示。
8个回答

8

这看起来是我正在寻找的最接近的东西。非常感谢,Andy。 - Stepppo

2
Andy Wilson提供的答案链接已经失效。你可以通过http://web.archive.org/web/20130116184636/http://interfacelab.com/metadataattributes-in-php/访问到该页面,但是作者提到的代码下载链接也已经失效。
不过,我后来在这里找到了一个很好的PHP注释实现:https://github.com/mindplay-dk/php-annotations 目前唯一的缺点是它要求文件名和类名相同并且大小写相同,而Code Igniter不符合这个要求。但是一旦解决了这个问题,它就能正常工作了。当然,这个限制并不会影响所有的实现。

1

不,至少在 PHP 中没有原生支持。

你可以使用一个框架来为表单提供验证,例如Zend Framework有一个 Zend_Form类,允许指定字段是否必填、它们应该是什么类型以及如果不是这样显示的错误消息。


0

在 PHP 中没有这样的功能,您实际上必须编写代码来实现它。

我想应该是这样的:

public function setUserName($str) {
    if (empty($str)) {
        throw new Exception('Please enter a user name.');
    }
    $this->userName = $str;
}

public function getUserName($str) {
    return $this->userName;
}

0

PHP没有属性或属性特性。

如果您想在PHP中实现类似的功能,您需要声明一个私有字段,并编写公共的getter和setter方法,在setter方法中进行某种形式的空值检查。

class User extends ValidationBase
{
    private $userName;
    public function GetUserName()
    {
        return $this->userName;
    }
    public function SetUserName($val = '')
    {
        if ($val === '')
        {
            return false;
        }
        else
        {
            $this->userName = $val;
            return true;
        }
    }
}

0

我认为一些框架可以提供这种功能,但PHP并不是设计用来提供这样高级结构的。


0

我在反射中使用了文档注释。更多信息请参见ReflectionClass::getDocComment

这里是一个示例代码来自我的项目

/**
* You can use doc comments in reflection. 
* See more info https://php.net/manual/en/reflectionclass.getdoccomment.php
* 
* @role("admin")
*/
class permissiontest extends Page
{
    public function render($p)
    {
        echo 'Howdy friend!';
        //$this->renderView($p);
    }
}

反射

class handler 
{
    public function OnPageRendering($page)
    {
        $r = new ReflectionClass(get_class($page));
        $s = $r->getDocComment();
        if (!str::isNullOrEmpty(trim($s))) {
            // tags::pre($s);
            /**
             * @role("filter")
             */
            $matches = array();
            //@role("filter") https://regex101.com/
            preg_match('/@role\(\"(.*)\"\)/', $s, $matches);
            if (!arrays::isNullOrEmpty($matches)) {
            // tags::pre($matches);//Array ( [0] => @role("filter") [1] => filter ) 
            // tags::pre($matches[0]);//@role("filter")        
            // tags::pre($matches[1]);//filter
                $filter = $matches[1];
                //tags::h("Check Permission for:".$filter);
                if (!userHasRights($filter)) {
                    die('You do not have permission on this page! Process stopped!');
                }
            }

        }


    }
}
function userHasRights($right) {
    return false;
}

0

正如其他答案所提到的,使用 PHP 5.0 以下版本是不可能的,但是自从 PHP 5.0 可以使用DocComment来模仿 C# 的功能。

我从this question中得到了灵感,并为此问题修改了它。可以使用JSON字符串作为DocComment,以便稍后更轻松地解析并从代码中使用反射访问它们,如下所示。

<?php
/** {"Description":"This is a test class"} */
class User {

   /** {"Message":"Please enter a user name."} */
   public $Username;

   /** {"Message":"Please enter a user name."} */
   public function Login($username) {
        print "Inside `aMemberFunc()`";
    }
}

$rc = new ReflectionClass("User");  // class name
print $rc->getDocComment()                          . "<br />\n"; // Get Class comment
print $rc->getMethod("Login")->getDocComment()      . "<br />\n"; // Get Method comment
print $rc->getProperty("Username")->getDocComment() . "<br />\n"; // Get Property comment

?>

以下是结果

/** {"Description":"This is a test class"} */
/** {"Message":"Please enter a user name."} */
/** {"Message":"Please enter a user name."} */

从这里开始更进一步应该很容易,删除DocComment标记并将其解析为JSON,以获得具有您属性的对象。还有更多的反射方法可用,例如获取属性、方法和常量的列表,您可以在PHP反射手册中了解到它。

注意:使用Zend等编译时,将从您的代码中删除注释,并且它们将不可用,因此您需要配置平台使其忽略注释。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接