Maison > développement back-end > tutoriel php > Comment créer une commande Laravel CSS-Minify

Comment créer une commande Laravel CSS-Minify

Joseph Gordon-Levitt
Libérer: 2025-02-21 08:30:14
original
308 Les gens l'ont consulté

Comment créer une commande Laravel CSS-Minify

Dans cet article, vous apprendrez à utiliser l'outil de ligne de commande Artisan de Laravel et comment créer une commande personnalisée. Notez que vous devez vous familiariser avec le framework Laravel pour tirer le meilleur parti de cet article.

Les plats clés

  • Tirez parti de Laravel Artisan: Utilisez l'outil de ligne de commande artisanale de Laravel pour créer des commandes personnalisées pour la minification CSS, améliorant l'efficacité du flux de travail dans les projets de développement Web.
  • Création de commande personnalisée: Créez facilement une commande personnalisée à l'aide de `PHP Artisan Commande: Make` avec des options pour la dénomination, le stockage et le service de noms, permettant des fonctionnalités personnalisées dans votre application Laravel.
  • Minification Options: Implémentez les options dans votre commande pour gérer la concaténation du fichier CSS et la préservation des commentaires, offrant une flexibilité basée sur différents besoins de développement.
  • Enregistrement de commande: assurez-vous d'enregistrer votre nouvelle commande dans le système artisanal de Laravel pour le rendre exécutable, soit via le fichier `artisan.php` ou un fournisseur de services pour le développement de packages.
  • EXÉCUTION ET SORTIE: Utilisez la commande pour réduire les fichiers CSS, avec des drapeaux facultatifs pour la concaténation et la préservation des commentaires, et améliorez les commentaires de la commande avec des messages informatifs pendant le processus d'exécution.

Que construisons-nous

Dans ce tutoriel, nous allons créer une commande pour minimer nos actifs CSS, qui seront utilisés comme ceci:

<span>cssmin 'output_path' 'file1'...'fileN' --comments --concat</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • output_path: (requis) chemin pour enregistrer les fichiers minifiés, (style.css -> style.min.css).
  • Fichier1 ... Filen: (requis) Liste des fichiers à minimer.
  • - Commentaires: (facultatif) Ajouter cette option pour garder les commentaires.
  • - Concat: (facultatif) Concaténer les fichiers minifiés en un seul fichier appelé all.min.css.

Qu'est-ce qu'une commande Laravel

Artisan est le nom de l'utilitaire de ligne de commande à Laravel. Il est livré avec un ensemble de commandes prédéfinies, que vous pouvez énumérer avec PHP Artisan List. Si vous souhaitez afficher l'aide pour une commande spécifique, vous pouvez utiliser la commande PHP Artisan Help.

Création de la commande CSS MINIFICARE

Pour créer une commande artisan, vous pouvez utiliser la commande: faire la commande. Cette commande accepte un argument:

  • Nom: le nom de classe pour la commande.

et trois options:

  • - Commande: le nom qui doit être tapé pour exécuter la commande.
  • - Chemin: par défaut, les commandes sont stockées dans le dossier APP / Commandes, cependant, vous pouvez modifier cela avec cette option.
  • - Espace de noms: vous pouvez utiliser cette option pour nommer votre ensemble de commandes, par ex. Dans la commande Commande: Make, la commande de Make est sous l'espace de noms de commande.

Maintenant, pour créer notre commande, nous utiliserons PHP Artisan Command: Faire CSSMinCommand --Command = CSSMinwhich créera un fichier CSSMinCommand.php dans notre répertoire APP / Commands.

<span>cssmin 'output_path' 'file1'...'fileN' --comments --concat</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Notre classe CSSMincommand étend le IlluminateConsoleCommand et remplace deux méthodes (getarguments, getOptions).

  • GetArguments: cette fonction renvoie un tableau d'arguments qui devraient être transmis à la commande, (Ex: la liste des fichiers que nous transmettons à la commande CSSMIN).
  • getOptions: renvoie une liste d'options ou de commutateurs que vous pouvez transmettre à la commande. (par exemple - les pays).

Remarque: les options peuvent ou non avoir des valeurs, - - Les vendeurs sont seulement un drapeau qui renvoie vrai s'il est transmis à la commande, tandis que --onupput = 'public / actifs' renvoie une valeur.

Lorsque votre commande est exécutée, la méthode de feu est appelée, c'est donc là que nous devons mettre notre logique de commande.

Enregistrer la commande

Si vous essayez d'exécuter notre commande php artisan cssmin 'args', vous obtiendrez une commande "cssmin" n'est pas définie.

Pour enregistrer une commande, vous devez l'ajouter au fichier artisan.php:

<span>use Illuminate<span>\Console\Command</span>;
</span><span>use Symfony<span>\Component\Console\Input\InputOption</span>;
</span><span>use Symfony<span>\Component\Console\Input\InputArgument</span>;
</span>
<span>class CssminCommand extends Command{
</span>    <span>protected $name = 'cssmin';
</span>    <span>protected $description = 'Command description.';
</span>    
    <span>public function __construct(){
</span>		<span><span>parent::</span>__construct();
</span>	<span>}
</span>    
    <span>public function fire(){
</span>		<span>//
</span>	<span>}
</span>	
	<span>protected function getArguments(){
</span>		<span>return array(
</span>			<span>array('example', InputArgument<span>::</span>REQUIRED, 'An example argument.'),
</span>		<span>);
</span>	<span>}
</span>    
	<span>protected function getOptions(){
</span>		<span>return array(
</span>			<span>array('example', null, InputOption<span>::</span>VALUE_OPTIONAL, 'An example option.', null),
</span>		<span>);
</span>	<span>}
</span><span>}</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

Si vous ne souhaitez pas mettre vos commandes dans le fichier artisan.php, vous pouvez créer un fichier séparé et l'inclure, ou si vous créez un package, vous pouvez les enregistrer dans votre fournisseur de services.

Arguments

Dans notre méthode GetArguments, nous définirons notre sortie et nos fichiers.
Pour définir un argument, nous devons passer un tableau de valeurs:

<span>Artisan<span>::</span>add( new CssMinCommand );
</span>
<span>//or through the container
</span><span>Artisan<span>::</span>add( App<span>::</span>make("CssMinCommand") );</span>
Copier après la connexion
Copier après la connexion
  • Nom: Nom de la clé à utiliser lors de la récupération des arguments.
  • Mode: Peut avoir l'une des trois options:

    • InputArgument :: requis: l'argument est requis.
    • InputArgument :: Facultatif: L'argument est facultatif.
    • inputargument :: is_array: l'argument accepte plusieurs valeurs (ex: file1 ... filen).

    Cependant, vous pouvez les combiner comme InputArgument :: is_Array | InputArgument :: requis (l'argument est requis et doit être un tableau).

  • Description: utile lors de l'impression de l'aide de la commande.
  • DefaultValue: Si l'argument n'a pas été fourni.

donc notre méthode GetArguments sera:

<span>array( 'name', 'mode', 'description', 'defaultValue' )</span>
Copier après la connexion
Copier après la connexion

Remarque: Lors de l'utilisation de l'argument is_array, ce devrait être le dernier sur le tableau des arguments retournés. (évidemment).

Options

Notre commande CSSMIN n'aura que deux options. Pour définir une option, nous passons un tableau:

<span>protected function getArguments(){
</span>        <span>return array(
</span>            <span>array(
</span>                <span>'output', 
</span>                <span>InputArgument<span>::</span>REQUIRED,
</span>                <span>'Path to output directory'
</span>            <span>),
</span>            <span>array(
</span>                <span>'files', 
</span>                <span>InputArgument<span>::</span>IS_ARRAY | InputArgument<span>::</span>OPTIONAL ,
</span>                <span>"List of css files to minify"
</span>            <span>),
</span>        <span>);
</span>    <span>}</span>
Copier après la connexion
Copier après la connexion
  • Nom: le nom de votre option (ex: commentaires).
  • raccourci: une version plus courte de votre option (ex: --verbose et -v).
  • MODE: Peut être l'une des quatre options (inputOption :: value_is_array, inputOption :: value_optional, inputOption :: value_required, inputOption :: value_none), les trois premières valeurs sont similaires aux arguments.

    • value_none: indique que l'option est un drapeau booléen (ex: --verbose).
  • Description: utile lors de l'impression de l'aide de la commande.

  • DefaultValue: si la valeur de l'option n'a pas été fournie.

donc notre méthode GetOptions sera:

<span>cssmin 'output_path' 'file1'...'fileN' --comments --concat</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

exécuter la commande

Lorsque notre méthode d'incendie est appelée, nous devons rassembler nos arguments et nos options. Nous pouvons faire une fonction distincte pour le faire pour nous:

<span>use Illuminate<span>\Console\Command</span>;
</span><span>use Symfony<span>\Component\Console\Input\InputOption</span>;
</span><span>use Symfony<span>\Component\Console\Input\InputArgument</span>;
</span>
<span>class CssminCommand extends Command{
</span>    <span>protected $name = 'cssmin';
</span>    <span>protected $description = 'Command description.';
</span>    
    <span>public function __construct(){
</span>		<span><span>parent::</span>__construct();
</span>	<span>}
</span>    
    <span>public function fire(){
</span>		<span>//
</span>	<span>}
</span>	
	<span>protected function getArguments(){
</span>		<span>return array(
</span>			<span>array('example', InputArgument<span>::</span>REQUIRED, 'An example argument.'),
</span>		<span>);
</span>	<span>}
</span>    
	<span>protected function getOptions(){
</span>		<span>return array(
</span>			<span>array('example', null, InputOption<span>::</span>VALUE_OPTIONAL, 'An example option.', null),
</span>		<span>);
</span>	<span>}
</span><span>}</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

L'argument et les méthodes d'option prennent une clé comme argument et renvoient la valeur appropriée.

Pour garder notre exemple propre et simple, nous utiliserons cette fonction simple avec une petite modification pour le processus de minification.

<span>Artisan<span>::</span>add( new CssMinCommand );
</span>
<span>//or through the container
</span><span>Artisan<span>::</span>add( App<span>::</span>make("CssMinCommand") );</span>
Copier après la connexion
Copier après la connexion

Maintenant, pour traiter nos arguments (fichiers), nous allons faire une méthode distincte pour faire le travail.

<span>array( 'name', 'mode', 'description', 'defaultValue' )</span>
Copier après la connexion
Copier après la connexion

Enfin, notre méthode d'incendie n'appellera que les deux méthodes:

<span>protected function getArguments(){
</span>        <span>return array(
</span>            <span>array(
</span>                <span>'output', 
</span>                <span>InputArgument<span>::</span>REQUIRED,
</span>                <span>'Path to output directory'
</span>            <span>),
</span>            <span>array(
</span>                <span>'files', 
</span>                <span>InputArgument<span>::</span>IS_ARRAY | InputArgument<span>::</span>OPTIONAL ,
</span>                <span>"List of css files to minify"
</span>            <span>),
</span>        <span>);
</span>    <span>}</span>
Copier après la connexion
Copier après la connexion

Astuce: vous pouvez également exécuter une commande externe à l'aide de la méthode d'appel.

<span>array('name', 'shortcut', 'mode', 'description', 'defaultValue')</span>
Copier après la connexion

Pour tester notre commande, nous allons copier certains fichiers CSS dans notre répertoire public / CSS, puis exécuter la commande.

<span>protected function getOptions(){
</span>        <span>return array(
</span>            <span>array('comments', 'c', InputOption<span>::</span>VALUE_NONE, 'Don\'t strip comments' , null),
</span>            <span>array('concat', null, InputOption<span>::</span>VALUE_NONE, 'Concat the minified result to one file' , null),
</span>        <span>);
</span>    <span>}</span>
Copier après la connexion

La première commande créera deux fichiers (style.min.css, Reactive.min.css) sur le répertoire public / css.

Parce que nous avons utilisé les - Comements et les indicateurs - CONCAT, nous allons obtenir un fichier appelé all.min.css contenant les deux fichiers avec des commentaires laissés.

Notre commande n'est pas très descriptive et ne donne aucun message ou notifications!

Amélioration de la commande

Avant de continuer, sur le référentiel GitHub final, je créerai une nouvelle balise pour notre commande afin que vous puissiez changer et tester chacun.

Pour rendre la commande un peu verbeuse, Laravel nous fournit certaines fonctions de sortie:

<span>private function init(){
</span>    <span>// retrun an array
</span>    <span>$this->files = $this->argument('files');
</span>    <span>// return a string
</span>    <span>$this->output_path = $this->argument('output');
</span>    <span>// return true if passed, otherwise false
</span>    <span>$this->comments = $this->option('comments');
</span>    <span>// return true if passed, otherwise false
</span>    <span>$this->concat = $this->option('concat');
</span><span>}</span>
Copier après la connexion

Ceci sera sorti:

Comment créer une commande Laravel CSS-Minify

à côté de simplement afficher des messages, vous pouvez demander des informations à l'utilisateur, ex:

<span>private function minify( $css, $comments ){
</span>        <span>// Normalize whitespace
</span>        <span>$css = preg_replace( '/\s+/', ' ', $css );
</span>
        <span>// Remove comment blocks, everything between /* and */, unless preserved with /*! ... */
</span>        <span>if( !$comments ){
</span>            <span>$css = preg_replace( '/\/\*[^\!](.*?)\*\//', '', $css );
</span>        <span>}//if
</span>        
        <span>// Remove ; before }
</span>        <span>$css = preg_replace( '/;(?=\s*})/', '', $css );
</span>
        <span>// Remove space after , : ; { } */ >
</span>        <span>$css = preg_replace( '/(,|:|;|\{|}|\*\/|>) /', '', $css );
</span>
        <span>// Remove space before , ; { } ( ) >
</span>        <span>$css = preg_replace( '/ (,|;|\{|}|\(|\)|>)/', '', $css );
</span>
        <span>// Strips leading 0 on decimal values (converts 0.5px into .5px)
</span>        <span>$css = preg_replace( '/(:| )0\.([0-9]+)(%|em|ex|px|in|cm|mm|pt|pc)/i', '.', $css );
</span>
        <span>// Strips units if value is 0 (converts 0px to 0)
</span>        <span>$css = preg_replace( '/(:| )(\.?)0(%|em|ex|px|in|cm|mm|pt|pc)/i', '0', $css );
</span>
        <span>// Converts all zeros value into short-hand
</span>        <span>$css = preg_replace( '/0 0 0 0/', '0', $css );
</span>
        <span>// Shortern 6-character hex color codes to 3-character where possible
</span>        <span>$css = preg_replace( '/#([a-f0-9])\1([a-f0-9])\2([a-f0-9])\3/i', '#', $css );
</span>
        <span>return trim( $css );
</span>    <span>}//minify</span>
Copier après la connexion
  • La méthode de confirmation prend deux arguments, un message de question et une valeur par défaut si l'utilisateur tape quelque chose de différent de Y / N.

  • La méthode de demande demandera à l'utilisateur une entrée au lieu de simplement O / N, et si elle est laissée vide, la valeur par défaut est renvoyée.

  • La méthode de choix donnera à l'utilisateur une liste numérotée à choisir, et si elle est laissée vide, la valeur par défaut est renvoyée.

  • La méthode secrète invitera l'utilisateur avec une question et masquera la saisie, mais l'entrée de l'utilisateur sera renvoyée.

En fait, Laravel ne fait que rendre l'API de la console de Symfony et plus verbeux, et il y a tellement plus si vous voulez creuser.

Rendons notre commande plus verbeuse et maintenons l'utilisateur à jour sur les tâches effectuées.

<span>private function processFiles(){
</span>        <span>// array of minified css
</span>        <span>$css_result = [];
</span>        
        <span>foreach ( $this->files as $file ) {
</span>            <span>//read file content
</span>            <span>$file_content = file_get_contents( $file );
</span>            <span>//minify CSS and add it to the result array
</span>            <span>$css_result[] = $this->minify( $file_content, $this->comments );
</span>        <span>}//foreach
</span>        
        <span>// if the concat flag is true
</span>        <span>if( $this->concat ){
</span>            <span>// join the array of minified css
</span>            <span>$css_concat = implode( PHP_EOL, $css_result );
</span>            <span>// save to file
</span>            <span>file_put_contents($this->output_path . '/all.min.css', $css_concat);
</span>        <span>}//if
</span>        <span>else{
</span>            <span>foreach ($css_result as $key => $css) {
</span>                <span>//remove '.css' to add '.min.css'
</span>                <span>$filename = basename( $this->files[$key], '.css' ) . '.min.css';
</span>                <span>// save to file
</span>                <span>file_put_contents($this->output_path . '/' . $filename, $css);
</span>            <span>}//for
</span>        <span>}//else
</span>
    <span>}//processFiles</span>
Copier après la connexion

Notre fonction imprime désormais quelques messages utiles pour garder une trace de ce qui se passe.

Comment créer une commande Laravel CSS-Minify

Remarque: ce sera étiqueté comme v2 de notre commande sur le référentiel github.

Lors de la création d'une application, nous avons l'habitude de vider la liste des routes disponibles (routes artisanales PHP).

Comment créer une commande Laravel CSS-Minify

Symfony fournit une fonction qui vous permet d'imprimer facilement un tel tableau. Vérifiez la documentation pour un exemple. Nous verrons ensuite comment nous pouvons utiliser certains aides à la console Symfony.

en utilisant les aides à la console Symfony

Pour illustrer l'utilisation de certains aides à symfony, nous utiliserons l'assistant de progression pour maintenir l'utilisateur à jour sur la progression de l'emploi.

À la fin de notre méthode init, nous aurons besoin d'une progression de The Helerset, puis de démarrer notre barre de progression.

<span>cssmin 'output_path' 'file1'...'fileN' --comments --concat</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

La méthode de démarrage accepte deux arguments, $ this-> la sortie est une instance consoleouput de la console Symfony. Le deuxième argument est le nombre maximum d'étapes.

Chaque fois que nous traitons un fichier dans notre méthode ProcessFiles, nous ferons progresser la barre de progression d'une étape, et lorsque le travail sera terminé, nous terminerons la barre de progression et imprimerons un message de notification.

<span>use Illuminate<span>\Console\Command</span>;
</span><span>use Symfony<span>\Component\Console\Input\InputOption</span>;
</span><span>use Symfony<span>\Component\Console\Input\InputArgument</span>;
</span>
<span>class CssminCommand extends Command{
</span>    <span>protected $name = 'cssmin';
</span>    <span>protected $description = 'Command description.';
</span>    
    <span>public function __construct(){
</span>		<span><span>parent::</span>__construct();
</span>	<span>}
</span>    
    <span>public function fire(){
</span>		<span>//
</span>	<span>}
</span>	
	<span>protected function getArguments(){
</span>		<span>return array(
</span>			<span>array('example', InputArgument<span>::</span>REQUIRED, 'An example argument.'),
</span>		<span>);
</span>	<span>}
</span>    
	<span>protected function getOptions(){
</span>		<span>return array(
</span>			<span>array('example', null, InputOption<span>::</span>VALUE_OPTIONAL, 'An example option.', null),
</span>		<span>);
</span>	<span>}
</span><span>}</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

Vous pouvez essayer la commande avec plusieurs fichiers ou décommenter la ligne de fonction de sommeil pour voir un effet en direct.

Comment créer une commande Laravel CSS-Minify

Remarque: cette version sera taguée sous forme de v3 sur le référentiel final.

Conclusion

Dans cet article, nous avons appris comment créer et étendre les commandes Laravel. Laravel a beaucoup de commandes intégrées que vous pouvez explorer, et vous pouvez également vérifier notre référentiel final sur GitHub pour tester le résultat final. Questions? Commentaires? Souhaitez-vous voir plus de tutoriels de commande artisanale? Faites-nous savoir!

Questions fréquemment posées (FAQ) sur la commande Laravel CSS Minify

Quel est le but de la réduction du CSS dans Laravel?

Minification CSS dans Laravel est une étape cruciale dans l'optimisation de votre site Web ou de votre application. Cela implique le processus de suppression des caractères inutiles tels que des espaces, des commentaires et des pauses de ligne des fichiers CSS. Ce processus réduit la taille des fichiers CSS, qui à son tour réduit la quantité de données qui doivent être transférées au client. Cela peut améliorer considérablement le temps de chargement de votre site Web ou de votre application, offrant une meilleure expérience utilisateur.

Comment Laravel Mix aide-t-il à CSS Minification?

Laravel Le mélange est un outil puissant qui fournit une couramment API pour définir des étapes de construction WebPack pour votre application Laravel. Il prend en charge plusieurs pré-processeurs CSS et JavaScript communs, y compris la minification. En utilisant Laravel Mix, vous pouvez facilement réduire vos fichiers CSS avec une seule commande, sans avoir à supprimer manuellement les caractères inutiles. Cela fait non seulement gagner du temps, mais garantit également que vos fichiers CSS sont aussi optimisés que possible.

Puis-je minimer les fichiers CSS sans utiliser Laravel Mix?

Oui, vous pouvez minifiliser les fichiers CSS sans utiliser Laravel Mélanger. Il existe plusieurs outils en ligne et packages NPM disponibles qui peuvent vous aider à réduire vos fichiers CSS. Cependant, l'utilisation de Laravel Mix est recommandée car elle s'intègre parfaitement à Laravel et fournit un moyen simple et pratique de gérer et d'optimiser vos fichiers CSS.

Quels sont les problèmes potentiels que je pourrais faire face tout en minimisant CSS dans Laravel?

Bien que la mini-montée CSS dans Laravel soit généralement un processus simple, vous pourriez rencontrer des problèmes si vos fichiers CSS contiennent des erreurs de syntaxe. Ces erreurs peuvent entraîner l'échec du processus de minification, ce qui entraîne des fichiers CSS non optimisés. Par conséquent, il est important de s'assurer que vos fichiers CSS sont sans erreur avant d'essayer de les minimer.

Comment puis-je déboguer les problèmes pendant la minification CSS dans Laravel?

Si vous rencontrez des problèmes pendant la minification CSS Dans Laravel, vous pouvez utiliser la fonctionnalité Source Maps de Laravel Mix pour les déboguer. Les cartes source sont des fichiers qui mappent les fichiers CSS minifiés dans les fichiers source d'origine, vous permettant de tracer et de résoudre facilement les problèmes.

Puis-je automatiser le processus de minification CSS dans Laravel?

Oui, vous pouvez automatiser le processus de minification CSS à Laravel en utilisant la fonction de versioning de Laravel Mix. Cette fonctionnalité diminue automatiquement vos fichiers CSS chaque fois que vous exécutez la commande de production de production. Cela garantit que vos fichiers CSS sont toujours optimisés, sans avoir à les minimer manuellement à chaque fois.

Comment la minification CSS affecte-t-elle les performances de mon application Laravel?

Minification CSS peut-elle améliorer considérablement les performances de votre application Laravel. En réduisant la taille de vos fichiers CSS, vous pouvez réduire la quantité de données qui doivent être transférées au client. Cela peut entraîner des temps de chargement plus rapides, offrant une meilleure expérience utilisateur.

Puis-je utiliser Laravel Mix pour minive Pour minimer les fichiers JavaScript. Cela peut optimiser davantage votre application Laravel, en réduisant la quantité de données qui doivent être transférées au client.

Quelle est la différence entre les fichiers CSS minimisation et concaténer?

Les fichiers CSS minimisation impliquent la suppression Caractères inutiles pour réduire leur taille, tandis que la concaténation des fichiers CSS consiste à combiner plusieurs fichiers CSS en un seul fichier. Les deux processus peuvent aider à optimiser votre application Laravel, mais elles servent des objectifs différents. La minimisation réduit la taille de chaque fichier CSS individuel, tandis que la concaténation réduit le nombre de demandes HTTP en combinant plusieurs fichiers en un. Pour vous assurer que vos fichiers CSS minifiés sont servis correctement, vous pouvez utiliser la fonction de versioning de Laravel Mix. Cette fonction a ajoute un hachage unique aux noms de fichiers de vos fichiers CSS minifiés, garantissant que le client reçoit toujours la dernière version de vos fichiers CSS.

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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal