Maison développement back-end tutoriel php Comment empêcher la survente de l'inventaire de produits dans des conditions de concurrence élevée en PHP

Comment empêcher la survente de l'inventaire de produits dans des conditions de concurrence élevée en PHP

Apr 06, 2022 am 10:37 AM
php

Cet article vous apporte des connaissances pertinentes sur PHP, qui introduit principalement des problèmes liés à la prévention des stocks de marchandises survendus dans des conditions de concurrence élevée, résolvant principalement la pression de la concurrence élevée sur la base de données et comment résoudre le problème de la concurrence. d'inventaire de produits survendus, j'espère que cela sera utile à tout le monde.

Comment empêcher la survente de l'inventaire de produits dans des conditions de concurrence élevée en PHP

Vous pouvez consulter les cas de test basés sur cet article via "Test de haute concurrence PHP : étude de cas sur la prévention de la survente des stocks". [Apprentissage recommandé : "Tutoriel PHP"]

Dans le système du centre commercial, les ventes précipitées et les ventes flash sont des scénarios marketing très courants. Au cours d'une certaine période de temps, un grand nombre d'utilisateurs visitent le centre commercial pour y passer des commandes. Il y a deux problèmes principaux qui doivent être résolus :

  • La pression d'une concurrence élevée sur la base de données

  • Comment résoudre l'inventaire survendu de marchandises sous concurrence ; la base de données

Pour la première question, utiliser la mise en cache est utilisée pour éviter d'exploiter directement la base de données, comme en utilisant Redis. Comment résoudre le problème de stock de produits survendu dans une situation concurrentielle

Pour la deuxième question, il faut se concentrer sur l'explication. Méthode d'écriture conventionnelle : interrogez l'inventaire du produit correspondant, déterminez si la quantité d'inventaire est supérieure à 0, puis effectuez des opérations telles que la génération d'une commande. Cependant, lors de la détermination si l'inventaire est supérieur à 0, il y aura des problèmes. dans des conditions de concurrence élevée, ce qui entraîne une quantité de stock négative.

Test table sql

Importez les données de la table suivante dans la base de données

/*
Navicat MySQL Data Transfer

Source Server         : 01 本地localhost
Source Server Version : 50553
Source Host           : localhost:3306
Source Database       : test

Target Server Type    : MYSQL
Target Server Version : 50553
File Encoding         : 65001

Date: 2020-11-06 14:31:35
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for products
-- ----------------------------
DROP TABLE IF EXISTS `products`;
CREATE TABLE `products` (
  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `title` varchar(50) DEFAULT NULL COMMENT '货品名称',
  `store` int(11) DEFAULT '0' COMMENT '货品库存',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='货品表';

-- ----------------------------
-- Records of products
-- ----------------------------
INSERT INTO `products` VALUES ('1', '稻花香大米', '20');

-- ----------------------------
-- Table structure for order_log
-- ----------------------------
DROP TABLE IF EXISTS `order_log`;
CREATE TABLE `order_log` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `content` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '日志内容',
  `c_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

-- ----------------------------
-- Table structure for order
-- ----------------------------
DROP TABLE IF EXISTS `order`;
CREATE TABLE `order` (
  `oid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '订单号',
  `product_id` int(11) DEFAULT '0' COMMENT '商品ID',
  `number` int(11) DEFAULT '0' COMMENT '购买数量',
  `c_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`oid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='订单表';
Copier après la connexion
Code de traitement des commandes

<?php

db();
global $con;

//step1 接收下单参数
$product_id = 1;// 商品ID
$buy_num = 1;// 购买数量

//step2 查询商品信息
$sql = "select * from products where id={$product_id}";
$result = mysqli_query($con, $sql);
$row = mysqli_fetch_assoc($result);

//step3 判断商品下单数量是否大于商品库存数量
//此处在高并发下,可能出现上一个下单后还没来得及更新库存,下一个下单判断库存数不是最新的库存
if ($row[&#39;store&#39;] > 0) {

    sleep(1);
    //step4 更新商品库存数量(减去下单数量)
    $sql = "update products set store=store-{$buy_num} where id={$product_id}";
    if (mysqli_query($con, $sql)) {
        echo "更新成功";
        //step5 生成订单号创建订单
        $oid = build_order_no();
        create_order($oid, $product_id, $buy_num);
        insertLog(&#39;库存减少成功,下单成功&#39;);
    } else {
        echo "更新失败";
        insertLog(&#39;库存减少失败&#39;);
    }

} else {
    echo "没有库存";
    insertLog(&#39;库存不够&#39;);
}

function db()
{
    global $con;
    $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;root&#39;,&#39;test&#39;);
    if (!$con) {
        echo "数据库连接失败";
    }
}

/**
 * 生成唯一订单号
 */
function build_order_no()
{
    return date(&#39;Ymd&#39;) . str_pad(mt_rand(1, 99999), 5, &#39;0&#39;, STR_PAD_LEFT);
}

function create_order($oid, $product_id, $number)
{
    global $con;
    $sql = "INSERT INTO `order` (oid, product_id, number) values(&#39;$oid&#39;, &#39;$product_id&#39;, &#39;$number&#39;)";
    mysqli_query($con, $sql);
}

/**
 * 记录日志
 */
function insertLog($content)
{
    global $con;
    $sql = "INSERT INTO `order_log` (content) values(&#39;$content&#39;)";
    mysqli_query($con, $sql);
}
Copier après la connexion

Définissez le champ du champ d'inventaire sur non signé

Parce que les champs d'inventaire ne peuvent pas être un nombre négatif. Lors de la mise à jour de l'inventaire du produit après avoir passé une commande, si un nombre négatif se produit, false sera renvoyé

<?php
db();
global $con;

//step1 接收下单参数
$product_id = 1;// 商品ID
$buy_num = 1;// 购买数量

//step2 查询商品信息
$sql = "select * from products where id={$product_id} for UPDATE";//利用for update 开启行锁
$result = mysqli_query($con, $sql);
$row = mysqli_fetch_assoc($result);

//step3 判断商品下单数量是否大于商品库存数量
if ($row[&#39;store&#39;] > 0) {

    sleep(1);
    //step4 更新商品库存数量(减去下单数量)
    $sql = "update products set store=store-{$buy_num} where id={$product_id}";
    if (mysqli_query($con, $sql)) {
        echo "更新成功";
        //step5 生成订单号创建订单
        $oid = build_order_no();
        create_order($oid, $product_id, $buy_num);
        insertLog(&#39;库存减少成功,下单成功&#39;);
    } else {
        // 如果出现负数将返回false
        echo "更新失败";
        insertLog(&#39;库存减少失败&#39;);
    }
} else {
    //商品已经抢购完
    echo "没有库存";
    insertLog(&#39;库存不够&#39;);
}

function db()
{
    global $con;
    $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;root&#39;,&#39;test&#39;);
    if (!$con) {
        echo "数据库连接失败";
    }
}

/**
 * 生成唯一订单号
 */
function build_order_no()
{
    return date(&#39;Ymd&#39;) . str_pad(mt_rand(1, 99999), 5, &#39;0&#39;, STR_PAD_LEFT);
}

function create_order($oid, $product_id, $number)
{
    global $con;
    $sql = "INSERT INTO `order` (oid, product_id, number) values(&#39;$oid&#39;, &#39;$product_id&#39;, &#39;$number&#39;)";
    mysqli_query($con, $sql);
}

/**
 * 记录日志
 */
function insertLog($content)
{
    global $con;
    $sql = "INSERT INTO `order_log` (content) values(&#39;$content&#39;)";
    mysqli_query($con, $sql);
}
Copier après la connexion
Utilisez la transaction mysql pour verrouiller la ligne de l'opération

Pendant le processus de traitement de la commande, la transaction en utilisant MySQL, vous passerez la commande Verrouillage des données de la ligne de produits

<?php
db();
global $con;

//step1 接收下单参数
$product_id = 1;// 商品ID
$buy_num = 1;// 购买数量

mysqli_query($con, "BEGIN"); //开始事务

//step2 查询商品信息
$sql = "select * from products where id={$product_id} for UPDATE";//利用for update 开启行锁
$result = mysqli_query($con, $sql);
$row = mysqli_fetch_assoc($result);

//step3 判断商品下单数量是否大于商品库存数量
if ($row[&#39;store&#39;] > 0) {

    sleep(1);
    //step4 更新商品库存数量(减去下单数量)
    $sql = "update products set store=store-{$buy_num} where id={$product_id}";
    if (mysqli_query($con, $sql)) {
        echo "更新成功";
        //step5 生成订单号创建订单
        $oid = build_order_no();
        create_order($oid, $product_id, $buy_num);
        insertLog(&#39;库存减少成功,下单成功&#39;);
        mysqli_query($con, "COMMIT");//事务提交即解锁
    } else {
        echo "更新失败";
        insertLog(&#39;库存减少失败&#39;);
        mysqli_query($con, "ROLLBACK");//事务回滚即解锁
    }
} else {
    //商品已经抢购完
    echo "没有库存";
    insertLog(&#39;库存不够&#39;);
    mysqli_query($con, "ROLLBACK");//事务回滚即解锁
}

function db()
{
    global $con;
    $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;root&#39;,&#39;test&#39;);
    if (!$con) {
        echo "数据库连接失败";
    }
}

/**
 * 生成唯一订单号
 */
function build_order_no()
{
    return date(&#39;Ymd&#39;) . str_pad(mt_rand(1, 99999), 5, &#39;0&#39;, STR_PAD_LEFT);
}

function create_order($oid, $product_id, $number)
{
    global $con;
    $sql = "INSERT INTO `order` (oid, product_id, number) values(&#39;$oid&#39;, &#39;$product_id&#39;, &#39;$number&#39;)";
    mysqli_query($con, $sql);
}

/**
 * 记录日志
 */
function insertLog($content)
{
    global $con;
    $sql = "INSERT INTO `order_log` (content) values(&#39;$content&#39;)";
    mysqli_query($con, $sql);
}
Copier après la connexion
Utiliser le verrouillage exclusif de fichier non bloquant

Lors du traitement d'une demande de commande, utilisez flock pour verrouiller un fichier. Si le verrouillage échoue, cela signifie que d'autres commandes. sont en cours de traitement, vous pouvez soit attendre, soit directement. L'utilisateur est informé que "le serveur est occupé" et le compteur stocke le nombre de produits achetés pour éviter d'interroger la base de données. Mode de blocage (attente) : pendant la simultanéité, lorsqu'il y a une deuxième demande d'utilisateur, le programme attendra que la première demande d'utilisateur se termine, libérera le verrou et obtiendra le verrouillage du fichier avant que le programme continue de s'exécuter.

<?php
db();
global $con;

//step1 接收下单参数
$product_id = 1;// 商品ID
$buy_num = 1;// 购买数量

$fp = fopen(&#39;lock.txt&#39;, &#39;w&#39;);
if (flock($fp, LOCK_EX)) {   //文件独占锁,阻塞
    //step2 查询商品信息
    $sql = "select * from products where id={$product_id}";
    $result = mysqli_query($con, $sql);
    $row = mysqli_fetch_assoc($result);

    //step3 判断商品下单数量是否大于商品库存数量
    if ($row[&#39;store&#39;] > 0) {
        //处理订单
        sleep(1);
        //step4 更新商品库存数量(减去下单数量)
        $sql = "update products set store=store-{$buy_num} where id={$product_id}";
        if (mysqli_query($con, $sql)) {
            echo "更新成功";
            //step5 生成订单号创建订单
            $oid = build_order_no();
            create_order($oid, $product_id, $buy_num);
            insertLog(&#39;库存减少成功,下单成功&#39;);
        } else {
            echo "更新失败";
            insertLog(&#39;库存减少失败&#39;);
        }
    } else {
        //商品已经抢购完
        echo "没有库存";
        insertLog(&#39;库存不够&#39;);
    }
    flock($fp, LOCK_UN); //释放锁

}
fclose($fp);

function db()
{
    global $con;
    $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;root&#39;,&#39;test&#39;);
    if (!$con) {
        echo "数据库连接失败";
    }
}

/**
 * 生成唯一订单号
 */
function build_order_no()
{
    return date(&#39;Ymd&#39;) . str_pad(mt_rand(1, 99999), 5, &#39;0&#39;, STR_PAD_LEFT);
}

function create_order($oid, $product_id, $number)
{
    global $con;
    $sql = "INSERT INTO `order` (oid, product_id, number) values(&#39;$oid&#39;, &#39;$product_id&#39;, &#39;$number&#39;)";
    mysqli_query($con, $sql);
}

/**
 * 记录日志
 */
function insertLog($content)
{
    global $con;
    $sql = "INSERT INTO `order_log` (content) values(&#39;$content&#39;)";
    mysqli_query($con, $sql);
}
Copier après la connexion
Mode non bloquant : lors de la concurrence, le premier utilisateur demande et obtient le verrouillage du fichier. Les utilisateurs qui demandent plus tard reviendront directement au système étant occupé, veuillez réessayer plus tard

<?php
db();
global $con;

//step1 接收下单参数
$product_id = 1;// 商品ID
$buy_num = 1;// 购买数量

$fp = fopen(&#39;lock.txt&#39;, &#39;w&#39;);
if (flock($fp, LOCK_EX|LOCK_NB)) {   //文件独占锁,非阻塞
    //step2 查询商品信息
    $sql = "select * from products where id={$product_id}";
    $result = mysqli_query($con, $sql);
    $row = mysqli_fetch_assoc($result);

    //step3 判断商品下单数量是否大于商品库存数量
    if ($row[&#39;store&#39;] > 0) {
        //处理订单
        sleep(1);
        //step4 更新商品库存数量(减去下单数量)
        $sql = "update products set store=store-{$buy_num} where id={$product_id}";
        if (mysqli_query($con, $sql)) {
            echo "更新成功";
            //step5 生成订单号创建订单
            $oid = build_order_no();
            create_order($oid, $product_id, $buy_num);
            insertLog(&#39;库存减少成功,下单成功&#39;);
        } else {
            echo "更新失败";
            insertLog(&#39;库存减少失败&#39;);
        }
    } else {
        //商品已经抢购完
        echo "没有库存";
        insertLog(&#39;库存不够&#39;);
    }
    flock($fp, LOCK_UN); //释放锁

} else {
    //系统繁忙,请稍后再试
    echo "系统繁忙,请稍后再试";
    insertLog(&#39;系统繁忙,请稍后再试&#39;);
}
fclose($fp);

function db()
{
    global $con;
    $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;root&#39;,&#39;test&#39;);
    if (!$con) {
        echo "数据库连接失败";
    }
}

/**
 * 生成唯一订单号
 */
function build_order_no()
{
    return date(&#39;Ymd&#39;) . str_pad(mt_rand(1, 99999), 5, &#39;0&#39;, STR_PAD_LEFT);
}

function create_order($oid, $product_id, $number)
{
    global $con;
    $sql = "INSERT INTO `order` (oid, product_id, number) values(&#39;$oid&#39;, &#39;$product_id&#39;, &#39;$number&#39;)";
    mysqli_query($con, $sql);
}

/**
 * 记录日志
 */
function insertLog($content)
{
    global $con;
    $sql = "INSERT INTO `order_log` (content) values(&#39;$content&#39;)";
    mysqli_query($con, $sql);
}
Copier après la connexion

Utiliser la file d'attente redis

Parce que l'opération pop est atomique, même si de nombreux utilisateurs arrivent en même temps, ils le feront être exécuté dans l'ordre. Il est recommandé d'utiliser

  • Les performances des transactions MySQL diminuent considérablement en cas de concurrence élevée, et la méthode de verrouillage de fichier est également


  • 1. Inventoriez d'abord le produit dans la file d'attente Redis
  • <?php
    
    db();
    global $con;
    
    // 查询商品信息
    $product_id = 1;
    $sql = "select * from products where id={$product_id}";
    $result = mysqli_query($con, $sql);
    $row = mysqli_fetch_assoc($result);
    $store = $row[&#39;store&#39;];
    
    // 获取商品在redis缓存的库存
    $redis = new Redis();
    $result = $redis->connect(&#39;127.0.0.1&#39;, 6379);
    $key = &#39;goods_store_&#39; . $product_id;
    $res = $redis->llen($key);
    $count = $store - $res;
    
    for ($i=0; $i<$count; $i++) {
        $redis->lpush($key, 1);
    }
    echo $redis->llen($key);
    
    function db()
    {
        global $con;
        $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;root&#39;,&#39;test&#39;);
        if (!$con) {
            echo "数据库连接失败";
        }
    }
    Copier après la connexion

    2. Logique d'achat précipité et de vente flash

    <?php
    
    db();
    global $con;
    
    //step1 接收下单参数
    $product_id = 1;// 商品ID
    $buy_num = 1;// 购买数量
    
    //step2 下单前判断redis队列库存量
    $redis = new Redis();
    $result = $redis->connect(&#39;127.0.0.1&#39;,6379);
    $count = $redis->lpop(&#39;goods_store_&#39; . $product_id);
    if (!$count) {
        insertLog(&#39;error:no store redis&#39;);
        return &#39;秒杀结束,没有商品库存了&#39;;
    }
    
    sleep(1);
    //step3 更新商品库存数量(减去下单数量)
    $sql = "update products set store=store-{$buy_num} where id={$product_id}";
    if (mysqli_query($con, $sql)) {
        echo "更新成功";
        //step4 生成订单号创建订单
        $oid = build_order_no();
        create_order($oid, $product_id, $buy_num);
        insertLog(&#39;库存减少成功,下单成功&#39;);
    } else {
        echo "更新失败";
        insertLog(&#39;库存减少失败&#39;);
    }
    
    function db()
    {
        global $con;
        $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;root&#39;,&#39;test&#39;);
        if (!$con) {
            echo "数据库连接失败";
        }
    }
    
    /**
     * 生成唯一订单号
     */
    function build_order_no()
    {
        return date(&#39;Ymd&#39;) . str_pad(mt_rand(1, 99999), 5, &#39;0&#39;, STR_PAD_LEFT);
    }
    
    function create_order($oid, $product_id, $number)
    {
        global $con;
        $sql = "INSERT INTO `order` (oid, product_id, number) values(&#39;$oid&#39;, &#39;$product_id&#39;, &#39;$number&#39;)";
        mysqli_query($con, $sql);
    }
    
    /**
     * 记录日志
     */
    function insertLog($content)
    {
        global $con;
        $sql = "INSERT INTO `order_log` (content) values(&#39;$content&#39;)";
        mysqli_query($con, $sql);
    }
    Copier après la connexion

redis prévention du verrouillage optimiste Survente

<?php

$redis =new Redis();
$redis->connect("127.0.0.1", 6379);
$redis->watch(&#39;sales&#39;);//乐观锁 监视作用 set()  初始值0
$sales = $redis->get(&#39;sales&#39;);

$n = 20;// 库存
if ($sales >= $n) {
    exit(&#39;秒杀结束&#39;);
}

//redis开启事务
$redis->multi();
$redis->incr(&#39;sales&#39;); //将 key 中储存的数字值增一 ,如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
$res = $redis->exec(); //成功1 失败0

if ($res) {
    //秒杀成功
    $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;root&#39;,&#39;test&#39;);
    if (!$con) {
        echo "数据库连接失败";
    }

    $product_id = 1;// 商品ID
    $buy_num = 1;// 购买数量
    sleep(1);

    $sql = "update products set store=store-{$buy_num} where id={$product_id}";

    if (mysqli_query($con, $sql)) {
        echo "秒杀完成";
    }

} else {
    exit(&#39;抢购失败&#39;);
}
Copier après la connexion

Apprentissage recommandé : "Tutoriel vidéo PHP"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 apporte plusieurs nouvelles fonctionnalités, améliorations de sécurité et de performances avec une bonne quantité de dépréciations et de suppressions de fonctionnalités. Ce guide explique comment installer PHP 8.4 ou mettre à niveau vers PHP 8.4 sur Ubuntu, Debian ou leurs dérivés. Bien qu'il soit possible de compiler PHP à partir des sources, son installation à partir d'un référentiel APT comme expliqué ci-dessous est souvent plus rapide et plus sécurisée car ces référentiels fourniront les dernières corrections de bogues et mises à jour de sécurité à l'avenir.

CakePHP travaillant avec la base de données CakePHP travaillant avec la base de données Sep 10, 2024 pm 05:25 PM

Travailler avec la base de données dans CakePHP est très simple. Nous comprendrons les opérations CRUD (Créer, Lire, Mettre à jour, Supprimer) dans ce chapitre.

Date et heure de CakePHP Date et heure de CakePHP Sep 10, 2024 pm 05:27 PM

Pour travailler avec la date et l'heure dans cakephp4, nous allons utiliser la classe FrozenTime disponible.

Téléchargement de fichiers CakePHP Téléchargement de fichiers CakePHP Sep 10, 2024 pm 05:27 PM

Pour travailler sur le téléchargement de fichiers, nous allons utiliser l'assistant de formulaire. Voici un exemple de téléchargement de fichiers.

Discuter de CakePHP Discuter de CakePHP Sep 10, 2024 pm 05:28 PM

CakePHP est un framework open source pour PHP. Il vise à faciliter grandement le développement, le déploiement et la maintenance d'applications. CakePHP est basé sur une architecture de type MVC à la fois puissante et facile à appréhender. Modèles, vues et contrôleurs gu

CakePHP créant des validateurs CakePHP créant des validateurs Sep 10, 2024 pm 05:26 PM

Le validateur peut être créé en ajoutant les deux lignes suivantes dans le contrôleur.

Journalisation CakePHP Journalisation CakePHP Sep 10, 2024 pm 05:26 PM

Se connecter à CakePHP est une tâche très simple. Il vous suffit d'utiliser une seule fonction. Vous pouvez enregistrer les erreurs, les exceptions, les activités des utilisateurs, les actions entreprises par les utilisateurs, pour tout processus en arrière-plan comme cronjob. La journalisation des données dans CakePHP est facile. La fonction log() est fournie

Comment configurer Visual Studio Code (VS Code) pour le développement PHP Comment configurer Visual Studio Code (VS Code) pour le développement PHP Dec 20, 2024 am 11:31 AM

Visual Studio Code, également connu sous le nom de VS Code, est un éditeur de code source gratuit – ou environnement de développement intégré (IDE) – disponible pour tous les principaux systèmes d'exploitation. Avec une large collection d'extensions pour de nombreux langages de programmation, VS Code peut être c

See all articles