我需要检查对象的类是否具有可用于分配值的成员.假设有一个课程: class MyClass: NSObject { var myVar : AnyObject! // ... } 我尝试了这种OBJC样式,但属性是Swift和第二行中的另一种野兽,总是返回false: let myClass: MyClass = MyClass() let hasClassMember = myClass.respondsToSelector(Selector("setMyVar:")) if hasClassMember { myClass.performSelector("setMyVar:", withObject: "Context" as! AnyObject) } 我认为Swift没有像OBJC那样有强大的反思,但是有任何解决方案吗? 更新结果我的代码工作起作用,但是我已将其简化为演示.怪异的部分是,一旦我将myvar的类型变为某些自定义类的实
以下是关于 reflection 的编程技术问答
我正在处理处理敏感数据的静态库.必须使用库的开发人员不能在库上使用反射. 在Android上,我们通过开发service s的aar文件来解决问题,然后将service运行到单独的过程中;(当服务运行到另一个过程中时,开发人员无法使用反射)但是我想知道iOS中是否存在类似的东西? 我们可以将静态库执行到一个单独的过程中吗?如果没有,我们如何避免在静态库上进行反思? 例如: MyTestObject *obj = [[[myTestView alloc] init ]; //=========================================== Class clazz = [obj class]; u_int count; Ivar* ivars = class_copyIvarList(clazz, &count); NSMutableArra
我有一个模型类,其中包含一些静态变量和属性.在运行时我可以获取属性; let instance = entity.init() let mirror = Mirror(reflecting:instance) var propertyStrings = [String]() for (propertyName, childMirror) in mirror.children { } ,但我也想将课程的静态变量作为列表.那么,如何获取静态变量的名称和值列表?这是我的模型类的结构: class ActionModel: NSObject { static let kLastModified = "LastModified" static let kEntityName = "EntityName" static let kIdentifier = "Id" var lastModified: Int64 var entityName: String? var i
我正在使用反射来从一种方法中获取DOC评论: http://www.php./www.php.net/manual/manual/manual/en/reflection clectionclass.getDoccomment.php ,看起来像这样: /** * Method description * * @param array $foo Bla bla * @return string More bla bla */ 如何将此字符串解析为可以使用的东西? 我需要从中提取"方法描述"文本.其他东西对我来说并不重要,因为我可以使用其他反射方法获取参数等. 解决方案 trim(str_replace(array('/', '*'), '', substr($rc->getDocComment(), 0, strpos($rc->getDocComment(), '@')))); 假设评论始终以这
我有一个在使用php5反射API的Windows&Mac上完美工作的应用程序. 我试图将应用程序部署到Linux计算机(运行PHP 5.3.6的CentOS框),只是发现ReflectionMethod::getDocComment()函数不会返回任何内容.我调查了一段时间,发现线末端是一个潜在的罪魁祸首. 我使用服务器上的dos2unix实用程序将所有线路端都更改为Unix风格,并且脚本可工作.现在,这是一个奇怪的部分:它只能使用 .这样,我的意思是,从ReflectionMethod::getDocComment()中返回数据的脚本一次,然后(没有对磁盘或代码上的文件进行任何修改),它会恢复为不工作. 任何帮助或建议将不胜感激. 解决方案 而不是全球打开它,您可以在.htaccess中使用php_flag这样: php_flag eaccelerator.enable 0 php_flag eaccelerator.optimizer 0 我遇到了
因此,我正在使用一个设置类,该类别扩展了基本设置类,该类别类似于"全局设置".有几种服务,每个服务都有自己的设置类,可以扩展抽象基础设置类.抽象基础设置类对应于服务之间共享的设置.因此,首先,我将在下面说明一个示例,然后我将定义问题: 示例: abstract class BaseSettings { protected $settingA; protected $settingB; } class MyServiceSettings extends BaseSettings { private $settingC; public $settingD; } 问题: 如果我创建了像这样的ReflectionClass实例. $reflect = new ReflectionClass($this); ..来自MyServicesettings类或底层类(因为显然您不能具有抽象类的实例),$reflect->getProper
是否可以反思一系列方法呼叫来确定您在呼叫链中的哪个点? 至少,是否可以辨别方法是否是链中的最后一个调用? $instance->method1()->method2()->method3()->method4() 是否可以使用返回对象实例的属性进行相同的操作? $instances->property1->property2->property3->property4 解决方案 如果您要调用的所有方法都返回相同对象以创建流利的接口(而不是将不同的对象链接在一起),则记录方法应该很微不足道在对象本身中呼叫. eg: class Eg { protected $_callStack = array(); public function f1() { $this->_callStack[] = __METHOD__; // other work } public function f2
通过反射,很容易获得开始和终点线,例如源文件中的方法:ReflectionFunctionAbstract::getFileName(),ReflectionFunctionAbstract::getStartLine(),ReflectionFunctionAbstract::getEndLine()提供此功能.但是,这似乎与属性不起作用.至少在类定义中提取属性声明的起点名称和文件名的最佳方法是什么? 解决方案 这并不容易,但也不是太难了. 您可以通过反射定义属性.从那里您可以获取文件名.然后,您要么要做的就是将文件归为tokenize,然后在属性声明的哪一行中检查,或者只是按行逐行访问文件并匹配字符串. 这是一种可能的方法: $reflector = new ReflectionProperty('Foo', 'bar'); $declaringClass = $reflector->getDeclaringClass(); $classFile
我试图从班级中获得DOC评论,并且为了我的一生,我不知道为什么GetDoccomment()返回错误.我希望getDoccomment返回 @whate. getDocComment()); 输出: 布尔(false) $ php --version PHP 5.5.1 (cli) (built: Aug 31 2013 01:32:53) Copyright (c) 1997-2013 The PHP Group Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies with Zend OPcache v7.0.2-dev, Copyright (c) 1999-2013, by Zend Technologies 解决方
我必须列出cordrence 的类实例的对象 class Foo {} class Foo1 {} $obj1 = new Foo; $obj2 = new Foo; $obj32 = new Foo1; 我需要一个解决方案来获取所有是Foo类实例的对象 你知道该怎么做吗? 解决方案 获得类的所有实例的解决方案是创建实例化类的记录: class Foo { static $instances=array(); public function __construct() { Foo::$instances[] = $this; } } 现在,全球可访问的数组Foo::$instances将包含该类的所有实例.您的问题有点广泛,所以我不能确切地说这是否是您想要的.如果没有,希望它可以帮助您更清楚您要寻找的内容. 其他解决方案 请参阅此答案 PHP 过去为我做了这一点.
我一直在看PHP反射方法,我想做的是在打开方法和任何返回值之前注入一些代码,例如我要更改: function foo($bar) { $foo = $bar ; return $foo ; } 并将一些代码注入其中,例如: function foo($bar) { //some code here $foo = $bar ; //some code here return $foo ; } 可能? 解决方案 查看其他解决方案 好吧,一种方法是使所有方法称为"虚拟": class Foo { protected $overrides = array(); public function __call($func, $args) { $func = strtolower($func); if (isset($this->overrides[$func])) {
请考虑以下示例代码: getParameters()); $s=serialize($r); $r=unserialize($s); var_dump($r->getParameters()); ?> 产生以下输出: array(0) { } Fatal error: ReflectionFunctionAbstract::getParameters() [reflectionfunctionabstract.getparameters]: Internal error: Failed to retrieve the reflection object in [...]test.php
以下代码正常. LibraryTests::TestGetServer(); 获取库的函数数组并运行它们: $methods = get_class_methods('LibraryTests'); foreach ($methods as $method) { call_user_func('LibraryTests::' . $method . '()' ); } 这引发了一个错误:Warning: call_user_func(LibraryTests::TestGetServer()) [function.call-user-func]: First argument is expected to be a valid callback 这是称为: 的类 class LibraryTests extends TestUnit { function TestGetServer() { TestUnit::AssertEqu
我想从列表中排除所有遗传方法,这些方法 那么如何知道课堂成员是否是从特质继承的? 是的,我可以这样检查: if ($trait->hasMethod($methodName) || $ref->getTraitAliases()[$methodName] !== null) { // } 但是,如果特征方法在班级中被超越了怎么办?怎么知道? 一种方法是检查方法主体是否相似,如果是的话,我可以将其排除, 但是有更好的方法可以实现这一目标吗? 解决方案 重要说明 这仅仅是因为在实际情况下您不应该关心的"学术"兴趣 - 从方法得出的地方,因为它与特征的思想相矛盾,例如透明替代. 同样,由于特征的工作方式,任何这种操作都可能被视为" hacky",因此行为可能在不同的PHP版本中有所不同,我不建议依靠这一点. 区别:困难 在PHP的反射中,有想象一下,有方法foo()和bar()有特质X,并且
在这里考虑此代码: final class TinkerWithMe { protected $key1 = 19; private $key2 = 88; } $class = new TinkerWithMe(); $getKeys = function() { return array($this->key1, $this->key2); }; $oldKeys = $getKeys->call($class); $newKey1 = 96; $newKey2 = 42; $setKeys = function() use ($newKey1, $newKey2) { $this->key1 = $newKey1; $this->key2 = $newKey2; }; $setKeys->call($class); 当您可以轻松地封闭或反思时,为什么要烦恼OOP的可见性? 是否有一种阻止我缺少这种事情的方法?
我刚刚在我的宠物项目dump_r() 中重新设计了递归检测算法 https://github.com/leeoniya/dump_r.php 检测对象递归并不难 - 您使用spl_object_hash()获取对象实例的唯一内部ID,将其存储在dict中并在倾倒其他节点时对其进行比较. 对于阵列递归检测,我有点困惑,我没有发现任何有用的东西. PHP本身能够识别递归,尽管它似乎为时已晚. 编辑:NVM,它发生在需要的地方:) $arr = array(); $arr[] = array(&$arr); print_r($arr); 它是否必须诉诸于跟踪递归堆栈中的所有内容,并与其他所有数组元素进行较浅的比较? 任何帮助将不胜感激, 谢谢! 解决方案 由于PHP的逐个调用机制,我在这里看到的唯一解决方案是逐个迭代数组,并在其中设置一个任意值,稍后您您是否存在它是否存在以查找是否存在以前在那里: function iterate_array(&$a
我有一个具有公共和受保护特性的类Foo. Foo需要有一个非静态方法,getPublicVars()返回Foo的所有公共属性列表(这只是一个示例,我从外部知道 the Foo对象调用 get_object_vars() 将实现这一目标,并且不需要我的getPublicVars()方法). ). 注意:此还必须返回在运行时分配的动态声明的属性,为类实例(对象),这些属性(对象)在类的定义中未定义. 这是一个示例: class Foo{ private $bar = '123'; protect $boo = '456'; public $beer = 'yum'; //will return an array or comma seperated list public function getPublicVars(){ // thar' be magic here... } } $foo = new F
我知道PHP 5.5上有一个静态class字段,但我必须坚持使用PHP 5.4.是否可以从变量中获取完全合格的类名称? 示例: namespace My\Awesome\Namespace class Foo { } 以及代码中的其他地方: public function bar() { $var = new \My\Awesome\Namespace\Foo(); // maybe there's something like this?? $fullClassName = get_qualified_classname($var); // outputs 'My\Awesome\Namespace\Foo' echo $fullClassName } 解决方案 您应该使用 get_class 如果您使用的是命名空间,此功能将返回类的名称,包括名称空间,因此请注意您的代码是否对此进行检查. namespac
使用以下功能: function is_closure($t) { return ( !is_string($t) && is_callable($t)); } 除了匿名闭合功能以外,其他任何东西都可以返回true吗?如果是这样,确定的正确方法是什么? 是否是变量? 非常感谢 解决方案 检查回调是否实际关闭的最确定性方法是: function is_closure($t) { return $t instanceof \Closure; } 所有匿名函数均表示为PHP中类型Closure的对象. (回到上述评论,恰好实现了__invoke()方法.) 其他解决方案 我认为您可以使用instanceof Closure,尽管手册指出这不应依靠.我想它可以正常工作现在. 当前使用闭合类实现匿名功能.这是一个实施细节,不应依靠. 更新 闭合手动页面已更新了有关此的指南.看来这种行为现在可以依靠. 在PHP 5.3中实现的匿