RedisCaster.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\VarDumper\Caster;
  11. use Symfony\Component\VarDumper\Cloner\Stub;
  12. /**
  13. * Casts Redis class from ext-redis to array representation.
  14. *
  15. * @author Nicolas Grekas <p@tchwork.com>
  16. */
  17. class RedisCaster
  18. {
  19. private static $serializer = [
  20. \Redis::SERIALIZER_NONE => 'NONE',
  21. \Redis::SERIALIZER_PHP => 'PHP',
  22. 2 => 'IGBINARY', // Optional Redis::SERIALIZER_IGBINARY
  23. ];
  24. private static $mode = [
  25. \Redis::ATOMIC => 'ATOMIC',
  26. \Redis::MULTI => 'MULTI',
  27. \Redis::PIPELINE => 'PIPELINE',
  28. ];
  29. private static $compression = [
  30. 0 => 'NONE', // Redis::COMPRESSION_NONE
  31. 1 => 'LZF', // Redis::COMPRESSION_LZF
  32. ];
  33. private static $failover = [
  34. \RedisCluster::FAILOVER_NONE => 'NONE',
  35. \RedisCluster::FAILOVER_ERROR => 'ERROR',
  36. \RedisCluster::FAILOVER_DISTRIBUTE => 'DISTRIBUTE',
  37. \RedisCluster::FAILOVER_DISTRIBUTE_SLAVES => 'DISTRIBUTE_SLAVES',
  38. ];
  39. public static function castRedis(\Redis $c, array $a, Stub $stub, $isNested)
  40. {
  41. $prefix = Caster::PREFIX_VIRTUAL;
  42. if (!$connected = $c->isConnected()) {
  43. return $a + [
  44. $prefix.'isConnected' => $connected,
  45. ];
  46. }
  47. $mode = $c->getMode();
  48. return $a + [
  49. $prefix.'isConnected' => $connected,
  50. $prefix.'host' => $c->getHost(),
  51. $prefix.'port' => $c->getPort(),
  52. $prefix.'auth' => $c->getAuth(),
  53. $prefix.'mode' => isset(self::$mode[$mode]) ? new ConstStub(self::$mode[$mode], $mode) : $mode,
  54. $prefix.'dbNum' => $c->getDbNum(),
  55. $prefix.'timeout' => $c->getTimeout(),
  56. $prefix.'lastError' => $c->getLastError(),
  57. $prefix.'persistentId' => $c->getPersistentID(),
  58. $prefix.'options' => self::getRedisOptions($c),
  59. ];
  60. }
  61. public static function castRedisArray(\RedisArray $c, array $a, Stub $stub, $isNested)
  62. {
  63. $prefix = Caster::PREFIX_VIRTUAL;
  64. return $a + [
  65. $prefix.'hosts' => $c->_hosts(),
  66. $prefix.'function' => ClassStub::wrapCallable($c->_function()),
  67. $prefix.'lastError' => $c->getLastError(),
  68. $prefix.'options' => self::getRedisOptions($c),
  69. ];
  70. }
  71. public static function castRedisCluster(\RedisCluster $c, array $a, Stub $stub, $isNested)
  72. {
  73. $prefix = Caster::PREFIX_VIRTUAL;
  74. $failover = $c->getOption(\RedisCluster::OPT_SLAVE_FAILOVER);
  75. $a += [
  76. $prefix.'_masters' => $c->_masters(),
  77. $prefix.'_redir' => $c->_redir(),
  78. $prefix.'mode' => new ConstStub($c->getMode() ? 'MULTI' : 'ATOMIC', $c->getMode()),
  79. $prefix.'lastError' => $c->getLastError(),
  80. $prefix.'options' => self::getRedisOptions($c, [
  81. 'SLAVE_FAILOVER' => isset(self::$failover[$failover]) ? new ConstStub(self::$failover[$failover], $failover) : $failover,
  82. ]),
  83. ];
  84. return $a;
  85. }
  86. /**
  87. * @param \Redis|\RedisArray|\RedisCluster $redis
  88. */
  89. private static function getRedisOptions($redis, array $options = []): EnumStub
  90. {
  91. $serializer = $redis->getOption(\Redis::OPT_SERIALIZER);
  92. if (\is_array($serializer)) {
  93. foreach ($serializer as &$v) {
  94. if (isset(self::$serializer[$v])) {
  95. $v = new ConstStub(self::$serializer[$v], $v);
  96. }
  97. }
  98. } elseif (isset(self::$serializer[$serializer])) {
  99. $serializer = new ConstStub(self::$serializer[$serializer], $serializer);
  100. }
  101. $compression = \defined('Redis::OPT_COMPRESSION') ? $redis->getOption(\Redis::OPT_COMPRESSION) : 0;
  102. if (\is_array($compression)) {
  103. foreach ($compression as &$v) {
  104. if (isset(self::$compression[$v])) {
  105. $v = new ConstStub(self::$compression[$v], $v);
  106. }
  107. }
  108. } elseif (isset(self::$compression[$compression])) {
  109. $compression = new ConstStub(self::$compression[$compression], $compression);
  110. }
  111. $retry = \defined('Redis::OPT_SCAN') ? $redis->getOption(\Redis::OPT_SCAN) : 0;
  112. if (\is_array($retry)) {
  113. foreach ($retry as &$v) {
  114. $v = new ConstStub($v ? 'RETRY' : 'NORETRY', $v);
  115. }
  116. } else {
  117. $retry = new ConstStub($retry ? 'RETRY' : 'NORETRY', $retry);
  118. }
  119. $options += [
  120. 'TCP_KEEPALIVE' => \defined('Redis::OPT_TCP_KEEPALIVE') ? $redis->getOption(\Redis::OPT_TCP_KEEPALIVE) : 0,
  121. 'READ_TIMEOUT' => $redis->getOption(\Redis::OPT_READ_TIMEOUT),
  122. 'COMPRESSION' => $compression,
  123. 'SERIALIZER' => $serializer,
  124. 'PREFIX' => $redis->getOption(\Redis::OPT_PREFIX),
  125. 'SCAN' => $retry,
  126. ];
  127. return new EnumStub($options);
  128. }
  129. }