├── README.md ├── config └── database.php └── vendor └── laravel └── framework └── src └── Illuminate └── Database ├── Connectors ├── ConnectionFactory.php └── MySqlSwooleProxyConnector.php └── MySqlSwooleProxyConnection.php /README.md: -------------------------------------------------------------------------------- 1 | # laravel-swoole-cp 2 | swoole connection pool for laravel 3 | 4 | [php-cp](https://github.com/swoole/php-cp)的Laravel驱动 5 | 6 | **注意** 7 | 1. 仅在Laravel5.4~5.5上测试通过,其他版本可能不适用; 8 | 2. PHP7环境请使用[breeze2/php-cp](https://github.com/breeze2/php-cp),目前[swoole/php-cp](https://github.com/swoole/php-cp)v1.5.0版本对PHP7存在问题。 9 | 10 | 主要是三个文件: 11 | 1. laravel/framework/src/Illuminate/Database/MySqlSwooleProxyConnection.php 12 | 2. laravel/framework/src/Illuminate/Database/Connectors/MySqlSwooleProxyConnector.php 13 | 3. laravel/framework/src/Illuminate/Database/Connectors/ConnectionFactory.php 14 | 15 | 只要将这三个文件放到Laravel项目的vendor文件夹下便可。 16 | 17 | `MySqlSwooleProxyConnection.php`和`MySqlSwooleProxyConnector.php`是模仿Laravel框架自有的`MySqlConnection.php`和`MySqlConnector.php`新增编写的;而`ConnectionFactory.php`则是在Laravel框架原有的基础上修改的,主要是调用`MySqlSwooleProxyConnection`和`MySqlSwooleProxyConnector`这两个新增类。 18 | 19 | `ConnectionFactory.php`修改的地方: 20 | 21 | ```php 22 | container->bound($key = "db.connector.{$config['driver']}")) { 37 | return $this->container->make($key); 38 | } 39 | 40 | switch ($config['driver']) { 41 | case 'mysql-cp': 42 | return new MySqlSwooleProxyConnector; 43 | case 'mysql': 44 | return new MySqlConnector; 45 | case 'pgsql': 46 | return new PostgresConnector; 47 | case 'sqlite': 48 | return new SQLiteConnector; 49 | case 'sqlsrv': 50 | return new SqlServerConnector; 51 | } 52 | 53 | throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]"); 54 | } 55 | 56 | protected function createConnection($driver, $connection, $database, $prefix = '', array $config = []) 57 | { 58 | if ($resolver = Connection::getResolver($driver)) { 59 | return $resolver($connection, $database, $prefix, $config); 60 | } 61 | 62 | switch ($driver) { 63 | case 'mysql-cp': 64 | return new MySqlSwooleProxyConnection($connection, $database, $prefix, $config); 65 | case 'mysql': 66 | return new MySqlConnection($connection, $database, $prefix, $config); 67 | case 'pgsql': 68 | return new PostgresConnection($connection, $database, $prefix, $config); 69 | case 'sqlite': 70 | return new SQLiteConnection($connection, $database, $prefix, $config); 71 | case 'sqlsrv': 72 | return new SqlServerConnection($connection, $database, $prefix, $config); 73 | } 74 | 75 | throw new InvalidArgumentException("Unsupported driver [$driver]"); 76 | } 77 | } 78 | ``` 79 | 80 | 注意,这里将php-cp的数据库连接驱动命名为`mysql-cp`,所以在Laravel项目的数据库配置`config/database.php`里应该这样配置php-cp的连接驱动: 81 | 82 | ```php 83 | env('DB_CONNECTION', 'mysql-cp'), 88 | 89 | 'connections' => [ 90 | 91 | 'mysql-cp' => [ 92 | 'driver' => 'mysql-cp', 93 | 'host' => env('DB_HOST', '127.0.0.1'), 94 | 'port' => env('DB_PORT', '3306'), 95 | 'database' => env('DB_DATABASE', 'forge'), 96 | 'username' => env('DB_USERNAME', 'forge'), 97 | 'password' => env('DB_PASSWORD', ''), 98 | 'unix_socket' => env('DB_SOCKET', ''), 99 | 'charset' => 'utf8mb4', 100 | 'collation' => 'utf8mb4_unicode_ci', 101 | 'prefix' => '', 102 | 'strict' => true, 103 | 'engine' => null, 104 | ], 105 | ... 106 | ], 107 | ] 108 | 109 | ``` 110 | 111 | 112 | -------------------------------------------------------------------------------- /config/database.php: -------------------------------------------------------------------------------- 1 | env('DB_CONNECTION', 'mysql-cp'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Database Connections 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here are each of the database connections setup for your application. 24 | | Of course, examples of configuring each database platform that is 25 | | supported by Laravel is shown below to make development simple. 26 | | 27 | | 28 | | All database work in Laravel is done through the PHP PDO facilities 29 | | so make sure you have the driver for your particular database of 30 | | choice installed on your machine before you begin development. 31 | | 32 | */ 33 | 34 | 'connections' => [ 35 | 36 | 'sqlite' => [ 37 | 'driver' => 'sqlite', 38 | 'database' => env('DB_DATABASE', database_path('database.sqlite')), 39 | 'prefix' => '', 40 | ], 41 | 42 | 'mysql-cp' => [ 43 | 'driver' => 'mysql-cp', 44 | 'host' => env('DB_HOST', '127.0.0.1'), 45 | 'port' => env('DB_PORT', '3306'), 46 | 'database' => env('DB_DATABASE', 'forge'), 47 | 'username' => env('DB_USERNAME', 'forge'), 48 | 'password' => env('DB_PASSWORD', ''), 49 | 'unix_socket' => env('DB_SOCKET', ''), 50 | 'charset' => 'utf8mb4', 51 | 'collation' => 'utf8mb4_unicode_ci', 52 | 'prefix' => '', 53 | 'strict' => true, 54 | 'engine' => null, 55 | ], 56 | 57 | 'mysql' => [ 58 | 'driver' => 'mysql', 59 | 'host' => env('DB_HOST', '127.0.0.1'), 60 | 'port' => env('DB_PORT', '3306'), 61 | 'database' => env('DB_DATABASE', 'forge'), 62 | 'username' => env('DB_USERNAME', 'forge'), 63 | 'password' => env('DB_PASSWORD', ''), 64 | 'unix_socket' => env('DB_SOCKET', ''), 65 | 'charset' => 'utf8mb4', 66 | 'collation' => 'utf8mb4_unicode_ci', 67 | 'prefix' => '', 68 | 'strict' => true, 69 | 'engine' => null, 70 | ], 71 | 72 | 'pgsql' => [ 73 | 'driver' => 'pgsql', 74 | 'host' => env('DB_HOST', '127.0.0.1'), 75 | 'port' => env('DB_PORT', '5432'), 76 | 'database' => env('DB_DATABASE', 'forge'), 77 | 'username' => env('DB_USERNAME', 'forge'), 78 | 'password' => env('DB_PASSWORD', ''), 79 | 'charset' => 'utf8', 80 | 'prefix' => '', 81 | 'schema' => 'public', 82 | 'sslmode' => 'prefer', 83 | ], 84 | 85 | 'sqlsrv' => [ 86 | 'driver' => 'sqlsrv', 87 | 'host' => env('DB_HOST', 'localhost'), 88 | 'port' => env('DB_PORT', '1433'), 89 | 'database' => env('DB_DATABASE', 'forge'), 90 | 'username' => env('DB_USERNAME', 'forge'), 91 | 'password' => env('DB_PASSWORD', ''), 92 | 'charset' => 'utf8', 93 | 'prefix' => '', 94 | ], 95 | 96 | ], 97 | 98 | /* 99 | |-------------------------------------------------------------------------- 100 | | Migration Repository Table 101 | |-------------------------------------------------------------------------- 102 | | 103 | | This table keeps track of all the migrations that have already run for 104 | | your application. Using this information, we can determine which of 105 | | the migrations on disk haven't actually been run in the database. 106 | | 107 | */ 108 | 109 | 'migrations' => 'migrations', 110 | 111 | /* 112 | |-------------------------------------------------------------------------- 113 | | Redis Databases 114 | |-------------------------------------------------------------------------- 115 | | 116 | | Redis is an open source, fast, and advanced key-value store that also 117 | | provides a richer set of commands than a typical key-value systems 118 | | such as APC or Memcached. Laravel makes it easy to dig right in. 119 | | 120 | */ 121 | 122 | 'redis' => [ 123 | 124 | 'client' => 'predis', 125 | 126 | 'default' => [ 127 | 'host' => env('REDIS_HOST', '127.0.0.1'), 128 | 'password' => env('REDIS_PASSWORD', null), 129 | 'port' => env('REDIS_PORT', 6379), 130 | 'database' => 0, 131 | ], 132 | 133 | ], 134 | 135 | ]; 136 | -------------------------------------------------------------------------------- /vendor/laravel/framework/src/Illuminate/Database/Connectors/ConnectionFactory.php: -------------------------------------------------------------------------------- 1 | container = $container; 35 | } 36 | 37 | /** 38 | * Establish a PDO connection based on the configuration. 39 | * 40 | * @param array $config 41 | * @param string $name 42 | * @return \Illuminate\Database\Connection 43 | */ 44 | public function make(array $config, $name = null) 45 | { 46 | $config = $this->parseConfig($config, $name); 47 | 48 | if (isset($config['read'])) { 49 | return $this->createReadWriteConnection($config); 50 | } 51 | 52 | return $this->createSingleConnection($config); 53 | } 54 | 55 | /** 56 | * Parse and prepare the database configuration. 57 | * 58 | * @param array $config 59 | * @param string $name 60 | * @return array 61 | */ 62 | protected function parseConfig(array $config, $name) 63 | { 64 | return Arr::add(Arr::add($config, 'prefix', ''), 'name', $name); 65 | } 66 | 67 | /** 68 | * Create a single database connection instance. 69 | * 70 | * @param array $config 71 | * @return \Illuminate\Database\Connection 72 | */ 73 | protected function createSingleConnection(array $config) 74 | { 75 | $pdo = $this->createPdoResolver($config); 76 | 77 | return $this->createConnection( 78 | $config['driver'], $pdo, $config['database'], $config['prefix'], $config 79 | ); 80 | } 81 | 82 | /** 83 | * Create a single database connection instance. 84 | * 85 | * @param array $config 86 | * @return \Illuminate\Database\Connection 87 | */ 88 | protected function createReadWriteConnection(array $config) 89 | { 90 | $connection = $this->createSingleConnection($this->getWriteConfig($config)); 91 | 92 | return $connection->setReadPdo($this->createReadPdo($config)); 93 | } 94 | 95 | /** 96 | * Create a new PDO instance for reading. 97 | * 98 | * @param array $config 99 | * @return \Closure 100 | */ 101 | protected function createReadPdo(array $config) 102 | { 103 | return $this->createPdoResolver($this->getReadConfig($config)); 104 | } 105 | 106 | /** 107 | * Get the read configuration for a read / write connection. 108 | * 109 | * @param array $config 110 | * @return array 111 | */ 112 | protected function getReadConfig(array $config) 113 | { 114 | return $this->mergeReadWriteConfig( 115 | $config, $this->getReadWriteConfig($config, 'read') 116 | ); 117 | } 118 | 119 | /** 120 | * Get the read configuration for a read / write connection. 121 | * 122 | * @param array $config 123 | * @return array 124 | */ 125 | protected function getWriteConfig(array $config) 126 | { 127 | return $this->mergeReadWriteConfig( 128 | $config, $this->getReadWriteConfig($config, 'write') 129 | ); 130 | } 131 | 132 | /** 133 | * Get a read / write level configuration. 134 | * 135 | * @param array $config 136 | * @param string $type 137 | * @return array 138 | */ 139 | protected function getReadWriteConfig(array $config, $type) 140 | { 141 | return isset($config[$type][0]) 142 | ? Arr::random($config[$type]) 143 | : $config[$type]; 144 | } 145 | 146 | /** 147 | * Merge a configuration for a read / write connection. 148 | * 149 | * @param array $config 150 | * @param array $merge 151 | * @return array 152 | */ 153 | protected function mergeReadWriteConfig(array $config, array $merge) 154 | { 155 | return Arr::except(array_merge($config, $merge), ['read', 'write']); 156 | } 157 | 158 | /** 159 | * Create a new Closure that resolves to a PDO instance. 160 | * 161 | * @param array $config 162 | * @return \Closure 163 | */ 164 | protected function createPdoResolver(array $config) 165 | { 166 | return array_key_exists('host', $config) 167 | ? $this->createPdoResolverWithHosts($config) 168 | : $this->createPdoResolverWithoutHosts($config); 169 | } 170 | 171 | /** 172 | * Create a new Closure that resolves to a PDO instance with a specific host or an array of hosts. 173 | * 174 | * @param array $config 175 | * @return \Closure 176 | */ 177 | protected function createPdoResolverWithHosts(array $config) 178 | { 179 | return function () use ($config) { 180 | foreach (Arr::shuffle($hosts = $this->parseHosts($config)) as $key => $host) { 181 | $config['host'] = $host; 182 | 183 | try { 184 | return $this->createConnector($config)->connect($config); 185 | } catch (PDOException $e) { 186 | if (count($hosts) - 1 === $key && $this->container->bound(ExceptionHandler::class)) { 187 | $this->container->make(ExceptionHandler::class)->report($e); 188 | } 189 | } 190 | } 191 | 192 | throw $e; 193 | }; 194 | } 195 | 196 | /** 197 | * Parse the hosts configuration item into an array. 198 | * 199 | * @param array $config 200 | * @return array 201 | */ 202 | protected function parseHosts(array $config) 203 | { 204 | $hosts = array_wrap($config['host']); 205 | 206 | if (empty($hosts)) { 207 | throw new InvalidArgumentException('Database hosts array is empty.'); 208 | } 209 | 210 | return $hosts; 211 | } 212 | 213 | /** 214 | * Create a new Closure that resolves to a PDO instance where there is no configured host. 215 | * 216 | * @param array $config 217 | * @return \Closure 218 | */ 219 | protected function createPdoResolverWithoutHosts(array $config) 220 | { 221 | return function () use ($config) { 222 | return $this->createConnector($config)->connect($config); 223 | }; 224 | } 225 | 226 | /** 227 | * Create a connector instance based on the configuration. 228 | * 229 | * @param array $config 230 | * @return \Illuminate\Database\Connectors\ConnectorInterface 231 | * 232 | * @throws \InvalidArgumentException 233 | */ 234 | public function createConnector(array $config) 235 | { 236 | if (! isset($config['driver'])) { 237 | throw new InvalidArgumentException('A driver must be specified.'); 238 | } 239 | 240 | if ($this->container->bound($key = "db.connector.{$config['driver']}")) { 241 | return $this->container->make($key); 242 | } 243 | 244 | switch ($config['driver']) { 245 | case 'mysql-cp': 246 | return new MySqlSwooleProxyConnector; 247 | case 'mysql': 248 | return new MySqlConnector; 249 | case 'pgsql': 250 | return new PostgresConnector; 251 | case 'sqlite': 252 | return new SQLiteConnector; 253 | case 'sqlsrv': 254 | return new SqlServerConnector; 255 | } 256 | 257 | throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]"); 258 | } 259 | 260 | /** 261 | * Create a new connection instance. 262 | * 263 | * @param string $driver 264 | * @param \PDO|\Closure $connection 265 | * @param string $database 266 | * @param string $prefix 267 | * @param array $config 268 | * @return \Illuminate\Database\Connection 269 | * 270 | * @throws \InvalidArgumentException 271 | */ 272 | protected function createConnection($driver, $connection, $database, $prefix = '', array $config = []) 273 | { 274 | if ($resolver = Connection::getResolver($driver)) { 275 | return $resolver($connection, $database, $prefix, $config); 276 | } 277 | 278 | switch ($driver) { 279 | case 'mysql-cp': 280 | return new MySqlSwooleProxyConnection($connection, $database, $prefix, $config); 281 | case 'mysql': 282 | return new MySqlConnection($connection, $database, $prefix, $config); 283 | case 'pgsql': 284 | return new PostgresConnection($connection, $database, $prefix, $config); 285 | case 'sqlite': 286 | return new SQLiteConnection($connection, $database, $prefix, $config); 287 | case 'sqlsrv': 288 | return new SqlServerConnection($connection, $database, $prefix, $config); 289 | } 290 | 291 | throw new InvalidArgumentException("Unsupported driver [$driver]"); 292 | } 293 | } 294 | -------------------------------------------------------------------------------- /vendor/laravel/framework/src/Illuminate/Database/Connectors/MySqlSwooleProxyConnector.php: -------------------------------------------------------------------------------- 1 | getDsn($config); 20 | 21 | $options = $this->getOptions($config); 22 | 23 | // We need to grab the pdoProxy options that should be used while making the brand 24 | // new connection instance. The pdoProxy options control various aspects of the 25 | // connection's behavior, and some might be specified by the developers. 26 | $connection = $this->createConnection($dsn, $config, $options); 27 | 28 | if (! empty($config['database'])) { 29 | $connection->exec("use `{$config['database']}`;"); 30 | } 31 | 32 | $this->configureEncoding($connection, $config); 33 | 34 | // Next, we will check to see if a timezone has been specified in this config 35 | // and if it has we will issue a statement to modify the timezone with the 36 | // database. Setting this DB timezone is an optional configuration item. 37 | $this->configureTimezone($connection, $config); 38 | 39 | $this->setModes($connection, $config); 40 | 41 | return $connection; 42 | } 43 | 44 | public function createConnection($dsn, array $config, array $options) 45 | { 46 | list($username, $password) = [ 47 | Arr::get($config, 'username'), Arr::get($config, 'password'), 48 | ]; 49 | 50 | try { 51 | // return $this->createPdoConnection( 52 | // $dsn, $username, $password, $options 53 | // ); 54 | return new pdoProxy($dsn, $username, $password, $options); 55 | } catch (Exception $e) { 56 | return $this->tryAgainIfCausedByLostConnection( 57 | $e, $dsn, $username, $password, $options 58 | ); 59 | } 60 | } 61 | 62 | /** 63 | * Set the connection character set and collation. 64 | * 65 | * @param \pdoProxy $connection 66 | * @param array $config 67 | * @return void 68 | */ 69 | protected function configureEncoding($connection, array $config) 70 | { 71 | if (! isset($config['charset'])) { 72 | return $connection; 73 | } 74 | 75 | $connection->prepare( 76 | "set names '{$config['charset']}'".$this->getCollation($config) 77 | )->execute(); 78 | } 79 | 80 | /** 81 | * Get the collation for the configuration. 82 | * 83 | * @param array $config 84 | * @return string 85 | */ 86 | protected function getCollation(array $config) 87 | { 88 | return isset($config['collation']) ? " collate '{$config['collation']}'" : ''; 89 | } 90 | 91 | /** 92 | * Set the timezone on the connection. 93 | * 94 | * @param \pdoProxy $connection 95 | * @param array $config 96 | * @return void 97 | */ 98 | protected function configureTimezone($connection, array $config) 99 | { 100 | if (isset($config['timezone'])) { 101 | $connection->prepare('set time_zone="'.$config['timezone'].'"')->execute(); 102 | } 103 | } 104 | 105 | /** 106 | * Create a DSN string from a configuration. 107 | * 108 | * Chooses socket or host/port based on the 'unix_socket' config value. 109 | * 110 | * @param array $config 111 | * @return string 112 | */ 113 | protected function getDsn(array $config) 114 | { 115 | return $this->hasSocket($config) 116 | ? $this->getSocketDsn($config) 117 | : $this->getHostDsn($config); 118 | } 119 | 120 | /** 121 | * Determine if the given configuration array has a UNIX socket value. 122 | * 123 | * @param array $config 124 | * @return bool 125 | */ 126 | protected function hasSocket(array $config) 127 | { 128 | return isset($config['unix_socket']) && ! empty($config['unix_socket']); 129 | } 130 | 131 | /** 132 | * Get the DSN string for a socket configuration. 133 | * 134 | * @param array $config 135 | * @return string 136 | */ 137 | protected function getSocketDsn(array $config) 138 | { 139 | return "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}"; 140 | } 141 | 142 | /** 143 | * Get the DSN string for a host / port configuration. 144 | * 145 | * @param array $config 146 | * @return string 147 | */ 148 | protected function getHostDsn(array $config) 149 | { 150 | extract($config, EXTR_SKIP); 151 | 152 | return isset($port) 153 | ? "mysql:host={$host};port={$port};dbname={$database}" 154 | : "mysql:host={$host};dbname={$database}"; 155 | } 156 | 157 | /** 158 | * Set the modes for the connection. 159 | * 160 | * @param \pdoProxy $connection 161 | * @param array $config 162 | * @return void 163 | */ 164 | protected function setModes(pdoProxy $connection, array $config) 165 | { 166 | if (isset($config['modes'])) { 167 | $this->setCustomModes($connection, $config); 168 | } elseif (isset($config['strict'])) { 169 | if ($config['strict']) { 170 | $connection->prepare($this->strictMode())->execute(); 171 | } else { 172 | $connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute(); 173 | } 174 | } 175 | } 176 | 177 | /** 178 | * Set the custom modes on the connection. 179 | * 180 | * @param \pdoProxy $connection 181 | * @param array $config 182 | * @return void 183 | */ 184 | protected function setCustomModes(pdoProxy $connection, array $config) 185 | { 186 | $modes = implode(',', $config['modes']); 187 | 188 | $connection->prepare("set session sql_mode='{$modes}'")->execute(); 189 | } 190 | 191 | /** 192 | * Get the query to enable strict mode. 193 | * 194 | * @return string 195 | */ 196 | protected function strictMode() 197 | { 198 | return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'"; 199 | } 200 | 201 | } 202 | -------------------------------------------------------------------------------- /vendor/laravel/framework/src/Illuminate/Database/MySqlSwooleProxyConnection.php: -------------------------------------------------------------------------------- 1 | withTablePrefix(new QueryGrammar); 23 | } 24 | 25 | /** 26 | * Get a schema builder instance for the connection. 27 | * 28 | * @return \Illuminate\Database\Schema\MySqlBuilder 29 | */ 30 | public function getSchemaBuilder() 31 | { 32 | if (is_null($this->schemaGrammar)) { 33 | $this->useDefaultSchemaGrammar(); 34 | } 35 | 36 | return new MySqlBuilder($this); 37 | } 38 | 39 | /** 40 | * Get the default schema grammar instance. 41 | * 42 | * @return \Illuminate\Database\Schema\Grammars\MySqlGrammar 43 | */ 44 | protected function getDefaultSchemaGrammar() 45 | { 46 | return $this->withTablePrefix(new SchemaGrammar); 47 | } 48 | 49 | /** 50 | * Get the default post processor instance. 51 | * 52 | * @return \Illuminate\Database\Query\Processors\MySqlProcessor 53 | */ 54 | protected function getDefaultPostProcessor() 55 | { 56 | return new MySqlProcessor; 57 | } 58 | 59 | /** 60 | * Get the Doctrine DBAL driver. 61 | * 62 | * @return \Doctrine\DBAL\Driver\PDOMySql\Driver 63 | */ 64 | protected function getDoctrineDriver() 65 | { 66 | return new DoctrineDriver; 67 | } 68 | 69 | /** 70 | * Bind values to their parameters in the given statement. 71 | * 72 | * @param \PDOStatement $statement 73 | * @param array $bindings 74 | * @return void 75 | */ 76 | public function bindValues($statement, $bindings) 77 | { 78 | foreach ($bindings as $key => $value) { 79 | $statement->bindValue( 80 | is_string($key) ? $key : $key + 1, $value, 81 | is_int($value) || is_float($value) ? PDO::PARAM_INT : PDO::PARAM_STR 82 | ); 83 | } 84 | } 85 | 86 | protected function swooleProxyPrepared(pdo_connect_pool_PDOStatement $statement) 87 | { 88 | $statement->setFetchMode($this->fetchMode); 89 | $this->event(new Events\StatementPrepared( 90 | $this, $statement 91 | )); 92 | 93 | return $statement; 94 | } 95 | 96 | /** 97 | * Run a select statement against the database. 98 | * 99 | * @param string $query 100 | * @param array $bindings 101 | * @param bool $useReadPdo 102 | * @return array 103 | */ 104 | public function select($query, $bindings = [], $useReadPdo = true) 105 | { 106 | return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { 107 | if ($this->pretending()) { 108 | return []; 109 | } 110 | 111 | // For select statements, we'll simply execute the query and return an array 112 | // of the database result set. Each element in the array will be a single 113 | // row from the database table, and will either be an array or objects. 114 | $statement = $this->swooleProxyPrepared($this->getPdoForSelect($useReadPdo) 115 | ->prepare($query)); 116 | 117 | $this->bindValues($statement, $this->prepareBindings($bindings)); 118 | 119 | $statement->execute(); 120 | 121 | return $statement->fetchAll(); 122 | }); 123 | } 124 | 125 | /** 126 | * Run a select statement against the database and returns a generator. 127 | * 128 | * @param string $query 129 | * @param array $bindings 130 | * @param bool $useReadPdo 131 | * @return \Generator 132 | */ 133 | public function cursor($query, $bindings = [], $useReadPdo = true) 134 | { 135 | $statement = $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { 136 | if ($this->pretending()) { 137 | return []; 138 | } 139 | 140 | // First we will create a statement for the query. Then, we will set the fetch 141 | // mode and prepare the bindings for the query. Once that's done we will be 142 | // ready to execute the query against the database and return the cursor. 143 | $statement = $this->swooleProxyPrepared($this->getPdoForSelect($useReadPdo) 144 | ->prepare($query)); 145 | 146 | $this->bindValues( 147 | $statement, $this->prepareBindings($bindings) 148 | ); 149 | 150 | // Next, we'll execute the query against the database and return the statement 151 | // so we can return the cursor. The cursor will use a PHP generator to give 152 | // back one row at a time without using a bunch of memory to render them. 153 | $statement->execute(); 154 | 155 | return $statement; 156 | }); 157 | 158 | while ($record = $statement->fetch()) { 159 | yield $record; 160 | } 161 | } 162 | } 163 | --------------------------------------------------------------------------------