RedisCaster.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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. * @final
  18. */
  19. class RedisCaster
  20. {
  21. private const SERIALIZERS = [
  22. \Redis::SERIALIZER_NONE => 'NONE',
  23. \Redis::SERIALIZER_PHP => 'PHP',
  24. 2 => 'IGBINARY', // Optional Redis::SERIALIZER_IGBINARY
  25. ];
  26. private const MODES = [
  27. \Redis::ATOMIC => 'ATOMIC',
  28. \Redis::MULTI => 'MULTI',
  29. \Redis::PIPELINE => 'PIPELINE',
  30. ];
  31. private const COMPRESSION_MODES = [
  32. 0 => 'NONE', // Redis::COMPRESSION_NONE
  33. 1 => 'LZF', // Redis::COMPRESSION_LZF
  34. ];
  35. private const FAILOVER_OPTIONS = [
  36. \RedisCluster::FAILOVER_NONE => 'NONE',
  37. \RedisCluster::FAILOVER_ERROR => 'ERROR',
  38. \RedisCluster::FAILOVER_DISTRIBUTE => 'DISTRIBUTE',
  39. \RedisCluster::FAILOVER_DISTRIBUTE_SLAVES => 'DISTRIBUTE_SLAVES',
  40. ];
  41. public static function castRedis(\Redis $c, array $a, Stub $stub, bool $isNested)
  42. {
  43. $prefix = Caster::PREFIX_VIRTUAL;
  44. if (!$connected = $c->isConnected()) {
  45. return $a + [
  46. $prefix.'isConnected' => $connected,
  47. ];
  48. }
  49. $mode = $c->getMode();
  50. return $a + [
  51. $prefix.'isConnected' => $connected,
  52. $prefix.'host' => $c->getHost(),
  53. $prefix.'port' => $c->getPort(),
  54. $prefix.'auth' => $c->getAuth(),
  55. $prefix.'mode' => isset(self::MODES[$mode]) ? new ConstStub(self::MODES[$mode], $mode) : $mode,
  56. $prefix.'dbNum' => $c->getDbNum(),
  57. $prefix.'timeout' => $c->getTimeout(),
  58. $prefix.'lastError' => $c->getLastError(),
  59. $prefix.'persistentId' => $c->getPersistentID(),
  60. $prefix.'options' => self::getRedisOptions($c),
  61. ];
  62. }
  63. public static function castRedisArray(\RedisArray $c, array $a, Stub $stub, bool $isNested)
  64. {
  65. $prefix = Caster::PREFIX_VIRTUAL;
  66. return $a + [
  67. $prefix.'hosts' => $c->_hosts(),
  68. $prefix.'function' => ClassStub::wrapCallable($c->_function()),
  69. $prefix.'lastError' => $c->getLastError(),
  70. $prefix.'options' => self::getRedisOptions($c),
  71. ];
  72. }
  73. public static function castRedisCluster(\RedisCluster $c, array $a, Stub $stub, bool $isNested)
  74. {
  75. $prefix = Caster::PREFIX_VIRTUAL;
  76. $failover = $c->getOption(\RedisCluster::OPT_SLAVE_FAILOVER);
  77. $a += [
  78. $prefix.'_masters' => $c->_masters(),
  79. $prefix.'_redir' => $c->_redir(),
  80. $prefix.'mode' => new ConstStub($c->getMode() ? 'MULTI' : 'ATOMIC', $c->getMode()),
  81. $prefix.'lastError' => $c->getLastError(),
  82. $prefix.'options' => self::getRedisOptions($c, [
  83. 'SLAVE_FAILOVER' => isset(self::FAILOVER_OPTIONS[$failover]) ? new ConstStub(self::FAILOVER_OPTIONS[$failover], $failover) : $failover,
  84. ]),
  85. ];
  86. return $a;
  87. }
  88. /**
  89. * @param \Redis|\RedisArray|\RedisCluster $redis
  90. */
  91. private static function getRedisOptions($redis, array $options = []): EnumStub
  92. {
  93. $serializer = $redis->getOption(\Redis::OPT_SERIALIZER);
  94. if (\is_array($serializer)) {
  95. foreach ($serializer as &$v) {
  96. if (isset(self::SERIALIZERS[$v])) {
  97. $v = new ConstStub(self::SERIALIZERS[$v], $v);
  98. }
  99. }
  100. } elseif (isset(self::SERIALIZERS[$serializer])) {
  101. $serializer = new ConstStub(self::SERIALIZERS[$serializer], $serializer);
  102. }
  103. $compression = \defined('Redis::OPT_COMPRESSION') ? $redis->getOption(\Redis::OPT_COMPRESSION) : 0;
  104. if (\is_array($compression)) {
  105. foreach ($compression as &$v) {
  106. if (isset(self::COMPRESSION_MODES[$v])) {
  107. $v = new ConstStub(self::COMPRESSION_MODES[$v], $v);
  108. }
  109. }
  110. } elseif (isset(self::COMPRESSION_MODES[$compression])) {
  111. $compression = new ConstStub(self::COMPRESSION_MODES[$compression], $compression);
  112. }
  113. $retry = \defined('Redis::OPT_SCAN') ? $redis->getOption(\Redis::OPT_SCAN) : 0;
  114. if (\is_array($retry)) {
  115. foreach ($retry as &$v) {
  116. $v = new ConstStub($v ? 'RETRY' : 'NORETRY', $v);
  117. }
  118. } else {
  119. $retry = new ConstStub($retry ? 'RETRY' : 'NORETRY', $retry);
  120. }
  121. $options += [
  122. 'TCP_KEEPALIVE' => \defined('Redis::OPT_TCP_KEEPALIVE') ? $redis->getOption(\Redis::OPT_TCP_KEEPALIVE) : 0,
  123. 'READ_TIMEOUT' => $redis->getOption(\Redis::OPT_READ_TIMEOUT),
  124. 'COMPRESSION' => $compression,
  125. 'SERIALIZER' => $serializer,
  126. 'PREFIX' => $redis->getOption(\Redis::OPT_PREFIX),
  127. 'SCAN' => $retry,
  128. ];
  129. return new EnumStub($options);
  130. }
  131. }