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