PHP code example of lzpeng / hyperf-cycle
1. Go to this page and download the library: Download lzpeng/hyperf-cycle library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
lzpeng / hyperf-cycle example snippets
declare(strict_types=1);
use Cycle\Database\Config\MySQL\TcpConnectionConfig;
use Lzpeng\HyperfCycle\Config\MySQLDriverConfig;
use function Hyperf\Support\env;
return [
'default' => 'default',
'databases' => [
'default' => ['connection' => 'default'],
],
'connections' => [
'default' => new MySQLDriverConfig(
connection: new TcpConnectionConfig(
database: env('DB_DATABASE', 'test'),
host: env('DB_HOST', 'localhost'),
port: env('DB_PORT', 3306),
user: env('DB_USER', 'test'),
password: env('DB_PASSWORD', ''),
charset: env('DB_CHARSET', 'utf8mb4'),
),
reconnect: true,
queryCache: true,
options: [],
poolOptions: [
'min_connections' => env('DB_MIN_CONNECTIONS', 1),
'max_connections' => env('DB_MAX_CONNECTIONS', 10),
'connect_timeout' => env('DB_CONNECT_TIMEOUT', 10.0),
'wait_timeout' => env('DB_WAIT_TIMEOUT', 3.0),
'heartbeat' => env('DB_HEARTBEAT', -1),
'max_idle_time' => env('DB_MAX_IDLE_TIME', 60.0),
],
),
],
];
use Lzpeng\HyperfCycle\ORMFactory;
$ormFactory = $container->get(ORMFactory::class);
$orm = $ormFactory->orm();
$em = $ormFactory->entityManager();
use Cycle\Database\Config\MySQL\TcpConnectionConfig;
use Cycle\ORM\Entity\Behavior\EventDrivenCommandGenerator;
use Cycle\ORM\Schema;
use Lzpeng\HyperfCycle\Config\DatabaseConfig;
use Lzpeng\HyperfCycle\Config\MySQLDriverConfig;
use Lzpeng\HyperfCycle\DatabaseManager;
use Lzpeng\HyperfCycle\ORMFactory;
$databaseManager = new DatabaseManager(
new DatabaseConfig([
'default' => 'default',
'databases' => [
'default' => ['connection' => 'mysql'],
],
'connections' => [
'mysql' => new MySQLDriverConfig(
connection: new TcpConnectionConfig(
database: 'spiral',
host: '127.0.0.1',
port: 3306,
user: 'spiral',
password: '',
),
queryCache: true,
poolOptions: [
'min_connections' => 1,
'max_connections' => 20,
'connect_timeout' => 10.0,
'wait_timeout' => 3.0,
'heartbeat' => -1,
'max_idle_time' => 60.0,
],
),
],
])
);
$container = /** 获取容器 */;
$schemaConfig = /** Cycle Schema 配置 */;
$schema = new Schema($schemaConfig);
$commandGenerator = new EventDrivenCommandGenerator($schema, $container);
$ormFactory = new ORMFactory(
databaseManager: $databaseManager,
schema: $schema,
commandGenerator: $commandGenerator,
);
$orm = $ormFactory->orm();
$em = $ormFactory->entityManager();
use Cycle\Database\DatabaseInterface;
use Lzpeng\HyperfCycle\DatabaseManager;
/**
* 产品数量管理器.
*/
class QuantityManager implements QuantityManagerInterface
{
private DatabaseInterface $database;
public function __construct(private DatabaseManager $databaseManager)
{
// 错误:作为属性持久化数据库连接会导致连接泄露问题或事务问题
$this->database = $this->databaseManager->database();
}
public function decrease(Id $productId, Id $skuId, Quantity $quantity): void
{
$affected = $this->database->execute(
'UPDATE `shop_product_sku` SET `quantity` = `quantity` - ? WHERE `id` = ? AND `product_id` = ? AND `quantity` > 0',
[
$quantity->toInt(),
$skuId,
$productId,
]
);
if ($affected === 0) {
throw DomainException::from('库存不足,无法减少库存量', [
'id' => $productId,
]);
}
}
// ...
}
/**
* 下单.
*/
class PlaceOrderCommand
{
public function __construct(
private SkuRepositoryInterface $skuRepository,
private UserRepositoryInterface $userRepository,
private OrderRepositoryInterface $orderRepository,
private OrderFactory $orderFactory,
private QuantityManagerInterface $quantityManager,
private TransactionInterface $transaction,
) {
}
public function execute(
Id $userId,
int $productId,
int $skuId,
int $quantity,
array $fulfillmentData,
): array {
// ...
$order = $this->orderFactory->create($user, $product, $sku, $quantity);
$this->transaction->execute(function () use ($order, $user) {
$this->orderRepository->save($order);
// 由于QuantityManager将数据库连接作为属性, 使用的不是与orderRepository同一个连接, 导致事务失效
$this->quantityManager->decrease($order->productId(), $order->skuId(), $order->quantity());
});
// ...
}
}
use Lzpeng\HyperfCycle\DatabaseManager;
/**
* 产品数量管理器.
*/
class QuantityManager implements QuantityManagerInterface
{
public function __construct(private DatabaseManager $databaseManager)
{
}
public function decrease(Id $productId, Id $skuId, Quantity $quantity): void
{
// 使用时才获取数据库连接,确保连接能够正确回收;
// 同一协程内的连接实例是同一个,事务能够正常工作
$affected = $this->databaseManager->database()->execute(
'UPDATE `shop_product_sku` SET `quantity` = `quantity` - ? WHERE `id` = ? AND `product_id` = ? AND `quantity` > 0',
[
$quantity->toInt(),
$skuId,
$productId,
]
);
if ($affected === 0) {
throw DomainException::from('库存不足,无法减少库存量', [
'id' => $productId,
]);
}
}
// ...
}
bash
php bin/hyperf.php vendor:publish lzpeng/hyperf-cycle