当我们使用一个类时既没有源码也没有文档时(尤其是php扩展提供的类,比如mysqli,Redis类),我们该怎么知道这个类中提供了哪些方法,以及每个方法该怎么使用呢,此时就该PHP中强大的反射登场了,下面以Redis扩展为例用代码演示:
当我们使用一个类时既没有源码也没有文档时(尤其是php扩展提供的类,比如mysqli,Redis类),我们该怎么知道这个类中提供了哪些方法,以及每个方法该怎么使用呢,此时就该PHP中强大的反射登场了,下面以Redis扩展为例用代码演示:
-
-
-
$ref = new ReflectionClass('Redis');
-
-
$consts = $ref->getConstants(); //返回所有常量名和值
-
echo "----------------consts:---------------" . PHP_EOL;
-
foreach ($consts as $key => $val)
-
{
-
echo "$key : $val" . PHP_EOL;
-
}
-
-
$props = $ref->getDefaultProperties(); //返回类中所有属性
-
echo "--------------------props:--------------" . PHP_EOL . PHP_EOL;
-
foreach ($props as $key => $val)
-
{
-
echo "$key : $val" . PHP_EOL; // 属性名和属性值
-
}
-
-
$methods = $ref->getMethods(); //返回类中所有方法
-
echo "-----------------methods:---------------" . PHP_EOL . PHP_EOL;
-
foreach ($methods as $method)
-
{
-
echo $method->getName() . PHP_EOL;
-
}
返回结果:
-
----------------consts:---------------
-
REDIS_NOT_FOUND : 0
-
REDIS_STRING : 1
-
REDIS_SET : 2
-
REDIS_LIST : 3
-
REDIS_ZSET : 4
-
REDIS_HASH : 5
-
ATOMIC : 0
-
MULTI : 1
-
PIPELINE : 2
-
OPT_SERIALIZER : 1
-
OPT_PREFIX : 2
-
OPT_READ_TIMEOUT : 3
-
SERIALIZER_NONE : 0
-
SERIALIZER_PHP : 1
-
OPT_SCAN : 4
-
SCAN_RETRY : 1
-
SCAN_NORETRY : 0
-
AFTER : after
-
BEFORE : before
-
--------------------props:--------------
-
-
-----------------methods:---------------
-
-
__construct
-
__destruct
-
connect
-
pconnect
-
close
-
ping
-
echo
-
get
-
set
-
setex
-
psetex
-
setnx
-
getSet
-
randomKey
-
renameKey
-
renameNx
-
getMultiple
-
exists
-
delete
-
incr
-
incrBy
-
incrByFloat
-
decr
-
decrBy
-
type
-
append
-
getRange
-
setRange
-
getBit
-
setBit
-
strlen
-
getKeys
-
sort
-
sortAsc
-
sortAscAlpha
-
sortDesc
-
sortDescAlpha
-
lPush
-
rPush
-
lPushx
-
rPushx
-
lPop
-
rPop
-
blPop
-
brPop
-
lSize
-
lRemove
-
listTrim
-
lGet
-
lGetRange
-
lSet
-
lInsert
-
sAdd
-
sSize
-
sRemove
-
sMove
-
sPop
-
sRandMember
-
sContains
-
sMembers
-
sInter
-
sInterStore
-
sUnion
-
sUnionStore
-
sDiff
-
sDiffStore
-
setTimeout
-
save
-
bgSave
-
lastSave
-
flushDB
-
flushAll
-
dbSize
-
auth
-
ttl
-
pttl
-
persist
-
info
-
resetStat
-
select
-
move
-
bgrewriteaof
-
slaveof
-
object
-
bitop
-
bitcount
-
bitpos
-
mset
-
msetnx
-
rpoplpush
-
brpoplpush
-
zAdd
-
zDelete
-
zRange
-
zReverseRange
-
zRangeByScore
-
zRevRangeByScore
-
zRangeByLex
-
zCount
-
zDeleteRangeByScore
-
zDeleteRangeByRank
-
zCard
-
zScore
-
zRank
-
zRevRank
-
zInter
-
zUnion
-
zIncrBy
-
expireAt
-
pexpire
-
pexpireAt
-
hGet
-
hSet
-
hSetNx
-
hDel
-
hLen
-
hKeys
-
hVals
-
hGetAll
-
hExists
-
hIncrBy
-
hIncrByFloat
-
hMset
-
hMget
-
multi
-
discard
-
exec
-
pipeline
-
watch
-
unwatch
-
publish
-
subscribe
-
psubscribe
-
unsubscribe
-
punsubscribe
-
time
-
eval
-
evalsha
-
script
-
debug
-
dump
-
restore
-
migrate
-
getLastError
-
clearLastError
-
_prefix
-
_serialize
-
_unserialize
-
client
-
scan
-
hscan
-
zscan
-
sscan
-
pfadd
-
pfcount
-
pfmerge
-
getOption
-
setOption
-
config
-
slowlog
-
rawCommand
-
getHost
-
getPort
-
getDBNum
-
getTimeout
-
getReadTimeout
-
getPersistentID
-
getAuth
-
isConnected
-
getMode
-
wait
-
pubsub
-
open
-
popen
-
lLen
-
sGetMembers
-
mget
-
expire
-
zunionstore
-
zinterstore
-
zRemove
-
zRem
-
zRemoveRangeByScore
-
zRemRangeByScore
-
zRemRangeByRank
-
zSize
-
substr
-
rename
-
del
-
keys
-
lrem
-
ltrim
-
lindex
-
lrange
-
scard
-
srem
-
sismember
-
zrevrange
-
sendEcho
-
evaluate
-
evaluateSha
进一步当我们想要知道具体一个方法怎么使用,有哪些参数时,我们可以对这个方法进行进一步的反射,以上例中的bitpos方法为例(文档中并没有介绍该方法的使用)
-
echo '---------------------params-----------------------' . PHP_EOL . PHP_EOL;
-
$reflectMethod = $ref->getMethod( 'bitpos'); //传入方法名即可
-
echo $reflectMethod; // 会调用$reflectMethod->__toString() 返回可打印的形式;
打印结果:
-
---------------------params-----------------------
-
-
Method [ <internal:redis> public method bitpos ] {
-
}
并没有看到需要参数,可能与该方法的具体实现有关,具体原因只能去看redis扩展的代码实现,正常情况下应该是返回如下的形式,以mysqli的select_db方法为例:
-
$ref = new ReflectionClass('mysqli');
-
echo '---------------------params-----------------------' . PHP_EOL . PHP_EOL;
-
$reflectMethod = $ref->getMethod( 'select_db'); //传入方法名即可
-
echo $reflectMethod; // 会调用$reflectMethod->__toString() 返回可打印的形式;
-
---------------------params-----------------------
-
-
Method [ <internal:mysqli> public method select_db ] {
-
-
- Parameters [ 1] {
-
Parameter #0 [ <required> $database ]
-
}
-
}
这时就没办法了 我们只能靠对redis的理解以及参考相似方法来使用了,比如bitop
public function bitOp( $operation, $retKey, ...$keys) {}
贴下最终的方法调用
-
$redis = new Redis();
-
$redis->connect( '127.0.0.1');
-
-
$redis->setBit( 'bit', 15, 1);
-
echo 'bitpos: ' . $redis->bitpos('bit', 1) . PHP_EOL; //bitpos: 15
-
$redis->close();
是不是很有趣呢!