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