Technical Documentation: yiisoft/yii2
ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference
Overview (`README.md`)
Yii 2 is a modern framework designed to be a solid foundation for your PHP application.
It is fast, secure and efficient and works right out of the box pre-configured with reasonable defaults.
The framework is easy to adjust to meet your needs, because Yii has been designed to be flexible.
Installation
[!IMPORTANT]
- The minimum required PHP version of Yii is PHP
7.4.- It works best with PHP
8.
- Follow the Definitive Guide
in order to get step by step instructions.
Documentation
- A Definitive Guide and
a Class Reference cover every detail
of the framework. - There is a PDF version of the Definitive Guide
and a Definitive Guide Mirror which is updated every 15 minutes. - For Yii 1.1 users, there is Upgrading from Yii 1.1
to get an idea of what has changed in 2.0.
Versions & PHP compatibility
[!NOTE]
See "Release Cycle" at the website for detailed information about supported versions.
Community
- Participate in discussions at forums.
- Community Slack and Chat in IRC.
- Follow us on Facebook, Twitter
and GitHub. - Check other communities.
Contributing
The framework is Open Source powered by an excellent community.
You may join us and:
- Report an issue
- Translate documentation or messages
- Give us feedback or start a design discussion
- Contribute to the core code or fix bugs
- Become a sponsor
Reporting Security issues
[!WARNING]
Please do not report security vulnerabilities through public GitHub issues.
Please refer to a special page at the website
describing proper workflow for security issue reports.
Directory Structure
build/ internally used build tools
docs/ documentation
framework/ core framework code
tests/ tests of the core framework codeSpreading the Word
Acknowledging or citing Yii 2 is as important as direct contributions.
In presentations
If you are giving a presentation or talk featuring work that makes use of Yii 2 and would like to acknowledge it,
we suggest using our logo on your title slide.
In projects
If you are using Yii 2 as part of an OpenSource project, a way to acknowledge it is to
use a special badge in your README:
If your code is hosted at GitHub, you can place the following in your README.md file to get the badge:
[](https://www.yiiframework.com/)Security
GitHub Actions workflows are analyzed by zizmor for supply-chain vulnerabilities and workflow misconfigurations.
Supply-chain security is tracked via the OpenSSF Scorecard, which evaluates security practices across the repository.
Sponsoring
Support this project by becoming a sponsor or a backer.
Overview (`framework/README.md`)
Yii PHP Framework Version 2
This is the core framework code of Yii 2.
This repository is a read-only git subsplit of https://github.com/yiisoft/yii2.
Please submit issue reports and pull requests to the main repository.
For license information check the LICENSE-file.
Installation
The preferred way to install the Yii framework is through composer.
Refer to Bower and NPM Assets installation to select an asset installation method.
Either run
composer require yiisoft/yii2or add
"yiisoft/yii2": "~2.0.0",to the require section of your composer.json.
Overview (`tests/README.md`)
Yii 2.0 Unit tests
DIRECTORY STRUCTURE
data/ models, config and other test data
config.php this file contains configuration for database and caching backends
framework/ the framework unit tests
runtime/ the application runtime dir for the yii test appHOW TO RUN THE TESTS
Make sure you have PHPUnit installed and that you installed all composer dependencies (run composer update in the repo base directory).
Run PHPUnit in the yii repo base directory.
phpunitYou can run tests for specific groups only:
phpunit --group=mysql,base,i18nYou can get a list of available groups via phpunit --list-groups.
A single test class could be run like the following:
phpunit tests/framework/base/ObjectTest.phpTEST CONFIGURATION
PHPUnit configuration is in phpunit.xml.dist in repository root folder.
You can create your own phpunit.xml to override dist config.
Database and other backend system configuration can be found in tests/data/config.php
adjust them to your needs to allow testing databases and caching in your environment.
You can override configuration values by creating a config.local.php file
and manipulate the $config variable.
For example to change MySQL username and password your config.local.php should
contain the following:
<?php
$config['databases']['mysql']['username'] = 'yiitest';
$config['databases']['mysql']['password'] = 'changeme';DOCKERIZED TESTING
Get started by going to the tests directory and copy the environment configuration.
cd tests
cp .env-dist .envThe newly created .env file defines the configuration files used by docker-compose. By default MySQL, Postgres etc. services are disabled.
You can choose services available for testing by merging
docker-compose.[...].ymlfiles in.env. For example, if you only want to test with MySQL, you can modify theCOMPOSE_FILEvariable as follows:
COMPOSE_FILE=docker-compose.yml:docker-compose.mysql.ymlNote: The files
docker-compose.caching.ymlanddocker-compose.mssql.ymlcannot be merged withdocker-compose.yml.
Running tests via shell script
You need to go to the tests directory and run the test-local.sh script. The first argument can be: default, caching, mssql, pgsql, mysql. You can pass additional arguments to this script to control the behavior of PHPUnit. For example:
cd tests
sh test-local.sh default --exclude caching,dbManually running the tests
You can also run tests manually. To do this, you need to start the container and run the tests. For example:
docker compose up -d
docker compose exec php vendor/bin/phpunit -vOracle tests
[!IMPORTANT]
Oracle tests requireoci8andpdo_ociPHP extensions installed locally. Thedocker-compose.oracle.ymlonly starts the Oracle database container; PHPUnit runs on the host.
Start the Oracle container and run the tests manually:
cd tests
COMPOSE_FILE=docker-compose.oracle.yml docker compose up -d --wait
cd ..
vendor/bin/phpunit -v --group oci
cd tests
COMPOSE_FILE=docker-compose.oracle.yml docker compose down -vOverview (`docs/guide-ar/README.md`)
Yii 2.0 الدليل التقني الخاص ببيئة العمل
تم تحرير هذا الملف اعتمادا على الشروط الخاصة بتوثيف ال Yii.
جميع الحقوق محفوظة
2014 (c) Yii Software LLC.
المقدمة
البداية من هنا
- ماذا يجب أن تعرف عن بيئة العمل
- تثبيت ال Yii
- تشغيل التطبيقات - Running Applications
- قل مرحبا - المشروع الأول
- التعامل مع ال forms
- التعامل مع قواعد البيانات
- إنشاء الشيفرة البرمجية من خلال ال gii
- ماذا الآن - الخطوة القادمة
الهيكلية الخاصة بالتطبيق (Application Structure)
- نظرة عامة عن الهيكلية الخاصة بالتطبيق
- Entry Scripts
- التطبيقات
- مكونات التطبيقات
- Controllers
- Models
- Views
- Modules
- Filters
- Widgets
- Assets
- Extensions
التعامل مع ال requests
- نظرة عامة عن التعامل مع ال requests
- Bootstrapping
- Routing and URL Creation
- Requests
- Responses
- Sessions and Cookies
- Handling Errors - التحكم بالأخطاء
- Logging - تسجيل الحركات
المفاهيم الرئيسية (Key Concepts)
- Components
- Properties
- Events
- Behaviors
- Configurations
- Aliases
- Class Autoloading
- Service Locator
- Dependency Injection Container
التعامل مع قواعد البيانات
- Database Access Objects: Connecting to a database, basic queries, transactions, and schema manipulation
- Query Builder: Querying the database using a simple abstraction layer
- Active Record: The Active Record ORM, retrieving and manipulating records, and defining relations
- Migrations: Apply version control to your databases in a team development environment
- Sphinx
- Redis
- MongoDB
- ElasticSearch
الحصول على البيانات من خلال المستخدمين
- Creating Forms
- Validating Input
- Uploading Files
- Collecting Tabular Input
- Getting Data for Multiple Models
- Extending ActiveForm on the Client Side
عرض البيانات
الامان والحماية
- Security Overview
- Authentication
- Authorization
- Working with Passwords
- Cryptography
- Auth Clients
- Best Practices
Caching التخزين المؤقت
RESTful Web Services
- Quick Start
- Resources
- Controllers
- Routing
- Response Formatting
- Authentication
- Rate Limiting
- Versioning
- Error Handling
الأدوات المساعدة أثناء تطوير التطبيقات
فحص واختبار التطبيقات
مواضيع وعناوين مميزة
- Advanced Project Template
- Building Application from Scratch
- Console Commands
- Core Validators
- Docker
- Internationalization
- Mailing
- Performance Tuning
- Shared Hosting Environment
- Template Engines
- Working with Third-Party Code
- Using Yii as a micro framework
Widgets
- GridView
- ListView
- DetailView
- ActiveForm
- Pjax
- Menu
- LinkPager
- LinkSorter
- Bootstrap Widgets
- jQuery UI Widgets
Helpers
Overview (`docs/guide-de/README.md`)
Das umfassende Handbuch für Yii 2.0
Dieses Tutorial wurde unter den Bedingungen der Yii-Dokumentation veröffentlicht.
Alle Rechte vorbehalten.
2014 (c) Yii Software LLC.
Einführung
Einstieg
- Yii installieren
- Running Applications
- Hallo sagen
- Arbeiten mit Formularen
- Arbeiten mit Datenbanken
- Code generieren mit Gii
- Ausblick
Application Struktur
- Überblick
- Entry Scripts
- Applications
- Application Komponenten
- Controller
- Model
- View
- TBD Filters
- TBD Widgets
- TBD Modules
- Assets
- TBD Extensions
Anfragen bearbeiten
- TBD Bootstrapping
- TBD Routing
- TBD Requests
- TBD Responses
- TBD Sessions and Cookies
- Parsen und Generieren von URLs
- Fehlerbehandlung
- Logging
Kern-Konzepte
- Komponenten
- Eigenschaften
- Events (Ereignisse)
- Behaviors
- Konfiguration
- Aliase
- Class Autoloading
- Service Locator
- Dependency Injection Container
Arbeiten mit Datenbanken
- Data Access Objects - Connecting to a database, basic queries, transactions and schema manipulation
- Query Builder - Querying the database using a simple abstraction layer
- Active Record - The active record ORM, retrieving and manipulating records and defining relations
- Migrations - Version control your databases in a team development environment
- TBD Sphinx
- TBD Redis
- TBD MongoDB
- TBD ElasticSearch
Eingabedaten verarbeiten
Ausgabe von Daten
- TBD Data Formatting
- TBD Pagination
- TBD Sorting
- Data Providers
- Data Widgets
- Theming
Sicherheit
Caching
RESTful Web Services
- Quick Start
- Resources
- Controllers
- Routing
- Response Formatting
- Authentication
- Rate Limiting
- Versioning
- Error Handling
Development Tools
Testing
- Overview
- TBD Unit Tests
- TBD Functional Tests
- TBD Acceptance Tests
- Fixtures
Yii erweitern
- Creating Extensions
- Customizing Core Code
- Using 3rd-Party Libraries
- TBD Using Yii in 3rd-Party Systems
- TBD Using Yii 1.1 and 2.0 Together
- Using Composer
Weitere Themen
- Advanced Application Template
- Building Application from Scratch
- Console Commands
- Core Validators
- Internationalization
- Mailing
- Performance Tuning
- TBD Shared Hosting Environment
- Template Engines
Widgets
- GridView: link to demo page
- ListView: link to demo page
- DetailView: link to demo page
- ActiveForm: link to demo page
- Pjax: link to demo page
- Menu: link to demo page
- LinkPager: link to demo page
- LinkSorter: link to demo page
- Bootstrap Widgets
- Jquery UI Widgets
Helfer-Klassen
- Overview
- TBD ArrayHelper
- TBD Html
- TBD Url
- TBD Security
Overview (`docs/guide-es/README.md`)
Guía Definitiva de Yii 2.0
Este tutorial se publica bajo los Términos de Documentación Yii.
Todos los derechos reservados.
2014 (c) Yii Software LLC.
Introducción
Primeros pasos
- Qué necesita saber
- Instalar Yii
- Funcionamiento de aplicaciones
- Hola a todos
- Trabajar con formularios
- Trabajar con bases de datos
- Generar códigos con Gii
- Adentrarse en Yii
Estructura de una aplicación
- Información general
- Script de entrada
- Aplicaciones
- Componentes de una aplicación
- Controladores
- Modelos
- Vistas
- Filtros
- Widgets
- Módulos
- Assets
- Extensiones
Gestión de las peticiones
- Información general
- Bootstrapping
- Routing y Creación de las URL
- Peticiones (Requests)
- Respuestas (Responses)
- Sesiones (Sessions) y Cookies
- Gestión de errores
- Registro de anotaciones
Conceptos clave
- Componentes
- Propiedades
- Eventos
- Comportamientos (Behaviors)
- Configuraciones
- Alias
- Autocarga de clases
- Localizador de servicios (Service Locator)
- Contenedor de inyección de dependencia
Trabajar con bases de datos
- Objeto de acceso a datos - Conexión a una base de datos, consultas básicas, transacciones y
manipulación de esquemas - Constructor de consultas - Consulta de la base de datos utilizando una simple capa de
abstracción - TBD Active Record - ORM Active Record, recuperación y manipulación de registros y
definición de relaciones - TBD Migraciones - Control de versiones de bases de datos en el entorno de desarrollo en
equipo - TBD Sphinx
- TBD Redis
- TBD MongoDB
- TBD ElasticSearch
Obtener datos de los usuarios
- TBD Crear formularios
- TBD Validar datos
- TBD Subir archivos
- TBD Recogida de tabular input
- TBD Obtener datos para múltiples modelos
Visualizar datos
- TBD Formato de datos
- TBD Paginación
- TBD Ordenación
- TBD Proveedores de datos
- TBD Widgets de datos
- TBD Trabajar con scripts de cliente
- Temas
Seguridad
- TBD Autenticación
- TBD Autorización
- TBD Trabajar con contraseñas
- Autenticar Clientes
- TBD Buenas prácticas
Caché
Servicios Web RESTful
- Guía breve
- Recursos (Resources)
- Controladores
- Gestión de rutas
- Formateo de respuestas
- Autenticación
- Límite de Rango
- Gestión de versiones
- Gestión de errores
Herramientas de Desarrollo
- Depurador y Barra de Herramientas de Depuración
- TBD Generación de códigos con Gii
- TBD Generación de documentación de API
Pruebas
- TBD Información general
- TBD Configuración del entorno de pruebas
- TBD Pruebas unitarias
- TBD Pruebas funcionales
- TBD Pruebas de aceptación
- TBD Fixtures
Temas especiales
- TBD Plantilla aplicación avanzada
- TBD Creación de una aplicación desde cero
- TBD Comandos de consola
- Validadores del núcleo
- TBD Internacionalización
- TBD Envío de correos electrónicos
- TBD Mejora del rendimiento
- TBD Entorno de alojamiento compartido
- TBD Motores de plantillas
- TBD Trabajar con Código de Terceros
Widgets
- GridView: TBD link to demo page
- ListView: TBD link to demo page
- DetailView: TBD link to demo page
- ActiveForm: TBD link to demo page
- Pjax: TBD link to demo page
- Menu: TBD link to demo page
- LinkPager: TBD link to demo page
- LinkSorter: TBD link to demo page
- Bootstrap Widgets
- Jquery UI Widgets
Clases auxiliares
Overview (`docs/guide-fr/README.md`)
Guide définitif pour Yii 2.0
Ce guide est soumis aux Conditions de la Documentation de Yii.
Tous droits réservés.
2014 (c) Yii Software LLC.
Introduction
Mise en Route
- Installer Yii
- Fonctionnement des applications
- Hello World
- Travailler avec les formulaires
- Travailler avec les bases de données
- Générer du code avec Gii
- En savoir plus
Structure Application
- Vue d'ensemble
- Scripts d'entrée
- Applications
- Composants application
- Contrôleurs
- Modèles
- Vues
- TBD Filtres
- TBD Widgets
- TBD Modules
- Assets
- TBD Extensions
Gérer les Requêtes
- TBD Amorçage (Bootstrapping)
- TBD Routes
- TBD Requêtes
- TBD Réponses
- TBD Sessions et Cookies
- Génération et traitement des URL
- Gestion des erreurs
- Journalisation
Concepts Clés
- Composants
- Propriétés
- Evénements
- Comportements
- Configurations
- Alias
- Auto-chargement de classes
- Annuaire de services
- Conteneur d'injection de dépendance
Travailler avec les Bases de Données
- Objet d'accès aux données (DAO) - Connexion à une base de données, requêtes basiques, transactions et manipulation de schéma
- Constructeur de requête - Interrogation de base de données en utilisant une couche d'abstraction simple
- Active Record - Active Record ORM, récupération et manipulation d'enregistrements et définition des relations
- Migrations - Contrôle de version de vos bases de données dans un environnement de développement en équipe
- TBD Sphinx
- TBD Redis
- TBD MongoDB
- TBD ElasticSearch
Getting Data from Users
- Créer des formulaires
- Valider les entrées
- TBD Télécharger des fichiers
- TBD Récupération de données provenant de plusieurs modèles
Afficher les données
- TBD Formattage
- TBD Pagination
- TBD Tri
- Fournisseurs de données
- Widgets pour afficher des données
- Thématisation
Securité
- Authentification
- Autorisation
- Gestion des mots de passe
- TBD Clients authentification
- TBD Meilleures pratiques
Cache
Services Web RESTful
- Démarrage rapide
- Ressources
- Contrôleurs
- Gestion des routes
- Formattage des réponses
- Authentification
- Limiter le taux d'utilisation
- Gestion des versions
- Gestion des erreurs
Outils de développement
Tests
Etendre Yii
- Créer des extensions
- Personnalisation du code du noyau
- Utiliser des libraires tierces
- TBD Utiliser Yii dans d'autres systèmes
- TBD Utiliser Yii 1.1 et 2.0 ensemble
- Utiliser Composer
Sujets avancés
- Modèle application avancée
- Créer une application à partir de zéro
- Commandes console
- Validateurs de base
- Internationalisation
- Envoyer des courriels
- Amélioration des performances
- TBD Environnement d'hébergement mutualisé
- Moteur de gabarit
Widgets
- GridView: link to demo page
- ListView: link to demo page
- DetailView: link to demo page
- ActiveForm: link to demo page
- Pjax: link to demo page
- Menu: link to demo page
- LinkPager: link to demo page
- LinkSorter: link to demo page
- Widgets Bootstrap
- TBD Widgets Jquery UI
Assistants
- Vue d'ensemble
- TBD ArrayHelper
- TBD Html
- TBD Url
- TBD Security
Overview (`docs/guide-id/README.md`)
Panduan Definitif Untuk Yii 2.0
Tutorial ini dirilis di bawah Persyaratan Dokumentasi Yii.
Seluruh hak cipta dilindungi.
2014 (c) Yii Software LLC.
Pengantar
Mulai
- Instalasi Yii
- Menjalankan Aplikasi
- Mengatakan Hello
- Bekerja dengan Form
- Bekerja dengan Database
- Membuat Kode Otomatis dengan Gii
- Menatap ke Depan
Struktur Aplikasi
- Tinjauan
- Script Masuk
- Aplikasi
- Komponen Aplikasi
- Controller
- Model
- Views
- Modul
- Filter
- Widgets
- Aset
- Ekstensi
Penanganan Permintaan
- Tinjauan
- Bootstrap
- Routing dan Pembuatan URL
- Permintaan
- Tanggapan
- Sesi dan Cookies
- Penanganan Kesalahan
- Logging
Konsep Pokok
- Komponen
- Properti
- Event
- Perilaku
- Konfigurasi
- Alias
- Class Autoloading
- Layanan Locator
- Dependency Injection
Bekerja dengan Database
- Data Access Objects: Menghubungkan ke database, query dasar, transaksi, dan manipulasi skema
- Query Builder: Query database menggunakan lapisan abstraksi sederhana
- Active Record: ORM Active Record, mengambil dan memanipulasi catatan, dan mendefinisikan hubungan
- Migrasi: Terapkan kontrol versi untuk database Anda dalam lingkungan pengembangan tim
- Sphinx
- Redis
- MongoDB
- ElasticSearch
Mendapatkan Data dari Pengguna
- Membuat Formulir
- Memvalidasi Masukan
- Mengunggah File
- Mengumpulkan Masukan Tabel
- Mendapatkan Data untuk Beberapa Model
Menampilkan Data
Keamanan
- Tinjauan
- Otentikasi
- Otorisasi
- Bekerja dengan Kata Sandi
- Kriptografi
- Otentikasi Klien
- Praktik Terbaik
Caching
Layanan Web RESTful
- Quick Start
- Sumber Daya
- Controller
- Routing
- Penformatan Respon
- Otentikasi
- Pembatasan Laju
- Versi
- Penanganan Kesalahan
Alat Pengembangan
Pengujian
Topik Khusus
- Cetakan Proyek Lanjutan
- Membangun Aplikasi dari Awal
- Console Commands
- Validator Inti
- Internasionalisasi
- Mailing
- Penyetelan Performa
- Lingkungan Shared Hosting
- Template Engine
- Bekerja dengan Kode Pihak Ketiga
Widget
- GridView
- ListView
- DetailView
- ActiveForm
- Pjax
- Menu
- LinkPager
- LinkSorter
- Bootstrap Widgets
- JQuery UI Widgets
Alat Bantu
Overview (`docs/guide-it/README.md`)
La guida definitiva a Yii 2.0
Questa guida è rilasciata nei termini della documentazione di Yii.
Tutti i diritti riservati.
2014 (c) Yii Software LLC.
Traduzione italiana a cura di Lorenzo Milesi (yetopen.it).
Introduzione
Primi passi
- Installare Yii
- Esecuzione applicazioni
- Dire Ciao
- Utilizzo dei form
- Utilizzo dei database
- Generare codice con Gii
- Passi successivi
Struttura dell'applicazione
- Panoramica
- Entry Scripts
- Applicazioni
- Componenti applicazioni
- Controller
- Modelli
- Viste
- Moduli
- Filtri
- Widget
- Asset
- Estensioni
Gestione delle richieste
- Panoramica
- Bootstrapping
- Instradamenti (routing)
- Richieste
- Risposte
- TBD Sessioni e cookie
- Analisi e generazione URL
- Gestione errori
- Log
Concetti chiave
- Componenti
- Proprietà
- Eventi
- Behavior
- Configurazioni
- Alias
- Caricamento automatico delle classi (autoload)
- Service Locator
- Container per Dependency Injection
Utilizzo del database
- Data Access Objects: Connessione ad un database, query semplici, transazioni e modifiche allo schema
- Query Builder: Esecuzione di query al database usando un semplice livello di astrazione
- Active Record: The Active Record ORM, retrieving and manipulating records, and defining relations
- Migrazoni: Applicare il controllo di versione al database in un ambiente di sviluppo di gruppo
- TBD Sphinx
- TBD Redis
- TBD MongoDB
- TBD ElasticSearch
Ricezione dati dagli utenti
Visualizzazione dei dati
- TBD Formattazione
- TBD Paginazione
- TBD Ordinamento
- Data Provider
- Data Widget
- Utilizzo del Client Scripts
- Temi
Sicurezza
Cache
Servizi web RESTful
- Avvio veloce
- Risorse
- Controller
- Instradamenti
- Formattazione risposte
- Autenticazione
- Limitazione di utilizzo
- Versioning
- Gestione degli errori
Strumenti di sviluppo
Test
Argomenti speciali
- Modello di applicazione avanzata
- Creazione di una applicazione da zero
- Comandi da console
- Validazioni predefinite
- Internazionalizzazione
- Invio email
- Ottimizzazione delle prestazioni
- TBD Ambienti di hosting condiviso
- Template Engine
- Utilizzo di codice di terze parti
Widget
- GridView: link to demo page
- ListView: link to demo page
- DetailView: link to demo page
- ActiveForm: link to demo page
- Pjax: link to demo page
- Menu: link to demo page
- LinkPager: link to demo page
- LinkSorter: link to demo page
- Widget Bootstrap
- Widget Jquery UI
Helper
- Panoramica
- TBD ArrayHelper
- TBD Html
- TBD Url
- TBD Security
Overview (`docs/guide-ja/README.md`)
Yii 2.0 決定版ガイド
このチュートリアルは Yii ドキュメント許諾条件 の下にリリースされています。
All Rights Reserved.
2014 (c) Yii Software LLC.
導入
始めよう
アプリケーションの構造
リクエストの処理
鍵となる概念
データベースの取り扱い
- データベース・アクセス・オブジェクト: データベースへの接続、基本的なクエリ、トランザクション、および、スキーマ操作
- クエリ・ビルダ: シンプルな抽象レイヤを使ってデータベースに対してクエリを行う
- アクティブ・レコード: アクティブ・レコード ORM、レコードの読み出しと操作、リレーションの定義
- マイグレーション: チーム開発環境においてデータベースにバージョン・コントロールを適用
- Sphinx
- Redis
- MongoDB
- ElasticSearch
ユーザからのデータ取得
データの表示
セキュリティ
キャッシュ
RESTful ウェブ・サービス
開発ツール
テスト
スペシャル・トピック
- アドバンスト・プロジェクト・テンプレート
- アプリケーションを一から構築する
- コンソール・コマンド
- コア・バリデータ
- 国際化
- メール送信
- パフォーマンス・チューニング
- 共有ホスティング環境
- テンプレート・エンジン
- サードパーティのコードを扱う
- Yii をマイクロ・フレームワークとして使う
ウィジェット
- GridView
- ListView
- DetailView
- ActiveForm
- Pjax
- Menu
- LinkPager
- LinkSorter
- Bootstrap ウィジェット
- jQuery UI ウィジェット
ヘルパ
Overview (`docs/guide-pl/README.md`)
Przewodnik po Yii 2.0
Ten poradnik udostępniony jest na Warunkach dokumentacji Yii.
Wszelkie prawa zastrzeżone.
2014 (c) Yii Software LLC.
Wstęp
Pierwsze kroki
- Co musisz wiedzieć
- Instalacja Yii
- Uruchamianie aplikacji
- Witaj świecie
- Praca z formularzami
- Praca z bazami danych
- Generowanie kodu za pomocą Gii
- Dalsze kroki
Struktura aplikacji
- Przegląd
- Skrypty wejściowe
- Aplikacje
- Komponenty aplikacji
- Kontrolery
- Modele
- Widoki
- Moduły
- Filtry
- Widżety
- Zasoby (Assets)
- Rozszerzenia
Obsługa żądań
- Przegląd
- Bootstrapping
- Parsowanie i generowanie adresów URL
- Żądania
- Odpowiedzi
- Sesje i ciasteczka
- Obsługa błędów
- Logowanie
Kluczowe koncepcje
- Komponenty
- Właściwości
- Zdarzenia (Events)
- Zachowania (Behaviors)
- Konfiguracje
- Aliasy
- Autoładowanie klas
- Lokator usług (Service Locator)
- Kontener wstrzykiwania zależności (DI Container)
Praca z bazami danych
- Obiekty dostępu do danych (DAO): Łączenie z bazą, podstawowe zapytania, transakcje i manipulacja schematem.
- Konstruktor kwerend: Zapytania do bazy danych z użyciem warstwy abstrakcyjnej.
- Active Record: Active Record ORM, otrzymywanie i manipulacja rekordami oraz definiowanie relacji.
- Migracje: Użycie systemu kontroli wersji bazy danych do pracy z wieloma środowiskami.
- Sphinx
- Redis
- MongoDB
- ElasticSearch
Odbieranie danych od użytkowników
- Tworzenie formularzy
- Walidacja danych wejściowych
- Wysyłanie plików
- Odczytywanie tablicowych danych wejściowych
- Pobieranie danych dla wielu modeli
- Rozszerzanie ActiveForm po stronie klienta
Wyświetlanie danych
- Formatowanie danych
- Stronicowanie
- Sortowanie
- Dostawcy danych
- Widżety danych
- Praca ze skryptami
- Skórki i motywy (Theming)
Bezpieczeństwo
- Omówienie
- Uwierzytelnianie
- Autoryzacja
- Praca z hasłami
- Kryptografia
- Klienty autoryzacji
- Bezpieczeństwo w praktyce
Pamięć podręczna
- Przegląd
- Pamięć podręczna danych
- Pamięć podręczna fragmentów
- Pamięć podręczna stron
- Pamięć podręczna HTTP
Webserwisy z wykorzystaniem REST
- Szybki start
- Zasoby
- Kontrolery
- Routing
- Formatowanie odpowiedzi
- Uwierzytelnianie
- Limit użycia
- Wersjonowanie
- Obsługa błędów
Narzędzia wspomagające tworzenie aplikacji
Testowanie
- Przegląd
- Konfiguracja środowiska testowego
- Testy jednostkowe
- Testy funkcjonalnościowe
- Testy akceptacyjne
- Fixtures
Tematy specjalne
- Szablon zaawansowanej aplikacji
- Tworzenie aplikacji od podstaw
- Komendy konsolowe
- Wbudowane walidatory
- Docker
- Internacjonalizacja
- Wysyłanie poczty
- Poprawianie wydajności
- Współdzielone środowisko hostingowe
- Silniki szablonów
- Praca z kodem zewnętrznym
- Używanie Yii jako mikroframeworka
Widżety
- GridView
- ListView
- DetailView
- ActiveForm
- Pjax
- Menu
- LinkPager
- LinkSorter
- Widżety Bootstrapowe
- Widżety jQuery UI
Klasy pomocnicze
Uwagi do polskiego tłumaczenia przewodnika
Niektóre z użytych w tym przewodniku programistycznych nazw zostały celowo spolszczone, w przypadku, gdy
w literaturze popularnej nie występują ich polskie odpowiedniki. Mam nadzieję, że czytelnik wybaczy okazjonalne
"settery", "gettery" i "traity", które umieszczamy tutaj licząc na powszechne zrozumienie tych terminów w polskiej
społeczności programistycznej. Jednocześnie spolszczenia/tłumaczenia niektórych terminów, jak "Fixtures", odmawiamy na razie
całkowicie, licząc na to, że język polski w końcu nadgoni lub wchłonie, w ten, czy inny sposób, techniczne nowości.
Overview (`docs/guide-pt-BR/README.md`)
Guia Definitivo para Yii 2.0
Esse tutorial está disponível sob os termos da documentação do Yii.
Todos os Direitos Reservados.
2014 (c) Yii Software LLC.
Introdução
Primeiros Passos
- O que você precisa saber
- Instalando o Yii
- Executando Aplicações
- Dizendo "Olá!"
- Trabalhando com Formulários
- Trabalhando com Bancos de Dados
- Gerando Código com Gii
- Seguindo em Frente
Estrutura da Aplicação
- Visão Geral
- Scripts de Entrada
- Aplicações
- Componentes de Aplicação
- Controladores (Controllers)
- Modelos (Models)
- Visões (Views)
- Módulos
- Filtros
- Widgets
- Assets
- Extensões
Tratando Requisições
- Visão Geral
- Preparação do Ambiente (Bootstrapping)
- Roteamento e Criação de URL
- Requisições
- Respostas
- Sessões e Cookies
- Tratamento de Erros
- Gerenciamento de Logs
Conceitos Chave
- Componentes
- Propriedades
- Eventos
- Comportamentos
- Configurações
- Apelidos (Aliases)
- Carregamento Automático de Classes (Autoloading)
- Service Locator
- Container de Injeção de Dependência
Trabalhando com Banco de Dados
- Objetos de Acesso a Dados - (Database Access Objects): Conectando a um banco de dados, consultas básicas, transações e manipulação de esquema
- Construtor de Consulta (Query Builder): Consultando o banco de dados usando uma camada de abstração simples
- Active Record: Sobre o Active Record ORM, recuperando e manipulando registros e definindo relacionamentos
- Migrações (Migrations): Aplica controle de versão para seus banco de dados em um ambiente de desenvolvimento em equipe
- Sphinx
- Redis
- MongoDB
- ElasticSearch
Coletando Dados de Usuários
- Criando Formulários
- Validando Dados
- Recebendo Arquivos (Upload)
- Coletando Dados Tabulares
- Coletando Dados para Múltiplos Models
- Extendendo o ActiveForm no Client Side
Exibindo Dados
- Formatação de Dados
- Paginação
- Ordenação
- Provedores de Dados (Data Providers)
- Widgets de Dados
- Trabalhando com Client Scripts
- Temas
Segurança
- Visão Geral
- Autenticação
- Autorização
- Trabalhando com Senhas
- Criptografia
- Auth Clients
- Melhores Práticas
Cache
Web Services RESTful
- Introdução
- Recursos
- Controladores (Controllers)
- Roteamento
- Formatação de Respostas
- Autenticação
- Taxa de Limite de Acessos
- Versionamento
- Tratamento de Erros
Ferramentas de Desenvolvimento
- Barra de Ferramentas de Depuração e Depurador
- Gerando Código usando o Gii
- Gerando Documentação da API
Testes
- Visão Geral
- Configuração do ambiente de testes
- Testes Unitários
- Testes Funcionais
- Testes de Aceitação
- Fixtures
Tópicos Especiais
- Template Avançado de Projetos
- Construindo uma Aplicação a Partir do Zero
- Comandos de Console
- Validadores Nativos
- Docker
- Internacionalização
- Envio de E-mails
- Ajustes de Desempenho
- Ambiente de Hospedagem Compartilhada
- Motores de Template (Template Engines)
- Trabalhando com Código de Terceiros
- Usando Yii como um Microframework
Widgets
- GridView
- ListView
- DetailView
- ActiveForm
- Pjax
- Menu
- LinkPager
- LinkSorter
- Widgets Bootstrap
- Widgets jQuery UI
Helpers - Funções Auxiliares
Overview (`docs/guide-ru/README.md`)
Полное руководство по Yii 2.0
Данное руководство выпущено в соответствии с положениями о документации Yii.
All Rights Reserved.
2014 © Yii Software LLC.
Введение
Первое знакомство
- Что нужно знать
- Установка Yii
- Запуск приложения
- Говорим «привет»
- Работа с формами
- Работа с базами данных
- Генерация кода при помощи Gii
- Что дальше?
Структура приложения
- Обзор
- Входные скрипты
- Приложения
- Компоненты приложения
- Контроллеры
- Модели
- Представления
- Модули
- Фильтры
- Виджеты
- Ресурсы
- Расширения
Обработка запросов
- Обзор
- Bootstrapping
- Разбор и генерация URL
- Запросы
- Ответы
- Сессии и куки
- Обработка ошибок
- Логирование
Основные понятия
- Компоненты
- Свойства
- События
- Поведения
- Конфигурации
- Псевдонимы
- Автозагрузка классов
- Service Locator
- Dependency Injection Container
Работа с базами данных
- Объекты доступа к данным (DAO) - Соединение с базой данных, простые запросы, транзакции и работа со схемой.
- Построитель запросов - Запросы к базе данных через простой слой абстракции.
- Active Record - Получение объектов AR, работа с ними и определение связей.
- Миграции - Контроль версий схемы данных при работе в команде.
- Sphinx
- Redis
- MongoDB
- ElasticSearch
Получение данных от пользователя
- Создание форм
- Валидация
- Загрузка файлов
- Табличный ввод
- Работа с несколькими моделями
- Расширение ActiveForm на стороне клиента
Отображение данных
- Форматирование данных
- Постраничная разбивка
- Сортировка
- Провайдеры данных
- Виджеты для данных
- Работа с клиентскими скриптами
- Темизация
Безопасность
Кеширование
Веб-сервисы REST
- Быстрый старт
- Ресурсы
- Контроллеры
- Фильтрация коллекций
- Роутинг
- Форматирование ответа
- Аутентификация
- Ограничение частоты запросов
- Версионирование
- Обработка ошибок
Инструменты разработчика
Тестирование
Специальные темы
- Шаблон приложения advanced
- Создание приложения с нуля
- Консольные команды
- Docker
- Встроенные валидаторы
- Интернационализация
- Отправка почты
- Оптимизация производительности
- Окружение виртуального хостинга
- Шаблонизаторы
- Работа со сторонним кодом
- Использование Yii в качестве микро-framework'а
Виджеты
- GridView
- ListView
- DetailView
- ActiveForm
- Pjax
- Menu
- LinkPager
- LinkSorter
- Виджеты Bootstrap
- Виджеты Jquery UI
Хелперы
Overview (`docs/guide-tr/README.md`)
Yii 2.0 için Açıklayıcı Rehber
Bu döküman, Yii Dökümantasyon Koşulları altında yayınlandı.
Tüm hakları saklıdır.
2014 (c) Yii Software LLC.
Giriş
Başlarken
- Ne bilmeye ihtiyacın var
- Yii Kurulumu
- Uygulamaları Çalıştırmak
- Merhaba deyin
- Formlarla Çalışırken
- Veritabanıyla Çalışırken
- Gii ile Kod Oluşturmak
- İleriye Bakmak
Uygulama Yapısı
- Uygulama Yapısına Genel Bakış
- Giriş Komutları
- Uygulamalar
- Uygulama Bileşenleri
- Kontrolcüler
- Modeller
- Görünümler
- Modüller
- Filtreler
- Araçlar
- Varlıklar
- Uzantılar
İstekleri İşlemek
- İstekleri İşlemeye Genel Bakış
- Bootstrapping
- Yönlendirme ve URL Oluşturma
- İstekler
- Yanıtlar
- Oturumlar ve Çerezler
- Hataları İşleme
- Logging
Anahtar Kavramlar
- Bileşenler
- Özellikler
- Olaylar
- Davranışlar
- Yapılandırmalar
- Takma Adlar
- Sınıf Otomatik Yüklemesi
- Servis Bulucu
- Dependency Injection Container
Veritabanıyla Çalışırken
- Veritabanı Erişim Nesneleri: Bir veritabanına bağlanmak, basit sorgular, işlemler ve şema manipilasyonu
- Sorgu Oluşturucu: Basit bir ayırma katmanı kullanarak veritabanı sorgulama
- Active Record: Active Record ORM, kayıtları almak, değiştirmek ve ilişkileri tanımlama
- Taşıma İşlemleri: Bir takım geliştirme ortamında sürüm kontrolünü veritabanlarına uygula
- Sphinx
- Redis
- MongoDB
- ElasticSearch
Kullanıcılardan Veri Alırken
- Form Oluşturma
- Veri Kontrolü
- Dosya Yükleme
- Collecting Tabular Input
- Birden fazla Model için Veri Alma
- Extending ActiveForm on the Client Side
Veriyi Gösterirken
- Veri Tipini Değiştirme
- Sayfalama
- Sıralama
- Veri Sağlayıcıları
- Veri Araçları
- Scriptlerle Çalışmak
- Tema Kullanımı
Güvenlik
- Güvenliğe Genel Bakış
- Kimlik Denetleme
- Yetkilendirme
- Şifrelerle Çalışma
- Kriptografi
- Auth Clients
- Egzersizler
Cache Almak
- Cache Genel Bakış
- Veriyi Cache Alma
- Sayfanın Sadece Bir Kısmını Cache Alma
- Sayfanın Tamamını Cache Alma
- HTTP Cache Alma
RESTful Web Servisleri
- Hızlı Başlangıç
- Kaynaklar
- Kontrolcüler
- Rota Yöntemleri
- Yanıt Formatlama
- Kimlik Denetleme
- İstek Sınırlama
- Sürümlere Ayırma
- Hataları Kullanma
Geliştirici Araçları
Test
- Testlere Genel Bakış
- Testler için Ortam Kurulumu
- Unit Testleri
- Fonksiyonel Testler
- Kabul Testleri
- Fixtures
Özel Başlıklar
- Gelişmiş Proje Şablonu
- Building Application from Scratch
- Konsol Komutları
- Core Validators
- Docker
- Uluslararası Hale Getirme
- Mail Gönderme
- Performans Ayarları
- Paylaşımlı Sunucu Ortamı
- Şablon Motoru
- 3. Parti Kodlarla Çalışma
- Yii'yi Mikro Kütüphane Gibi Kullanma
Araçlar
- GridView
- ListView
- DetailView
- ActiveForm
- Pjax
- Menu
- LinkPager
- LinkSorter
- Bootstrap Widgets
- jQuery UI Widgets
Yardımcılar
Overview (`docs/guide-uk/README.md`)
Повний посібник з Yii 2.0
Даний посібник випущено відповідно до положень про документацію Yii.
All Rights Reserved.
2014 (c) Yii Software LLC.
Введення
Перше знайомство
- Встановлення Yii
- Виконання додатків
- Говоримо "Привіт"
- Робота з формами
- Робота з базами даних
- Генерування коду за допомогою Gii
- Наступні кроки
Структура додатка
- Огляд
- Вхідні скрипти
- Додатки
- Компоненти додатка
- Контролери
- Моделі
- TBD Представлення
- TBD Модулі
- TBD Фільтри
- TBD Віджети
- TBD Ресурси
- TBD Розширення
Обробка запитів
- TBD Огляд
- TBD Початкове завантаження
- TBD Маршрутизація та створення URL
- TBD Запити
- TBD Відповіді
- TBD Сесії та кукі
- TBD Обробка помилок
- TBD Журналювання
Основні поняття
- TBD Компоненти
- TBD Властивості
- TBD Події
- TBD Поведінки
- TBD Конфігурації
- Псевдоніми
- Автозавантаження класів
- TBD Локатор служб
- TBD Dependency Injection Container
Робота з базами даних
- TBD Обʼєкти доступу до даних (DAO): Зʼєднання з базою даних, прості запити, транзакції і робота зі схемою
- TBD Конструктор запитів: Запити до бази даних через простий шар абстракції
- TBD Active Record: Отримання обʼєктів AR, робота з ними та визначення звʼязків
- TBD Міграції: Контроль версій схеми даних при роботі в команді
- Sphinx
- Redis
- MongoDB
- ElasticSearch
Отримання даних від користувача
- TBD Створення форм
- TBD Перевірка вводу
- TBD Завантаження файлів
- TBD Збір табличного вводу
- TBD Робота з декількома моделями
Відображення даних
- TBD Форматування даних
- TBD Розділення на сторінки
- TBD Сортування
- TBD Провайдери даних
- TBD Віджети даних
- TBD Робота з клієнтськими скриптами
- TBD Темізація
Безпека
- TBD Аутентифікація
- TBD Авторизація
- TBD Робота з паролями
- Клієнти авторизації
- TBD Кращі практики
Кешування
- TBD Огляд
- TBD Кешування даних
- Кешування фрагментів
- TBD Кешування сторінок
- TBD HTTP кешування
Веб-сервіси RESTful
- Швидкий старт
- TBD Ресурси
- TBD Контролери
- TBD Маршрутизація
- TBD Форматування відповіді
- TBD Аутентифікація
- Обмеження частоти запитів
- TBD Версіонування
- TBD Обробка помилок
Інструменти розробника
- Панель налагодження та налагоджувач
- Генерування коду за допомогою Gii
- TBD Генерування документації API
Тестування
- TBD Огляд
- TBD Налаштування середовища тестування
- TBD Модульні тести
- TBD Функціональні тести
- TBD Приймальні тести
- TBD Фікстури
Спеціальні теми
- TBD Розширений шаблон проекту
- Створення додатка з нуля
- Консольні додатки
- TBD Основні валідатори
- TBD Інтернаціоналізація
- TBD Робота з поштою
- TBD Покращення швидкодії
- TBD Робота на віртуальному хостингу
- Шаблонізатори
- Робота із стороннім кодом
Віджети
- GridView: TBD link to demo page
- ListView: TBD link to demo page
- DetailView: TBD link to demo page
- ActiveForm: TBD link to demo page
- Pjax: TBD link to demo page
- Menu: TBD link to demo page
- LinkPager: TBD link to demo page
- LinkSorter: TBD link to demo page
- Віджети Bootstrap
- Віджети jQuery UI
Хелпери
- TBD Огляд хелперів
- TBD ArrayHelper
- TBD Html
- TBD Url
Overview (`docs/guide-uz/README.md`)
Yii 2.0 bo'yicha to'liq qo'llanma
Ushbu qo'llanma Yii qo'llanmalarining holati bilan mos holda yo'lga qo'yildi.
All Rights Reserved.
2014 © Yii Software LLC.
Kirish
Birinchi tanishuv
- Yii ni o'rnatish
- Ilovani ishga tushirish
- «Salom» deymiz
- Formalar bilan ishlash
- Ma'lumotlar ombori bilan ishlash
- Gii yordamida kodlarni generatsiya qilish
- Keyin nima?
Ilova strukturasi
- Sharh
- Kirish skriptlari
- Ilova
- Ilova komponentlari
- Kontrollyorlar
- Namoyish
- Modellar
- TBD Filtrlar
- TBD Vidjetlar
- TBD Modullar
- Resurslar
- TBD Kengaytmalar
So'rovlarni qayta ishlash
- TBD Bootstrapping
- TBD Routing
- TBD So'rovlar
- TBD Javoblar
- TBD Sessiyalar va kuklar
- URL ni tahlil va generatsiya qilish
- Xatoliklarni qayta ishlash
- Jurnallarga yozish
Asosiy tushunchalar
- Komponentlar
- Xususiyat
- Xodisa
- O'zini tutish
- Muhim sozlashlar
- Taxalluslar
- Sinflarni avtoyuklash
- Service Locator
- Dependency Injection Container
Ma'lumotlar ombori bilan ishlash
- Ma'lumotlar bilan ishlashga imkon beruvchi obektlar(DAO) - Ma'lumotlar ombori bilan bog'lanish, oddiy so'rovlar, tranzaksiya va sxema bilan ishlash.
- So'rovlarni yaratuvchi - Ma'lumotlar omboriga abstraksiyaning oddiy qatlamidan so'rovlar.
- Active Record - AR obektlarini olish, ular bilan ishlash va bog'lanishlarni aniqlash.
- Migratsiyalar - Komandada (jamoada) ishlaganda ma'lumotlar sxemasini talqinlarini boshqarish.
- TBD Sphinx
- TBD Redis
- TBD MongoDB
- TBD ElasticSearch
Foydalanuvchidan ma'lumotlarni qabul qilish
Ma'lumotlarni namoyish etish
- TBD Ma'lumotlarni formatlash
- TBD Sahifalar bo'yicha ajratish
- TBD Saralash
- Ma'lumotlar provayderlari
- Ma'lumotlar uchun vidjetlar
- Mavzulashtirish
Xavfsizlik
- Autentifikatsiya
- Avtorizatsiya
- Parollar bilan ishlash
- TBD Avtorizatsiya mijozlari
- TBD Eng yaxshi amaliyotlar
Keshlash
REST web-xizmatlari
- Tezkor boshlash
- Resurslar
- Kontrollyorlar
- Routing
- Javoblarni formatlash
- Autentifikatsiya
- So'rovlarni chastotasini chegaralash
- Talqin yaratish
- Xatoliklarni qayta ishlash
Ishlab chiquvchining uskunalari
- Qayta ishlash paneli va qayta ishlovchi
- Gii bilan kodni generatsiya qilish
- TBD API qo'llanmani generatori
Test o'tkazish
Yii kengaytmalari
- Kengaytmani yaratish
- Freymvork kodini kengaytirish
- Tashqi kutubxonalarni qo'llash
- TBD Tashqi tizimlarda Yii integratsiyasi
- TBD Yii 1.1 va 2.0 larni bir vaqtda ishlatish
- Composer ni ishlatish
Maxsus mavzular
- advanced ilova shabloni
- Ilovani noldan yaratish
- Konsol komandalari
- Xalqarolashtirish
- Pochta yuborish
- Ish inumdorligini oshirish
- TBD shared xostingida ishlash
- Shablonlashtiruvchilar
Vidjetlar
- GridView: link to demo page
- ListView: link to demo page
- DetailView: link to demo page
- ActiveForm: link to demo page
- Pjax: link to demo page
- Menu: link to demo page
- LinkPager: link to demo page
- LinkSorter: link to demo page
- Bootstrap vidjetlari
- TBD Jquery UI vidjetlari
Xelperlar
- Sharh
- TBD ArrayHelper
- TBD Html
- TBD Url
- TBD Security
Overview (`docs/guide-vi/README.md`)
The Definitive Guide to Yii 2.0
Các hướng dẫn được phát hành theo Các điều khoản về tài liệu Yii.
Tất cả bản quyền đã được bảo hộ (All Rights Reserved).
2014 (c) Yii Software LLC.
Giới thiệu
Bắt đầu
- Những gì bạn cần biết
- Cài đặt Yii
- Thực hiện chạy ứng dụng
- Viết chương trình đầu tiên
- Làm việc với Forms
- Làm việc với Databases
- Sử dụng Gii để sinh mã tự động
- Nâng cao
Kiến trúc ứng dụng (Application Structure)
- Tổng quan về kiến trúc ứng dụng
- Mục Scripts
- Ứng dụng (Applications)
- Các thành phần bên trong ứng dụng
- Controllers
- Models
- Views
- Modules
- Bộ lọc (Filters)
- Widgets
- Assets
- Phần mở rộng (Extensions)
Xử lý yêu cầu (Handling Requests)
- Tổng quan
- Khởi động
- Định tuyến (Routing) và khởi tạo đường dẫn (URL Creation)
- Yêu cầu (Requests)
- Kết quả (Responses)
- Sessions và Cookies
- Xử lý lỗi (Handling Error)
- Logging
Các khái niệm chính
- Thành phần (Components)
- Thuộc tính (Properties)
- Sự kiện (Events)
- Hành vi (Behaviors)
- Cấu hình (Configurations)
- Bí danh (Aliases)
- Lớp tự động nạp (Autoloading)
- Service Locator
- Dependency Injection Container
Làm việc với Databases
- Data Access Objects: Kết nối cơ sở dữ liệu, truy vấn cơ bản, giao dịch và phương thức hoạt động
- Query Builder: Sử dụng một truy vấn đơn giản, các lớp cơ sở dữ liệu trừu tượng
- Active Record: The Active Record ORM, truy vấn và thao tác với dữ liệu, định nghĩa các mối quan hệ giữa các bảng
- Migrations: Cung cấp cho đội dự án một công cụ dễ dàng trong việc quản lý những schema CSDL trong ứng dụng
- Sphinx
- Redis
- MongoDB
- ElasticSearch
Nhận dữ liệu từ user
- Tạo mới Forms
- Kiểm tra dữ liệu đầu vào (Validating Input)
- File Upload
- Thu thập dữ liệu từ danh sách đầu vào (Đang phát triển)
- Lấy dữ liệu cho nhiều Models (Chưa giải quyết)
- Mở rộng ActiveForm ở phía Máy khách
Hiển thị dữ liệu
- Định dạng dữ liệu (Data Formatting)
- Phân trang (Pagination)
- Sắp xếp (Sorting)
- Cung cấp dữ liệu ra (Data Providers)
- Dữ liệu Widgets
- làm việc với Client Scripts
- Giao diện (Theming)
Bảo mật (Security)
- Xác thực (Authentication)
- Quyền (Authorization)
- Các thao tác xử lý với Passwords (Đang phát triển)
- Auth Clients
- Best Practices
Bộ nhớ Cache
RESTful Web Services
- Bắt đầu
- Tài nguyên (Resources)
- Bộ điều khiển (Controllers)
- Routing
- Định dạng thông điệp gửi đi (Response Formatting)
- Xác thực (Authentication)
- Rate Limiting
- Phiên bản (Version)
- Error Handling
Công cụ phát triển (Development Tools)
- Thanh công cụ gỡ lỗi và sửa lỗi (Debug Toolbar và Debugger)
- Sử dụng Gii để tạo code
- Tạo tài liệu về API
Testing
- Tổng quan
- Thiết lập môi trường
- Unit Tests
- Kiểm tra chức năng (Functional Tests)
- Acceptance Tests
- Fixtures
Chủ đề năng cao
- Advanced Application Template
- Building Application from Scratch
- Giao diện dòng lệnh (Console Commands)
- Core Validators
- Quốc tế hóa (Internationalization)
- Thư (Mailing)
- Tối ưu hiệu năng ứng dụng (Performance Tuning)
- Shared Hosting Environment
- Template Engines
- Tích hợp mã nguồn của bên thứ ba (Working with Third-Party Code)
- Dùng Yii như các framework nhỏ
Widgets
- GridView
- ListView
- DetailView
- ActiveForm
- Pjax
- Menu
- LinkPager
- LinkSorter
- Bootstrap Widgets
- jQuery UI Widgets
Helpers
Overview (`docs/guide-zh-CN/README.md`)
Yii 2.0 权威指南
本教程的发布遵循 Yii 文档使用许可。
版权所有。
2014 (c) Yii Software LLC。
介绍(Introduction)
入门(Getting Started)
- 你需要了解什么(What do you need to know)
- 安装 Yii(Installing Yii)
- 运行应用(Running Applications)
- 第一次问候(Saying Hello)
- 使用 Forms(Working with Forms)
- 玩转 Databases(Working with Databases)
- 用 Gii 生成代码(Generating Code with Gii)
- 更上一层楼(Looking Ahead)
应用结构(Application Structure)
- 结构概述(Overview)
- 入口脚本(Entry Scripts)
- 应用(Applications)
- 应用组件(Application Components)
- 控制器(Controllers)
- 模型(Models)
- 视图(Views)
- 模块(Modules)
- 过滤器(Filters)
- 小部件(Widgets)
- 前端资源(Assets)
- 扩展(Extensions)
请求处理(Handling Requests)
- 运行概述(Overview)
- 引导(Bootstrapping)
- 路由引导与创建 URL(Routing and URL Creation)
- 请求(Requests)
- 响应(Responses)
- Sessions and Cookies
- 错误处理(Handling Errors)
- 日志(Logging)
关键概念(Key Concepts)
- 组件(Components)
- 属性(Properties)
- 事件(Events)
- 行为(Behaviors)
- 配置(Configurations)
- 别名(Aliases)
- 类自动加载(Class Autoloading)
- 服务定位器(Service Locator)
- 依赖注入容器(Dependency Injection Container)
配合数据库工作(Working with Databases)
- 数据库访问(Data Access Objects): 数据库连接、基本查询、事务和模式操作
- 查询生成器(Query Builder): 使用简单抽象层查询数据库
- 活动记录(Active Record): 活动记录对象关系映射(ORM),检索和操作记录、定义关联关系
- 数据库迁移(Migrations): 在团体开发中对你的数据库使用版本控制
- Sphinx
- Redis(yii2-redis): yii2-redis 扩展详解
- MongoDB
- ElasticSearch
接收用户数据(Getting Data from Users)
- 创建表单(Creating Forms)
- 输入验证(Validating Input)
- 文件上传(Uploading Files)
- 收集列表输入(Collecting Tabular Input)
- 多模型同时输入(Getting Data for Multiple Models)
- 在客户端扩展 ActiveForm(Extending ActiveForm on the Client Side)
显示数据(Displaying Data)
- 格式化输出数据(Data Formatting)
- 分页(Pagination)
- 排序(Sorting)
- 数据提供器(Data Providers)
- 数据小部件(Data Widgets)
- 操作客户端脚本(Working with Client Scripts)
- 主题(Theming)
安全(Security)
- 概述(Overview)
- 认证(Authentication)
- 授权(Authorization)
- 处理密码(Working with Passwords)
- 加密(Cryptography)
- 客户端认证(Auth Clients)
- 安全领域的最佳实践(Best Practices)
缓存(Caching)
RESTful Web 服务(RESTful Web Services)
- 快速入门(Quick Start)
- 资源(Resources)
- 控制器(Controllers)
- 路由(Routing)
- 格式化响应(Response Formatting)
- 授权验证(Authentication)
- 速率限制(Rate Limiting)
- 版本化(Versioning)
- 错误处理(Error Handling)
开发工具(Development Tools)
- 调试工具栏和调试器(Debug Toolbar and Debugger)
- 使用 Gii 生成代码(Generating Code using Gii)
- 生成 API 文档(Generating API Documentation)
测试(Testing)
- 概述(Overview)
- 搭建测试环境(Testing environment setup)
- 单元测试(Unit Tests)
- 功能测试(Functional Tests)
- 验收测试(Acceptance Tests)
- 测试夹具(Fixtures)
高级专题(Special Topics)
- 高级应用模版(Advanced Project Template)
- 从头构建自定义模版(Building Application from Scratch)
- 控制台命令(Console Commands)
- 核心验证器(Core Validators)
- Docker
- 国际化(Internationalization)
- 收发邮件(Mailing)
- 性能优化(Performance Tuning)
- 共享主机环境(Shared Hosting Environment)
- 模板引擎(Template Engines)
- 集成第三方代码(Working with Third-Party Code)
- 使用 Yii 作为微框架(Using Yii as a micro framework)
小部件(Widgets)
- GridView
- ListView
- DetailView
- ActiveForm
- Pjax
- Menu
- LinkPager
- LinkSorter
- Bootstrap Widgets
- jQuery UI Widgets
助手类(Helpers)
Overview (`docs/guide/README.md`)
The Definitive Guide to Yii 2.0
This tutorial is released under the Terms of Yii Documentation.
All Rights Reserved.
2014 (c) Yii Software LLC.
Introduction
Getting Started
- What do you need to know
- Installing Yii
- Running Applications
- Saying Hello
- Working with Forms
- Working with Databases
- Generating Code with Gii
- Looking Ahead
Application Structure
- Application Structure Overview
- Entry Scripts
- Applications
- Application Components
- Controllers
- Models
- Views
- Modules
- Filters
- Widgets
- Assets
- Extensions
Handling Requests
- Request Handling Overview
- Bootstrapping
- Routing and URL Creation
- Requests
- Responses
- Sessions and Cookies
- Handling Errors
- Logging
Key Concepts
- Components
- Properties
- Events
- Behaviors
- Configurations
- Aliases
- Class Autoloading
- Service Locator
- Dependency Injection Container
Working with Databases
- Database Access Objects: Connecting to a database, basic queries, transactions, and schema manipulation
- Query Builder: Querying the database using a simple abstraction layer
- Active Record: The Active Record ORM, retrieving and manipulating records, and defining relations
- Migrations: Apply version control to your databases in a team development environment
- Sphinx
- Redis
- MongoDB
- ElasticSearch
Getting Data from Users
- Creating Forms
- Validating Input
- Uploading Files
- Collecting Tabular Input
- Getting Data for Multiple Models
- Extending ActiveForm on the Client Side
Displaying Data
Security
- Security Overview
- Authentication
- Authorization
- Working with Passwords
- Cryptography
- Auth Clients
- Best Practices
Caching
RESTful Web Services
- Quick Start
- Resources
- Controllers
- Filtering Collections
- Routing
- Response Formatting
- Authentication
- Rate Limiting
- Versioning
- Error Handling
Development Tools
Testing
Special Topics
- Advanced Project Template
- Building Application from Scratch
- Console Commands
- Core Validators
- Docker
- Internationalization
- Mailing
- Performance Tuning
- Shared Hosting Environment
- Template Engines
- Working with Third-Party Code
- Using Yii as a micro framework
Widgets
- GridView
- ListView
- DetailView
- ActiveForm
- Pjax
- Menu
- LinkPager
- LinkSorter
- Bootstrap Widgets
- jQuery UI Widgets
Helpers
Overview (`docs/internals-ja/README.md`)
Yii 開発者ドキュメント
このディレクトリは、Yii フレームワークの開発とリリース・プロセスに関するドキュメントを含んでいます。
寄稿者のためのガイドライン
- 課題を報告する仕方
- 始めよう
- Yii 2 寄稿者のための Git ワークフロー - 開発環境をセットアップして Yii に対する寄稿を始めるためのステップ・バイ・ステップのガイド。
- Yii 2 コア・フレームワーク・コード・スタイル
- Yii 2 ビュー・コード・スタイル
ドキュメント
フレームワーク開発
- プル・リクエストの品質保証
- 自動化されるタスク コード・スタイルの修正、ドキュメントやファイルの自動生成など。
- 設計上の決定 - よく議論される事柄についての FAQ 形式の声明リスト。
バージョニングとリリース
その他
例外の階層
データベースのテスト
こちら に、Yii がサポートする全てのデータベースのためのテスト環境構成があります。
Overview (`docs/internals-pl/README.md`)
Dokumentacja dewelopera Yii
Ten folder zawiera dokumentację dotyczącą procesu rozwoju i powstawania nowych wydań frameworka Yii.
Wskazówki dla kontrybutorów
- W jaki sposób zgłaszać problemy
- Od czego zacząć
- Cykl produkcji Git dla kontrybutorów Yii 2 - przewodnik krok po kroku jak utworzyć środowisko deweloperskie i współtworzyć Yii.
- Styl kodowania bazowych plików frameworka Yii 2
- Styl kodowania widoków Yii 2
Dokumentacja
- Status tłumaczeń - które z dokumentów są gotowe do przetłumaczenia.
- Ekipy tłumaczące
- Cykl tworzenia tłumaczenia
Rozwój frameworka
- Zapewnienie jakości kodu w prośbie o połączenie
- Zadania zautomatyzowane, takie jak poprawki stylu kodu, automatyczne tworzenie dokumentacji i generowanie plików.
- Decyzje projektowe - lista pytań i odpowiedzi dotyczących często rozważanych zagadnień.
Wersjonowanie i wydania
Inne zagadnienia
Hierarchia wyjątków
Overview (`docs/internals-ru/README.md`)
Документация для разработчиков Yii
В этой директории собрана документация по разработке Yii Framework и процессу выпуска релизов.
Руководство контрибьютора
- Как сообщить о проблеме
- С чего начать
- Git-процесс для контрибьюторов Yii 2 - пошаговое руководство: настройка окружения и начало работы над Yii.
- Стиль кода ядра Yii 2
- Стиль кода представлений Yii 2
Документация
- Статус переводов - какие документы готовы к переводу.
- Команды переводчиков
- Процесс перевода
Разработка фреймворка
- Контроль качества pull request
- Автоматизация - автоисправление стиля кода, генерация документации и файлов.
- Проектные решения - FAQ по спорным вопросам, которые закрыты решением core team.
Версионирование и релизы
Разное
Иерархия исключений
Тестирование баз данных
Здесь находится конфигурация тестовых окружений для всех поддерживаемых Yii баз данных.
Overview (`docs/internals/README.md`)
Yii Developer Documentation
This directory contains documentation about Yii Framework development and release process.
Contributor Guidelines
- How to Report an Issue
- Getting started
- Git workflow for Yii 2 contributors - a step by step guide on how to set up your dev environment and start contributing to Yii.
- Yii 2 Core Framework Code Style
- Yii 2 View Code Style
Documentation
- Translation Status - which documents are ready for translation.
- Translation teams
- Translation workflow
Framework Development
- Pull request quality assurance
- Automated Tasks, like code style fixes, automatic documentation and file generation.
- Design Decisions - a FAQ-like list of statements about commonly debated things.
Versioning and Release
Misc
Exception Hierarchy
Database testing
Here is config for test environments for all supported Yii databases.
Guide Es Caching Overview (`docs/guide-es/caching-overview.md`)
El Almacenamiento en Caché
El almacenamiento en caché es una forma económica y eficaz para mejorar el rendimiento de una aplicación web. Mediante
el almacenamiento de datos relativamente estáticos en la memoria caché y su correspondiente recuperación cuando éstos sean
solicidatos, la aplicación salvaría todo ese tiempo y recursos necesarios para volver a generarlos cada vez desde cero.
El almacenamiento en caché se puede usar en diferentes niveles y lugares en una aplicación web. En el lado del servidor, al más bajo nivel,
la caché puede ser usada para almacenar datos básicos, tales como una una lista de los artículos más recientes obtenidos de una base de datos;
y en el más alto nivel, la caché puede ser usada para almacenar fragmentos o la totalidad de las páginas web, tales como el resultado del renderizado de los artículos más recientes. En el lado del cliente, el almacenamiento en caché HTTP puede ser utilizado para mantener
el contenido de la página que ha sido visitada más recientemente en el caché del navegador.
Yii soporta los siguientes mecanismos de almacenamiento de caché:
Guide Es Helper Overview (`docs/guide-es/helper-overview.md`)
Helpers
Note: Esta sección está en desarrollo.
Yii ofrece muchas clases que ayudan a simplificar las tareas comunes de codificación, como manipulación de string o array,
generación de código HTML, y más. Estas clases helper están organizadas bajo el namespace yii\helpers y
son todo clases estáticas (lo que significa que sólo contienen propiedades y métodos estáticos y no deben ser instanciadas).
Puedes usar una clase helper directamente llamando a uno de sus métodos estáticos, como a continuación:
use yii\helpers\Html;
echo Html::encode('Test > test');Note: Para soportar la personalización de clases helper, Yii separa cada clase helper del núcleo
en dos clases: una clase base (ej.BaseArrayHelper) y una clase concreta (ej.ArrayHelper).
Cuando uses un helper, deberías sólo usar la versión concreta y nunca usar la clase base.
Clases Helper del núcleo
Las siguientes clases helper del núcleo son proporcionadas en los releases de Yii:
- ArrayHelper
- Console
- FileHelper
- Html
- HtmlPurifier
- Image
- Inflector
- Json
- Markdown
- Security
- StringHelper
- Url
- VarDumper
Personalizando Las Clases Helper
Para personalizar una clase helper del núcleo (ej. [[yii\helpers\ArrayHelper]]), deberías crear una nueva clase extendiendo
de los helpers correspondientes a la clase base (ej. [[yii\helpers\BaseArrayHelper]]), incluyendo su namespace. Esta clase
será creada para remplazar la implementación original del framework.
El siguiente ejemplo muestra como personalizar el método [[yii\helpers\ArrayHelper::merge()|merge()]] de la clase
[[yii\helpers\ArrayHelper]]:
<?php
namespace yii\helpers;
class ArrayHelper extends BaseArrayHelper
{
public static function merge($a, $b)
{
// tu implementación personalizada
}
}Guarda tu clase en un fichero nombrado ArrayHelper.php. El fichero puede estar en cualquier directorio, por ejemplo @app/components.
A continuación, en tu script de entrada de la aplicación, añade las siguientes lineas de código
después de incluir el fichero yii.php para decirle a la clase autoloader de Yii que cargue tu
clase personalizada en vez de la clase helper original del framework:
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';Nota que la personalización de clases helper sólo es útil si quieres cambiar el comportamiento de una función
existente de los helpers. Si quieres añadir funciones adicionales para usar en tu aplicación puedes mejor crear un helper
por separado para eso.
Guide Es Runtime Overview (`docs/guide-es/runtime-overview.md`)
Información General
Cada vez que una aplicación Yii gestiona una petición, se somete a un flujo de trabajo similar.
- Un usuario hace una petición al script de entrada ‘web/index.php’.
- El script de entrada carga la configuración y crea una instancia de la
aplicación para gestionar la petición. - La aplicación resuelve la ruta solicitada con la ayuda del componente
petición de la aplicación. - La aplicación crea una instancia del controlador para gestionar la petición.
- El controlador crea una instancia de la acción y ejecuta los filtros para la acción.
- Si algún filtro falla, se cancela la acción.
- Si pasa todos los filtros, se ejecuta la acción.
- La acción carga un modelo de datos, posiblemente de la base de datos.
- La acción renderiza una vista, proporcionándole el modelo de datos.
- El resultado renderizado se devuelve al componente respuesta de la aplicación.
- El componente respuesta envía el resultado renderizado al navegador del usuario.
El siguiente diagrama muestra como una aplicación gestiona una petición.
En esta sección, se describirá en detalle cómo funcionan algunos de estos pasos.
Guide Es Structure Overview (`docs/guide-es/structure-overview.md`)
Información general
Las aplicaciones realizadas con Yii están organizadas de acuerdo al patrón de diseño modelo-vista-controlador (MVC). Los
modelos representan datos, la lógica de negocios y sus reglas; las vistas
son la representación de salida de los modelos; y finalmente, los controladores que toman datos de entrada y los convierten en instrucciones para los modelos y vistas.
Además de MVC, las aplicaciones Yii también tienen las siguientes entidades:
- scripts de entrada: Existen scripts PHP directamente accesibles a los usuarios finales.
Son los responsables de comenzar el ciclo de manejo de una solicitud. - aplicaciones: Son objetos accesibles globalmente que gestionan y coordinan los componentes
de la aplicación con el fin de atender las diferentes solicitudes. - componentes de la aplicación: Son los objetos registrados con la aplicación, y
proporcionan varios servicios para cumplir las solicitudes. - módulos: Son paquetes auto-contenidos los cuales por si solos poseen estructura MVC.
Una aplicación puede estar organizada en términos de múltiples módulos. - filtros: Representan el código que debe ser invocado antes y despues de la ejecución de cada
solicitud por los controladores. - widgets: Son objetos que pueden ser embebidos en las Vistas. Pueden
contener lógica del controlador y ser reutilizados en múltiples vistas.
El siguiente esquema muestra la estructura estática de una aplicación:
Guide Es Test Overview (`docs/guide-es/test-overview.md`)
Tests
Las pruebas son una parte importante del desarrollo de software. Seamos conscientes
de ello o no, ralizamos pruebas contínuamente.
Por ejemplo, cuando escribimos una clase en PHP, podemos depurarla paso a paso o
simplemente usar declaraciones echo o die para verificar que la implementación
funciona conforme a nuestro plan inicial. En el caso de una aplicación web, introducimos
algunos datos de prueba en los formularios para asegurarnos de que la página interactúa
con nosotros como esperábamos.
El proceso de testeo se puede automatizar para que cada vez que necesitemos verificar
algo, solamente necesitemos invocar el código que lo hace por nosotros. El código que
verifica que el restulado coincide con lo que habíamos planeado se llama test y el proceso
de su creación y posterior ejecución es conocido como testeo automatizado, que es el
principal tema de estos capítulos sobre testeo.
Desarrollo con tests
El Desarrollo Dirigido por Pruebas (Test-Driven Development o TDD) y el Desarrollo
Dirigido por Corpotamientos (Behavior-Driven Development o BDD) son enfoques para
desarrollar software, en los que se describe el comportamiento de un trozo de código
o de toda la funcionalidad como un conjunto de escenarios o pruebas antes de escribir
el código real y sólo entonces crear la implementación que permite pasar esos tests
verificando que se ha logrado el comportamiento pretendido.
El proceso de desarrollo de una funcionalidad es el siguiente:
- Crear un nuevo test que describe una funcionalidad a implementar.
- Ejecutar el nuevo test y asegurarse de que falla. Esto es lo esperado, dado que todavía no hay ninguna implementación.
- Escribir un código sencillo para superar el nuevo test.
- Ejecutar todos los tests y asegurarse de que se pasan todos.
- Mejorar el código y asegurarse de que los tests siguen superándose.
Una vez hecho, se repite el proceso de neuvo para otra funcionalidad o mejora.
Si se va a cambiar la funcionalidad existente, también hay que cambiar los tests.
Tip: Si siente que está perdiendo tiempo haciendo un montón de iteraciones pequeñas
y simples, intente cubrir más por cada escenario de test, de modo que haga más cosas antes
de ejecutar los tests de nuevo. Si está depurando demasiado, intente hacer lo contrario.
La razón para crear los tests antes de hacer ninguna implementación es que eso nos permite
centrarnos en lo que queremos alcanzar y sumergirnos totalmente en «cómo hacerlo» después.
Normalmente conduce a mejores abstracciones y a un más fácil mantenimiento de los tests
cuando toque hacer ajustes a las funcionalidades o componentes menos acoplados.
Para resumir, las ventajas de este enfoque son las siguientes:
- Le mantiene centrado en una sola cosa en cada momento, lo que resulta en una mejor planificación e implementación.
- Resulta en más funcionalidades cubiertas por tests, y en mayor detalle. Es decir, si se superan los tests, lo más problable es que no haya nada roto.
A largo plazo normalmente tiene como efecto un buen ahorro de tiempo.
Qué y cómo probar
Aunque el enfoque de primero los tests descrito arriba tiene sentido para el largo plazo
y proyectos relativamente complejos, sería excesivo para proyectos más simples.
Hay algunas indicaciones de cuándo es apropiado:
- El proyecto ya es grande y complejo.
- Los requisitos del proyecto están empezando a hacerse complejos. El proyecto crece constantemente.
- El proyecto pretende a ser a largo plazo.
- El coste de fallar es demasiado alto.
No hay nada malo en crear tests que cubran el comportamiento de una implementación existente.
- Es un proyecto legado que se va a renovar gradualmente.
- Le han dado un proyecto sobre el que trabajar y no tiene tests.
En algunos casos cualquier forma de testo automatizado sería exagerada:
- El proyecto es sencillo y no se va a volver más complejo.
- Es un proyecto puntual en el que no se seguirá trabajando.
De todas formas, si dispone de tiempo, es bueno automatizar las pruebas también en esos casos.
Más lecturas
- Test Driven Development: By Example / Kent Beck. ISBN: 0321146530.
Guide Fr Caching Overview (`docs/guide-fr/caching-overview.md`)
Mise en cache
La mise en cache est un moyen peu coûteux et efficace d'améliorer la performance d'une application Web. En stockant des données relativement statiques en cache et en les servant à partir de ce cache lorsqu'elles sont demandées, l'application économise le temps qu'il aurait fallu pour générer ces données à partir de rien à chaque demande.
La mise en cache se produit à différents endroits et à différents niveaux dans une application Web. Du côté du serveur, au niveau le plus bas, le cache peut être utilisé pour stocker des données de base, telles qu'une liste des informations sur des articles recherchée dans une base de données ; et à un niveau plus élevé, il peut être utilisé pour stocker des fragments ou l'intégralité de pages Web, telles que le rendu des articles les plus récents.
Du côté client, la mise en cache HTTP peut être utilisée pour conserver le contenu des pages visitées les plus récentes dans le cache du navigateur.
Yii prend en charge tous ces mécanismes de mise en cache :
Guide Fr Helper Overview (`docs/guide-fr/helper-overview.md`)
Classes assistantes
Note: cette section est en cours de développement.
Yii procure de nombreuses classes qui vous aident à simplifier le code de tâches courantes, telles que la manipulation de chaînes de caractères ou de tableaux, la génération de code HTML, et ainsi de suite. Ces classes assistantes sont organisées dans l'espace de noms yii\helpers et sont toutes des classes statiques (ce qui signifie qu'elles ne contiennent que des propriétés et des méthodes statiques et ne doivent jamais être instanciées).
Vous utilisez une classe assistante en appelant directement une de ses méthodes statiques, comme ceci :
use yii\helpers\Html;
echo Html::encode('Test > test');Note: pour prendre en charge la personnalisation des classes assistantes, Yii éclate chacune des classes assistantes du noyau en deux classes : une classe de base (p. ex.
BaseArrayHelper) et une classe concrète (p. ex.ArrayHelper). Lorsque vous utilisez une classe assistante, vous devez utiliser la version concrète uniquement et ne jamais utiliser la classe de base.
Classes assistantes du noyau
Les versions de Yii fournissent les classes assistantes du noyau suivantes :
- ArrayHelper
- Console
- FileHelper
- FormatConverter
- Html
- HtmlPurifier
- Imagine (provided by yii2-imagine extension)
- Inflector
- Json
- Markdown
- StringHelper
- Url
- VarDumper
Personnalisation des classes assistantes
Pour personnaliser une classe assistante du noyau (p. ex. [[yii\helpers\ArrayHelper]]), vous devez créer une nouvelle classe qui étend la classe de base correspondant à la classe assistante (p. ex. [[yii\helpers\ArrayHelper]]), y compris son espace de noms. Cette classe sera ensuite configurée pour remplacer l'implémentation originale de Yii.
L'exemple qui suit montre comment personnaliser la méthode [[yii\helpers\ArrayHelper::merge()|merge()]] de la classe [[yii\helpers\ArrayHelper]] :
<?php
namespace yii\helpers;
class ArrayHelper extends BaseArrayHelper
{
public static function merge($a, $b)
{
// votre implémentation personnalisée
}
}Sauvegardez votre classe dans un fichier nommé ArrayHelper.php. Le fichier peut se trouver dans n'importe quel dossier, par exemple, @app/components.
Ensuite, dans le script d'entrée de votre application, ajoutez la ligne de code suivante, après l'inclusion du fichier yii.php pour dire à la classe autoloader de Yii de charger votre classe personnalisée au lieu de la classe assistance originale de Yii.
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';Notez que la personnalisation d'une classe assistante n'est utile que si vous désirez changer le comportement d'une fonction existante de la classe assistante. Si vous désirez ajouter une fonction additionnelle à utiliser dans votre application, le mieux est de créer une classe assistante séparée pour cela.
Guide Fr Runtime Overview (`docs/guide-fr/runtime-overview.md`)
Vue d'ensemble
À chaque fois qu'une application Yii prend en charge une requête, elle entreprend un flux de travail similaire.
- Un utilisateur effectue une requête auprès du script d'entrée
web/index.php. - Le script d'entrée charge la configuration de l'application et crée une instance d'application pour prendre en charge la requête.
- L'application résoud la route requise avec l'aide du composant d'application request.
- L'application crée une instance de contrôleur pour prendre en charge le requête.
- Le contrôleur crée une instance d'action et exécute les filtres de l'action.
- Si un filtre échoue, l'exécution de l'action est annulée.
- Si tous les filtres réussissent l'action est exécutée.
- L'action charge un modèle de données, possiblement à partir d'une base de données.
- L'action rend une vue, en lui passant le modèle de données.
- Le résultat rendu est retourné au composant d'application response.
- Le composant response envoye le résultat rendu au navigateur de l'utilisateur.
Le diagramme ci-dessous illustre comment une application prend une requête en charge.
Dans cette section, nous décrivons en détails comment se déroulent quelques unes de ces étapes.
Guide Fr Security Overview (`docs/guide-fr/security-overview.md`)
Sécurité
Une bonne sécurité est vitale pour la santé et le succès de toute application. Malheureusement, beaucoup de développeurs lésinent un peu quand ils en arrivent à la sécurité, soit par manque de compréhension ou parce que sa mise en œuvre n'est pas une mince affaire. Pour rendre votre application Yii aussi sûre que possible, Yii inclut plusieurs fonctionnalités de sécurité, excellentes et faciles à mettre en œuvre.
- L'authentification
- L'autorisation
- Le travail avec des mots de passe
- La cryptographie
- La sécurité des vues
- L'extension Auth Clients
- Les bonnes pratiques
Guide Fr Structure Overview (`docs/guide-fr/structure-overview.md`)
Vue d'ensemble
Les applications Yii sont organisées suivant le modèle de conception
model-view-controller (MVC). Les Modèles
représentent les données, la logique métier et les règles; les vues sont les représentations
visuelles des modèles, et les contrôleurs prennent une entrée et la convertissent en
commandes pour les modèles et les vues.
En plus du MVC, les applications Yii ont les entités suivantes :
- scripts d'entrée: ce sont des scripts PHP qui sont directement accessibles aux
utilisateurs. Ils sont responsables de l'amorçage d'un cycle de gestion de requête. - applications: ce sont des objets globalement accessibles qui gèrent les composants
d'application et les coordonnent pour satisfaire des requêtes. - composants d'application: ce sont des objets enregistrés avec des applications et
qui fournissent différents services pour satisfaire des requêtes. - modules: ce sont des paquets auto-contenus qui contiennent du MVC complet. Une application peut
être organisée en de multiples modules. - filtres: ils représentent du code qui doit être invoqué avant et après la gestion effective
de chaque requête par des contrôleurs. - objets graphiques: ce sont des objets qui peuvent être intégrés dans des vues. Ils
peuvent contenir de la logique contrôleur et peuvent être réutilisés dans différentes vues.
Le diagramme suivant montre la structure statique d'une application :
Guide Id Structure Overview (`docs/guide-id/structure-overview.md`)
Tinjauan
Aplikasi Yii diorganisir berdasarkan pola arsitektur model-view-controller (MVC).
Model merepresentasikan data, pengaturan dan proses bisnis; view
adalah output yang merepresentasikan model; dan controller mengelola input dan merubahnya
menjadi perintah-perintah untuk model dan view.
Selain MVC, aplikasi Yii juga memiliki entitas berikut:
- entry scripts: Ini adalah skrip PHP yang diakses secara langsung oleh pengguna.
Ini bertugas untuk memulai siklus penanganan request. - applications: Ini adalah objek yang dapat diakses secara global, yang mengelola component aplikasi
dan mengaturnya untuk memenuhi sebuah request. - application components: Ini adalah objek-objek yang didaftarkan pada objek application dan
menyediakan beragam layanan untuk memenuhi request. - modules: Ini adalah paket (package) mandiri yang berisikan MVC lengkap.
Sebuah aplikasi boleh diistilahkan sebagai module-module yang telah diorganisir. - filters: Ini merepresentaikan kode yang mutlak untuk dijalakan sebelum dan sesudah
penanganan dari tiap-tiap request yang dikelola oleh controller. - widgets: Ini adalah objek-objek yang dapat ditanam kedalam views. Ini
dapat mengandung logika controller dan dapat digunakan berulang-ulang pada view yang berbeda.
Diagram dibawah ini menunjukkan struktur statis dari sebuah aplikasi:
Guide Ja Caching Overview (`docs/guide-ja/caching-overview.md`)
キャッシュ
キャッシュはウェブ・アプリケーションのパフォーマンスを向上させるための安価で効果的な方法です。
比較的静的なデータをキャッシュに格納し、要求に応じてキャッシュからそれを取得します。
これによって、アプリケーションは、毎回一からデータを生成した場合に必要になるであろう時間を節約することができます。
キャッシュはアプリケーション内のさまざまなレベルと場所で使用することができます。
例えばサーバ・サイドでの低いレベルでは、データベースから取得した最新の記事情報リストのような
基本的なデータを格納するためにキャッシュを使用することが出来ます。
より高いレベルでは、ウェブ・ページの断片または全体、例えば、最新の記事のレンダリング結果を格納するためにキャッシュを使用することが出来ます。
クライアント・サイドでは、最近訪れたページの内容をブラウザのキャッシュに格納するために、HTTP キャッシュを使用することができます。
Yii はこれら全てのキャッシュ機構をサポートしています:
Guide Ja Helper Overview (`docs/guide-ja/helper-overview.md`)
ヘルパ
Note: このセクションはまだ執筆中です。
Yii は、一般的なコーディングのタスク、例えば、文字列や配列の操作、HTML コードの生成などを手助けする多くのクラスを提供しています。
これらのヘルパ・クラスは yii\helpers 名前空間の下に編成されており、すべてスタティックなクラス
(すなわち、スタティックなプロパティとメソッドのみを含み、インスタンス化すべきでないクラス) です。
ヘルパ・クラスは、そのスタティックなメソッドの一つを直接に呼び出すことによって使用します。例えば、
use yii\helpers\Html;
echo Html::encode('Test > test');Note: ヘルパ・クラスをカスタマイズする ことをサポートするために、Yii はコア・ヘルパ・クラスのすべてを二つのクラスに分割しています。
すなわち、基底クラス (例えばBaseArrayHelper) と具象クラス (例えばArrayHelper) です。
ヘルパを使うときは、具象クラスのみを使うべきであり、基底クラスは決して使ってはいけません。
コア・ヘルパ・クラス
以下のコア・ヘルパ・クラスが Yii のリリースにおいて提供されています。
- 配列ヘルパ
- Console
- FileHelper
- FormatConverter
- Html ヘルパ
- HtmlPurifier
- Imagine (yii2-imagine エクステンションによって提供)
- Inflector
- Json
- Markdown
- StringHelper
- Url ヘルパ
- VarDumper
ヘルパ・クラスをカスタマイズする
コア・ヘルパ・クラス (例えば [[yii\helpers\ArrayHelper]]) をカスタマイズするためには、
そのヘルパに対応する基底クラス (例えば [[yii\helpers\BaseArrayHelper]]) を拡張するクラスを作成して、名前空間も含めて、
対応する具象クラス (例えば [[yii\helpers\ArrayHelper]]) と同じ名前を付けます。
このクラスが、フレームワークのオリジナルの実装を置き換えるものとしてセットアップされます。
次の例は、[[yii\helpers\ArrayHelper]] クラスの [[yii\helpers\ArrayHelper::merge()|merge()]]
メソッドをカスタマイズする方法を示すものです。
<?php
namespace yii\helpers;
class ArrayHelper extends BaseArrayHelper
{
public static function merge($a, $b)
{
// あなた独自の実装
}
}あなたのクラスを ArrayHelper.php という名前のファイルに保存します。このファイルはどこに置いても構いません。例えば、@app/components に置くことにしましょう。
次に、アプリケーションの エントリ・スクリプト で、
次のコード行を yii.php ファイルをインクルードする行の後に追加して、Yii クラス・オートローダ に、
フレームワークから本来のヘルパ・クラスをロードする代りに、あなたのカスタム・クラスをロードすべきことを教えます。
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';ヘルパ・クラスのカスタマイズは、ヘルパの既存の関数の振る舞いを変更したい場合にだけ役立つものであることに注意してください。
アプリケーションの中で使用する関数を追加したい場合は、
そのための独立したヘルパを作成する方が良いでしょう。
Guide Ja Runtime Overview (`docs/guide-ja/runtime-overview.md`)
概要
Yii のアプリケーションがリクエストを処理するときは、毎回、同じようなワーク・フローになります。
- ユーザが エントリ・スクリプト
web/index.phpにリクエストをします。 - エントリ・スクリプトは、アプリケーションの 構成情報 をロードして、
リクエストを処理するための アプリケーション のインスタンスを作成します。 - アプリケーションは、リクエスト アプリケーション・コンポーネントの助けを借りて、
リクエストされた ルート を解決します。 - アプリケーションはリクエストを処理するための コントローラ のインスタンスを作成します。
- コントローラは アクション のインスタンスを作成して、アクションのためのフィルタを実行します。
- フィルタのどれかが失敗すると、アクションはキャンセルされます。
- すべてのフィルタを無事に通ったら、アクションが実行されます。
- アクションはデータモデルを、おそらくはデータベースから、ロードします。
- アクションはデータ・モデルをビューに提供して、ビューをレンダリングします。
- レンダリングの結果は レスポンス アプリケーション・コンポーネントに返されます。
- レスポンス・コンポーネントがレンダリングの結果をユーザのブラウザに送信します。
次の図は、アプリケーションがどのようにしてリクエストを処理するかを示すものです。
このセクションでは、これらのステップのいくつかについて、どのように動作するかを詳細に説明します。
Guide Ja Security Overview (`docs/guide-ja/security-overview.md`)
セキュリティ
十分なセキュリティは、すべてのアプリケーションの健全さと成功のために欠くことが出来ないものです。
不幸なことに、理解が不足しているためか、実装の難易度が高すぎるためか、セキュリティのことになると手を抜く開発者がたくさんいます。
Yii によって駆動されるあなたのアプリケーションを可能な限り安全にするために、Yii はいくつかの優秀な使いやすいセキュリティ機能を内蔵しています。
Guide Ja Structure Overview (`docs/guide-ja/structure-overview.md`)
概要
Yii のアプリケーションは モデル・ビュー・コントローラ (MVC) アーキテクチャ・パターンに従って編成されています。
モデル は、データ、ビジネス・ロジック、規則を表現します。
ビュー は、モデルの出力表現です。
そして コントローラ は入力を受け取って、それを モデル と ビュー のためのコマンドに変換します。
MVC 以外にも、Yii のアプリケーションは下記の要素を持っています。
- エントリ・スクリプト: エンド・ユーザから直接アクセスできる PHP スクリプトです。
これはリクエスト処理サイクルを開始する役目を持っています。 - アプリケーション: グローバルにアクセス可能なオブジェクトであり、
アプリケーション・コンポーネントを管理し、連携させて、リクエストに応えます。 - アプリケーション・コンポーネント: アプリケーションと共に登録されたオブジェクトであり、
リクエストに応えるための様々なサービスを提供します。 - モジュール: それ自身に完全な MVC を含む自己完結的なパッケージです。
アプリケーションは複数のモジュールとして編成することが出来ます。 - フィルタ: 各リクエストが実際に処理される前と後に、
コントローラから呼び出される必要があるコードを表現します。 - ウィジェット: ビュー に埋め込むことが出来るオブジェクトです。
コントローラのロジックを含むことが可能で、異なるビューで再利用することが出来ます。
下の図がアプリケーションの静的な構造を示すものです。
Guide Ja Test Overview (`docs/guide-ja/test-overview.md`)
テスト
テストはソフトウェア開発の重要な部分です。
気付いているか否かにかかわらず、私たちは継続的にテストをしています。
例えば、PHP でクラスを書くとき、私たちはステップごとにデバッグしたり、または単純に echo 文や die 文を使ったりして、実装が最初の計画通りに動作することを検証します。
ウェブ・アプリケーションの場合は、何らかのテスト・データをフォームに入力して、ページが期待通りにユーザと相互作用をすることを確認します。
テストを実行するプロセスを自動化して、何かを検証する必要があるときは、いつでも、
それを代行してくれるコードを呼び出すだけでよいようにすることが出来ます。
結果が計画したものと合致することを検証するコードが テスト と呼ばれ、それを作成して更に実行するプロセスが テスト自動化 として知られています。
このテストの章の主題は、このテストの自動化です。
テストとともに開発する
テスト駆動開発 (TDD) とビヘイビア駆動開発 (BDD) のソフトウェア開発手法においては、実際のコードを書く前に、
コードの断片または全体の機能の振る舞いを一連のシナリオまたはテストとして記述します。
そして、その後で初めて、テストに合格するように実装を作成して、
意図された振る舞いが達成されていることを検証します。
一つの機能を開発するプロセスは以下のようになります。
- 実装されるべき機能を記述するテストを作成する。
- 新しいテストを走らせて、失敗することを確認する。まだ実装がないので、これは予期された結果です。
- 新しいテストに合格するための単純なコードを書く。
- 全てのテストを走らせて、全てが合格することを確認する。
- コードを改良して、それでも全てのテストが OK であることを確認する。
完了すれば、別の機能または改良のために、このプロセスを再び繰り返します。
既存の機能が変更される場合は、テストも変更されなければなりません。
Tip: 多数の小さくて単純なイテレーションを繰り返すために時間を取られていると感じる場合は、テスト・シナリオのカバー範囲を広くして、テストを再度実行するまでの作業量を増やしてみてください。
デバッグばかりやっている場合は、逆に範囲を狭めてみてください。
全ての実装作業の前にテストを作成する理由は、そうすれば、その後で、
達成したい事柄に集中して「どのようにするか」に没頭することが出来るからです。
通常、そのようにすることは、良い抽象化、機能修正時の容易なテスト保守、また、結合度の低いコンポーネントにつながります。
ですから、このような手法の長所を要約すると次のようになります。
- 一時に一つの事柄に集中できるため、計画と実装がより良いものになる。
- より多くの機能をより詳細にテストでカバーできる。つまり、テストが OK なら何も問題がないと期待できる。
通常は、長い期間で見れば、かなり時間を節約する効果があります。
いつ、どうやって、テストするか
上記で説明したテスト・ファーストの手法は長期間にわたる比較的複雑なプロジェクトには合理的なものですが、簡単なプロジェクトでは、やりすぎとなるおそれもあります。
この手法が適切であることを示す指標がいくつかあります。
- プロジェクトは既に大きくて複雑である。
- プロジェクトの要求仕様が複雑になってきている。プロジェクトが継続的に大きくなっている。
- プロジェクトが長期にわたる予定である。
- 失敗のコストが高すぎる。
既存の実装の振る舞いをカバーするテストを作成することは、何も悪いことではありません。
- プロジェクトはレガシーなものであるが、段階的に刷新される予定である。
- 従事すべきプロジェクトを得たが、それにはテストがなかった。
どんな形式の自動化テストもやりすぎになる、という場合もあるでしょう。
- プロジェクトが単純で、この先も、複雑になる心配はない。
- これ以上かかわることはない一度限りのプロジェクトである。
ただ、このような場合であっても、時間に余裕があれば、テストを自動化することは良いことです。
参考
- Test Driven Development: By Example / Kent Beck. ISBN: 0321146530.
Guide Pl Caching Overview (`docs/guide-pl/caching-overview.md`)
Pamięć podręczna
Mechanizmy wykorzystujące pamięć podręczną pozwalają na poprawienie wydajności aplikacji sieciowej w tani i efektywny sposób.
Zapisanie statycznych danych w pamięci podręcznej, zamiast generowania ich od podstaw przy każdym wywołaniu, pozwala na znaczne zaoszczędzenie czasu odpowiedzi aplikacji.
Zapis pamięci podręcznej może odbywać się na wielu poziomach i w wielu miejscach aplikacji. Po stronie serwera, na niskim poziomie,
można wykorzystać pamięć podręczną do zapisania podstawowych danych, takich jak zbiór informacji o najnowszych artykułach pobieranych z bazy danych.
Na wyższym poziomie, pamięci podręcznej można użyć do przechowania części bądź całości strony www, na przykład w postaci rezultatu wyrenderowania
listy ww. najświeższych artykułów. Po stronie klienta, pamięć podręczna HTTP przeglądarki może zapisać zawartość ostatnio odwiedzonej strony.
Yii wpiera wszystkie te mechanizmy zapisu w pamięci podręcznej:
Guide Pl Helper Overview (`docs/guide-pl/helper-overview.md`)
Klasy pomocnicze
Note: Ta sekcja jest w trakcie tworzenia.
Yii jest wyposażone w wiele klas upraszczających pisanie często wykorzystywanych zadań w kodzie, takich jak manipulowanie ciągami znaków bądź tablicami, generowanie kodu HTML, itp.
Te pomocnicze klasy znajdują się w przestrzeni nazw yii\helpers i wszystkie są klasami statycznymi (czyli zawierają wyłącznie statyczne właściwości i nie powinny być tworzone ich
instancje).
Aby skorzystać z klasy pomocnicznej, należy bezpośrednio wywołać jedną z jej statycznych metod, jak w przykładzie poniżej:
use yii\helpers\Html;
echo Html::encode('Test > test');Note: W celu zapewnienia możliwości dostosowania klas pomocniczych do własnych potrzeb, Yii rozdziela każdą z ich wbudowanych wersji
na dwie klasy: podstawę (np.BaseArrayHelper) i klasę właściwą (np.ArrayHelper). Kiedy chcesz użyć klasy pomocnicznej, powinieneś korzystać wyłącznie z jej właściwej wersji
i nigdy nie używać bezpośrednio podstawy.
Wbudowane klasy pomocnicze
Poniższe wbudowane klasy pomocnicze dostępne są w każdym wydaniu Yii:
- ArrayHelper
- Console
- FileHelper
- FormatConverter
- Html
- HtmlPurifier
- Imagine (poprzez rozszerzenie yii2-imagine)
- Inflector
- Json
- Markdown
- StringHelper
- Url
- VarDumper
Dostosowywanie klas pomocniczych do własnych potrzeb
Aby zmodyfikować wbudowaną klasę pomocniczną (np. [[yii\helpers\ArrayHelper|ArrayHelper]]), należy stworzyć nową klasę rozszerzającą odpowiednią podstawę
(np. [[yii\helpers\BaseArrayHelper|BaseArrayHelper]]) i nazwać ją identycznie jak jej wersja właściwa (np. [[yii\helpers\ArrayHelper|ArrayHelper]]), łącznie z zachowaniem jej
przestrzeni nazw. Ta klasa może następnie zostać użyta do zastąpienia oryginalnej implementacji we frameworku.
Poniższy przykład ilustruje w jaki sposób zmodyfikować metodę [[yii\helpers\ArrayHelper::merge()|merge()]] klasy [[yii\helpers\ArrayHelper|ArrayHelper]]:
<?php
namespace yii\helpers;
class ArrayHelper extends BaseArrayHelper
{
public static function merge($a, $b)
{
// zmodyfikowana wersja metody
}
}Klasę należy zapisać w pliku o nazwie ArrayHelper.php, który może znajdować się w dowolnym odpowiednim folderze, np. @app/components.
Następnie dopisujemy poniższą linijkę kodu w skrypcie wejściowym aplikacji po fragmencie dołączającym plik yii.php,
dzięki czemu autoloader klas Yii załaduje zmodyfikowaną wersję klasy pomocniczej zamiast oryginalnej:
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';Należy pamiętać o tym, że modyfikowanie klasy pomocniczej jest użyteczne tylko w przypadku, gdy chcemy zmienić domyślny sposób działania jej metody.
W przypadku dodawania do aplikacji dodatkowych funkcjonalności, lepszym pomysłem jest stworzenie całkowicie nowej, osobnej klasy pomocniczej.
Guide Pl Runtime Overview (`docs/guide-pl/runtime-overview.md`)
Przegląd
Za każdym razem kiedy aplikacja Yii obsługuje żądanie, przetwarza je w podobny sposób.
- Użytkownik wykonuje żądanie do skryptu wejściowego
web/index.php. - Skrypt wejściowy ładuje konfigurację aplikacji i tworzy instancję aplikacji, aby obsłużyć zapytanie.
- Aplikacja osiąga żądaną ścieżkę za pomocą komponentu żądania aplikacji.
- Aplikacja tworzy instancję kontrolera, który obsłuży żądanie.
- Kontroler tworzy instancję akcji i przetwarza filtry dla akcji.
- Jeżeli jakikolwiek filtr się nie wykona, akcja zostanie anulowana.
- Jeżeli wszystkie filtry przejdą, akcja zostaje wykonana.
- Akcja wczytuje model danych, być może z bazy danych.
- Akcja renderuje widok dostarczając go z modelem danych.
- Wyrenderowana zawartość jest zwracana do komponentu odpowiedzi aplikacji.
- Komponent odpowiedzi wysyła wyrenderowaną zawartość do przeglądarki użytkownika.
W tej sekcji opiszemy szczegóły dotyczące niektórych kroków przetwarzania żądania.
Guide Pl Security Overview (`docs/guide-pl/security-overview.md`)
Bezpieczeństwo
Spełnienie wymogów bezpieczeństwa jest podstawą sukcesu i długiej żywotności każdej aplikacji. Niestety, wielu deweloperów idzie
w tym temacie drogą na skróty, czy to z powodu braku jego zrozumienia, czy też kłopotów z implementacją we własnym kodzie.
Aby uczynić Twoją aplikację opartą na Yii tak bezpieczną, jak to tylko możliwe, Yii zapewnia kilka świetnych i jednocześnie łatwych
w użyciu funkcjonalności służących poprawie bezpieczeństwa.
- Uwierzytelnianie
- Autoryzacja
- Praca z hasłami
- Kryptografia
- Bezpieczeństwo widoków
- Klienty autoryzacji
- Bezpieczeństwo w praktyce
Guide Pl Structure Overview (`docs/guide-pl/structure-overview.md`)
Struktura aplikacji
Aplikacja Yii jest zorganizowana według wzorca architektonicznego model-widok-kontroler (MVC).
Modele reprezentują dane, logikę biznesową i zasady walidacji, widoki
są odpowiedzialne za wyświetlanie informacji związanych z modelami, a kontrolery przyjmują dane wejściowe
i przekształcają je w polecenia dla modeli i widoków.
Oprócz MVC, w aplikacjach Yii zdefiniowane są następujące struktury:
- skrypty wejściowe: skrypty PHP dostępne bezpośrednio dla użytkowników końcowych,
odpowiedzialne za uruchomienie obsługi cyklu życia żądania. - aplikacje: globalnie dostępne obiekty koordynujące działanie i zarządzające komponentami aplikacji.
- komponenty aplikacji: obiekty zarejestrowane w aplikacji, zapewniające dostępność dedykowanych usług.
- moduły: niezależne pakiety kodu zawierające kompletną wewnętrzną strukturę MVC.
Aplikacja może być zorganizowana modułowo. - filtry: reprezentują kod, który musi być wykonany przed i po obsłużeniu każdego z żądań kontrolera.
- widżety: obiekty, które mogą być dołączone w widokach. Mogą zawierać logikę kontrolera
i być wykorzystane wielokrotnie w różnych miejscach.
Poniższy diagram ilustruje statyczną strukturę aplikacji:
Guide Pl Test Overview (`docs/guide-pl/test-overview.md`)
Testowanie
Testowanie jest istotnym elementem produkcji każdego oprogramowania. Niezależnie, czy jesteśmy tego świadomi, czy też nie, testy przeprowadzamy nieustannie.
Dla przykładu, kiedy napiszemy klasę w PHP, możemy debugować ją krok po kroku lub po prostu użyć wyrażeń jak echo lub die, aby sprawdzić, czy implementacja
działa zgodnie z naszym początkowym planem. W przypadku aplikacji web wprowadzamy testowe dane w formularzach, aby upewnić się, że strona odpowiada tak, jak powinna.
Proces testowania może zostać zautomatyzowany, dzięki czemu za każdym razem, kiedy musimy coś sprawdzić, wystarczy wywołać kod, który zrobi to za nas.
Kod, który weryfikuje zgodność wyniku z planowaną odpowiedzią, jest nazywany testem, a proces jego tworzenia i późniejszego wykonania jest nazywany testowaniem zautomatyzowanym,
co jest głównym tematem tych rozdziałów.
Tworzenie kodu z testami
Tworzenie kodu opartego na testach (Test-Driven Development, TDD) i opartego na zachowaniach (Behavior-Driven Development, BDD) jest podejściem deweloperskim
opierającym się na opisywaniu zachowania fragmentu kodu lub też całej jego funkcjonalności jako zestawu scenariuszy lub testów przed napisaniem właściwego kodu
i dopiero potem stworzeniu implementacji, która pozwoli na poprawne przejście testów, spełniających zadane kryteria.
Proces tworzenia funkcjonalności wygląda następująco:
- Stwórz nowy test, opisujący funkcjonalność do zaimplementowania.
- Uruchom nowy test i upewnij się, że zakończy się błędem. To właściwe zachowanie, ponieważ nie ma jeszcze implementacji funkcjonalności.
- Napisz prosty kod, który przejdzie poprawnie nowy test.
- Uruchom wszystkie testy i upewnij się, że wszystkie zakończą się poprawnie.
- Ulepsz kod, sprawdzając czy testy wciąż są zdane.
Po zakończeniu proces jest powtarzany dla kolejnej funkcjonalności lub ulepszenia. Jeśli istniejąca funkcjonalność ma być zmodyfikowana,
testy powinny być również zmienione.
Wskazówka: Jeśli czujesz, że tracisz czas, przeprowadzając dużo krótkich i prostych iteracji, spróbuj objąć testowym scenariuszem więcej działań,
aby sprawdzić więcej kodu, przed ponownym uruchomieniem testów. Jeśli debugujesz zbyt dużo, spróbuj zrobić dokładnie na odwrót.
Powodem tworzenia testów przed jakąkolwiek implementacją, jest możliwość skupienia się na tym, co chcemy osiągnąć, zanim przystąpimy do "w jaki sposób to zrobić".
Zwykle prowadzi to do stworzenia lepszej warstwy abstrakcji i łatwiejszej obsługi testów w przypadku poprawek funkcjonalności.
Podsumowując, zalety takiego projektowania są następujące:
- Pozwala na skupienie się na pojedynczej rzeczy na raz, dzięki czemu pozwala na lepsze planowanie i implementacje.
- Obejmuje testami więcej funkcjonalności w większym stopniu, co oznacza, że jeśli testy zakończyły się poprawnie jest spore prawdopodobieństwo, że wszystko działa poprawnie.
Na dłuższą metę przynosi to zwykle efekt w postaci mnóstwa oszczędzonego czasu i problemów.
Wskazówka: Jeśli chcesz dowiedzieć się więcej na temat reguł ustalania wymagań dla oprogramowania i modelowania istoty tego rozdziału,
warto zapoznać się z domenowym podejściem do tworzenia aplikacji (Domain Driven Development, DDD).
Kiedy i jak testować
Podejście typu "testy najpierw" opisane powyżej, ma sens w przypadku długofalowych i relatywnie skomplikowanych projektów i może być przesadne w przypadku prostszych.
Przesłanki, kiedy testy są odpowiednie są następujące:
- Projekt jest już duży i skomplikowany.
- Wymagania projektowe zaczynają być skomplikowane. Projekt wciąż się powiększa.
- Projekt jest planowany jako długoterminowy.
- Koszty potencjalnych błędów są zbyt duże.
Nie ma nic złego w tworzeniu testów obejmujących zachowania istniejących implementacji.
- Projekt jest oparty starszym kodzie i stopniowo przepisywany.
- Projekt, nad którym masz pracować, nie ma w ogóle testów.
W niektórych przypadkach jakakolwiek forma automatycznego testu może być nadmiarowa:
- Projekt jest prosty i nie jest rozbudowywany.
- Projekt jest jednorazowym zadaniem, które nie będzie rozwijane.
Pomimo tego, jeśli masz na to czas, automatyzacja testowania jest również dobrym pomysłem.
Biblioteka
- Test Driven Development: By Example - Kent Beck. (ISBN: 0321146530)
Guide Pt BR Caching Overview (`docs/guide-pt-BR/caching-overview.md`)
Cache
Cache é uma maneira simples e eficiente de melhorar o desempenho de uma aplicação Web. Ao gravar dados relativamente
estáticos em cache e servindo os do cache quando requisitados, a aplicação economiza o tempo que seria necessário para renderizar as informações do zero todas as vezes.
Cache pode ocorrer em diferentes níveis e locais em uma aplicação Web. No servidor, no baixo nível,
cache pode ser usado para armazenar dados básicos, como a informação de uma lista de artigos mais recentes trazidos
do banco de dados; e no alto nível, cache pode ser usado para armazenar fragmentos ou páginas Web inteiras, como o
resultado da renderização dos artigos mais recentes. No cliente, cache HTTP pode ser usado para manter o conteúdo da última página acessada no cache do navegador.
Yii suporta todos os quatro métodos de cache:
Guide Pt BR Helper Overview (`docs/guide-pt-BR/helper-overview.md`)
Helpers
Observação: Esta seção está em desenvolvimento.
O Yii oferece muitas classes que ajudam a simplificar as tarefas comuns de codificação, como manipulação de string ou de array,
geração de código HTML, e assim por diante. Essas classes helpers (auxiliares) são organizadas no namespace yii\helpers e
são todas classes estáticas (o que significa que contêm apenas propriedades e métodos estáticos e não devem ser instanciadas).
Você usa uma classe helper chamando diretamente um de seus métodos estáticos, como o seguinte:
use yii\helpers\Html;
echo Html::encode('Test > test');Observação: Para oferecer suporte à personalização de classes helper, o Yii divide cada classe helper principal
em duas classes: uma classe base (ex.BaseArrayHelper) e uma classe concreta (ex.ArrayHelper).
Ao usar um helper, você deve usar apenas a versão concreta e nunca a classe base.
Principais Classes Helper
As seguintes classes helper são fornecidas nas versões Yii:
- ArrayHelper
- Console
- FileHelper
- FormatConverter
- Html
- HtmlPurifier
- Imagine (fornecido pela extensão yii2-imagine)
- Inflector
- Json
- Markdown
- StringHelper
- Url
- VarDumper
Personalização de Classes Helper
Para personalizar uma classe helper principal (ex. [[yii\helpers\ArrayHelper]]), você deve criar uma nova classe que
estende da classe base correspondente ao helper (ex. [[yii\helpers\BaseArrayHelper]]) e nomear a sua classe da mesma
forma que a classe concreta correspondente (ex. [[yii\helpers\ArrayHelper]]), Essa classe será então configurada para
substituir a implementação original da estrutura.
O exemplo a seguir mostra como personalizar o método [[yii\helpers\ArrayHelper::merge()|merge()]] da classe
[[yii\helpers\ArrayHelper]]:
<?php
namespace yii\helpers;
class ArrayHelper extends BaseArrayHelper
{
public static function merge($a, $b)
{
// sua implementação personalizada
}
}Salve sua classe em um arquivo chamado ArrayHelper.php. O arquivo pode estar em qualquer diretório, por exemplo @app/components.
Em seguida, no script de entrada da sua aplicação, adicione a seguinte linha de código
depois do include do arquivo yii.php para dizer ao autoloader de classes do Yii para carregar sua classe
personalizada em vez da classe Helper original do framework:
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';Observe que personalizar as classes Helper só é útil se você quiser mudar o comportamento de uma função existente
dos Helpers. Se você deseja adicionar outras funções para usar em sua aplicação, é melhor criar um
Helper para isso.
Guide Pt BR Runtime Overview (`docs/guide-pt-BR/runtime-overview.md`)
Visão Geral
Cada vez que uma aplicação Yii processa uma requisição, ele passa por um fluxo
de trabalho parecido como o seguinte:
- Um usuário faz uma pedido para o script de entrada
web/index.php. - O script de entrada carrega a configuração da
aplicação e cria uma instância da aplicação para
processar o pedido. - A aplicação resolve a rota solicitada com a ajuda do
componente request da aplicação. - A aplicação cria uma instância do controller (controlador)
para processar o pedido. - O controller (controlador) cria uma instância da ação
e executar os filtros para a ação. - Se qualquer filtro falhar, a ação será cancelada.
- Se todos os filtros passarem, a ação será executada.
- A ação carrega os dados do model (modelo), possivelmente a partir de um banco
de dados. - A ação renderiza uma view (visão), com os dados fornecidos pelo model (modelo).
- O resultado da renderização é devolvida para o componente response
da aplicação. - O componente response envia o resultado da renderização para o navegador do
usuário.
O diagrama a seguir mostra como uma aplicação processa um pedido.
Nesta seção, descreveremos com mais detalhes como alguns destes passos trabalham.
Guide Pt BR Structure Overview (`docs/guide-pt-BR/structure-overview.md`)
Visão Geral
As aplicações do Yii são organizadas de acordo com o padrão de projeto
model-view-controller (MVC)
(modelo-visão-controlador). Os models representam dados,
lógica e regras de negócio; as views são a representação
da saída dos modelos; e os controllers recebem entradas
e as convertem em comandos para os models e as views.
Além do MVC, as aplicações do Yii também possuem as seguintes entidades:
- scripts de entrada: são scripts PHP que são
diretamente acessíveis aos usuários finais. São responsáveis por iniciar o
ciclo de tratamento de uma requisição. - aplicações: são objetos globalmente acessíveis que
gerenciam os componentes da aplicação e os coordenam para atender às requisições. - componentes da aplicação: são objetos
registrados com as aplicações e fornecem vários serviços para atender às
requisições. - módulos: são pacotes auto-contidos que contém um MVC
completo por si sós. Uma aplicação pode ser organizada em termos de múltiplos
módulos. - filtros: representam código que precisa ser chamado
pelos controllers antes e depois do tratamento propriamente dito de cada
requisição. - widgets: são objetos que podem ser embutidos em
views. Podem conter lógica de controller e podem ser
reutilizados em diferentes views.
O diagrama a seguir demonstra a estrutura estática de uma aplicação:
Guide Pt BR Test Overview (`docs/guide-pt-BR/test-overview.md`)
Testes
O teste é uma parte importante do desenvolvimento de software. Se estamos conscientes disso ou não, Realizamos testes continuamente.
Por exemplo, enquanto escrevemos uma classe PHP, podemos depurá-lo passo a passo ou simplismente usar declarações echo ou die para verificar se a implantação está de acordo com nosso plano inicial.
No caso de uma aplicação web, estamos entrando em alguns testes de dados em forma de assegurar que a página interage com a gente como esperado.
O processo de teste pode ser automatizado de modo que cada momento em que precisamos para verificar alguma coisa, só precisamos chamar o código que faz isso por nós. O código que verifica o resultado coincide com o que temos planejado é chamado de teste e o processo de sua criação e posterior execução é conhecido como teste automatizado,
que é o principal tema destes capítulos de testes.
Desenvolvendo com testes
Test-Driven Development (TDD), and Behavior-Driven Development (BDD) são abordagens de desenvolvimento de software,
descrevendo o comportamento de um trecho de código ou todo o recurso como um conjunto de cenários ou testes antes de escrever
código real e só então criar a aplicação que permite que estes testes passem verificando se comportamento a que se destina é conseguido.
O processo de desenvolvimento de uma funcionalidade é a seguinte:
- Criar um novo teste que descreve uma funcionalidade a ser implementada.
- Execute o novo teste e verifique se ele falha. isto é esperado já que não há nenhuma implementação ainda.
- Escrever um código simples para fazer o novo teste passar.
- Executar todos os testes e garantir que todos eles passam.
- Melhorar código e certificar-se de testes ainda estão OK.
Depois feito o processo é repetido novamente para outras funcionalidades ou melhorias.
Se uma funcionalidade existente deve ser alterada, os testes devem ser mudadas também.
Dica: Se você sentir que você está perdendo tempo fazendo um monte de pequenas e simples iterações, experimente cobrindo mais por você.
Cenários de teste é para que você faça mais antes de executar testes novamente. Se você está depurando muito, tente fazer o oposto.
A razão para criar testes antes de fazer qualquer implementação é que ela nos permite focar no que queremos alcançar e totalmente mergulhar "como fazê-lo" depois.
Normalmente, leva a melhores abstrações e manutenção de teste mais fácil quando se trata de ajustes na funcionalidade ou de menos componentes acoplados.
Assim, para resumir as vantagens de tal abordagem são as seguintes:
- Mantém-se focado em uma coisa de cada vez que resulta em uma melhor planejamento e implementação.
- Resultados cobertos por testes para mais funcionalidade em maior detalhe, ou seja, se os testes são OK provavelmente nada está quebrado.
No longo prazo, geralmente, dá-lhe um boa melhoria na produtividade.
Dica: Se você quiser saber mais sobre os princípios de levantamento de requisitos de software e modelagem do assunto
esta é uma referência boa para aprender [Domain Driven Development (DDD)] (https://en.wikipedia.org/wiki/Domain-driven_design).
Quando e como testar
Enquanto a primeira abordagem de teste descrito acima faz sentido em longo prazo para projetos relativamente complexos e que seria um exagero
para os mais simples. Existem alguns indicadores de quando é apropriado:
- Projeto já é grande e complexo.
- Requisitos do projeto estão começando a ficarem complexos. Projeto cresce constantemente.
- Projeto pretende ser a longo prazo.
- O custo da falha é muito alta.
Não há nada errado na criação de testes que abrangem o comportamento de implementação existente.
- Projeto é um legado para ser gradualmente renovada.
- Você tem um projeto para trabalhar e não tem testes.
Em alguns casos, qualquer forma de teste automatizado poderia ser um exagero:
- Projeto é simples e não está ficando mais complexo.
- É um projeto emporal eque deixarão de trabalhar nele.
Ainda assim, se você tiver tempo é bom automatizar testes nestes casos também.
Outras leituras
- Test Driven Development: By Example / Kent Beck. ISBN: 0321146530.
Guide Ru Caching Overview (`docs/guide-ru/caching-overview.md`)
Кэширование
Кэширование — это простой и эффективный способ повысить производительность веб-приложения. Сохраняя относительно
статичные данные в кэше и извлекая их из кэша, когда потребуется, мы экономим время, затрачиваемое на генерацию
данных с нуля каждый раз.
Кэширование может использоваться на различных уровнях и в различных местах веб-приложения. На стороне сервера, на более
низком уровне мы используем кэширование для хранения основных данных, таких как список последних полученных из базы
данных статьей. На более высоком уровне кэш может использоваться для хранения фрагментов или целых веб-страниц. Таких,
например, как результат рендеринга последних статьей. На стороне клиента для сохранения содержимого недавно посещенных
страниц в кэше браузера может использоваться HTTP-кэширование.
Yii поддерживает все эти механизмы кэширования:
Guide Ru Helper Overview (`docs/guide-ru/helper-overview.md`)
Хелперы
Note: Этот раздел находиться в стадии разработки.
Yii предоставляет много классов, которые помогают упростить общие задачи программирования, такие как манипуляция со строками или массивами, генерация HTML-кода, и так далее. Все helper-классы организованы в рамках пространства имен yii\helpers и являются статическими классами
(это означает, что они содержат в себе только статические свойства и методы, и объекты статического класса создать нельзя).
Вы можете использовать helper-класс с помощью вызова одного из статических методов, как показано ниже:
use yii\helpers\Html;
echo Html::encode('Test > test');Note: Помощь в настройке helper-классов, в Yii каждый основной helper состоит из двух классов: базовый класс (например,
BaseArrayHelper) и конкретный класс (например,ArrayHelper).
Когда вы используете helper, вы должны использовать только конкретные версии классов и никогда не использовать базовые классы.
Встроенные хелперы
В этой версии Yii предоставляются следующие основные helper-классы:
- ArrayHelper
- Console
- FileHelper
- FormatConverter
- Html
- HtmlPurifier
- Imagine (provided by yii2-imagine extension)
- Inflector
- Json
- Markdown
- StringHelper
- Url
- VarDumper
Настройка хелперов
Для настройки основных helper-классов (например, [[yii\helpers\ArrayHelper]]), вы должны создать расширяющийся класс из помощников соответствующих базовых классов (например, [[yii\helpers\BaseArrayHelper]]) и дать похожее название вашему классу с соответствующим конкретному классу (например, [[yii\helpers\ArrayHelper]]), в том числе его пространство имен. Тогда созданный класс заменит оригинальную реализацию в фреймворке.
В следующих примерах показывается как настроить метод [[yii\helpers\ArrayHelper::merge()|merge()]]
[[yii\helpers\ArrayHelper]] класса:
<?php
namespace yii\helpers;
class ArrayHelper extends BaseArrayHelper
{
public static function merge($a, $b)
{
// ваша собственная реализация
}
}Сохраните ваш класс в файле с именем ArrayHelper.php. Файл должен находиться в другой директории, например @app/components.
Далее, в приложении входной скрипт, добавьте следующую строчку кода
после подключения yii.php файла, которая сообщит автозагрузка классов Yii загрузить
ваш класс вместо оригинального helper-класса фреимворка:
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';Обратите внимание что пользовательская настройка helper-классов полезна только, если вы хотите изменить поведение существующей функции helper-классов. Если вы хотите добавить дополнительные функции, для использования в вашем приложении, будет лучше создать отдельный helper.
Guide Ru Runtime Overview (`docs/guide-ru/runtime-overview.md`)
Обзор
Все запросы, обрабатываемые Yii приложением, проходят подобный путь.
- Пользователь создает запрос ко входному скрипту
web/index.php. - Входной скрипт загружает конфигурацию и создает экземпляр приложения для обработки запроса.
- Приложение определяет запрошенный маршрут при помощи компонента request.
- Приложение создает экземпляр контроллера для обработки запроса.
- Контроллер создает экземпляр действия и выполняет фильтры для этого действия.
- При неудачном выполнении любого фильтра, действие не выполняется.
- При успешном выполнении всех фильтров, выполняется действие.
- Действие загружает модель данных, возможно, из базы данных.
- Действие рендерит представление и передает ему модель данных.
- Результат рендеринга передается в компонент приложения response.
- Компонент response посылает готовые данные пользователю.
Ниже представлена диаграмма обработки запроса приложением.
В данном разделе описаны подробности некоторых этапов обработки запроса.
Guide Ru Security Overview (`docs/guide-ru/security-overview.md`)
Безопасность
Хорошая безопасность жизненно важна для успеха любого приложения. К сожалению, многие разработчики не уделяют ей должного внимания. Происходит это либо из-за недостатка понимания, либо из-за того, что это слишком сложно. Чтобы сделать ваше приложение максимально безопасным, в Yii включено несколько превосходных и простых в использовании функций безопасности.
- Аутентификация
- Авторизация
- Работа с паролями
- Криптография
- Безопасность видов
- Клиенты авторизации
- Лучшие практики
- Доверенные прокси и заголовки
Guide Ru Structure Overview (`docs/guide-ru/structure-overview.md`)
Обзор
Yii приложения организованы согласно шаблону проектирования модель-представление-контроллер (MVC).
Модели представляют собой данные, бизнес логику и бизнес правила; представления
отвечают за отображение информации, в том числе и на основе данных, полученных из моделей; контроллеры
принимают входные данные от пользователя и преобразовывают их в понятный для моделей формат и команды, а также отвечают за отображение
нужного представления.
Кроме MVC, Yii приложения также имеют следующие сущности:
- входные скрипты: это PHP скрипты, которые доступны напрямую конечному пользователю приложения.
Они ответственны за запуск и обработку входящего запроса; - приложения: это глобально доступные объекты, которые осуществляют корректную работу различных
компонентов приложения и их координацию для обработки запроса; - компоненты приложения: это объекты, зарегистрированные в приложении и предоставляющие
различные возможности для обработки текущего запроса; - модули: это самодостаточные пакеты, которые включают в себя полностью все средства для MVC.
Приложение может быть организованно с помощью нескольких модулей; - фильтры: это код, который должен быть выполнен до и после обработки запроса контроллерами;
- виджеты: это объекты, которые могут включать в себя представления.
Они могут содержать различную логику и быть использованы в различных представлениях.
Ниже на диаграмме представлена структурная схема приложения:
Guide Ru Test Overview (`docs/guide-ru/test-overview.md`)
Тестирование
Тестирование является важной составляющей разработки программного обеспечения. Мы проводим тестирование непрерывно, осознаем мы это или нет. Например, когда мы пишем класс на языке PHP, мы можем отлаживать его шаг за шагом или просто использовать echo или die для проверки, что реализация работает в соответствии с намеченным планом. В случае веб приложения, мы вводим некоторые тестовые данные в форму для того, чтобы убедиться, что страница взаимодействует с нами, как ожидается.
Процесс тестирования может быть автоматизирован так, что каждый раз, когда нам нужно что-то проверить, мы просто должны
вызвать код, который сделает это за нас. Код, который проверяет, что результат совпадает с тем, что мы планировали, называется тестом, а процесс создания тестов и их последующего использования - автоматизированным тестированием, что и является главной темой данного раздела.
Разработка с тестами
Разработка через тестирование (TDD) и разработка через поведение (BDD) - это подходы разработки программного обеспечения, в рамках которых поведение части кода или целая фича описывается в виде набора сценариев или тестов ДО написания фактического кода и только
затем создается реализация. Тем самым мы можем использовать данные тесты для проверки, что достигается заданное поведение.
Процесс разработки фичи следующий:
- Создать новый тест, описывающий функцию, которая будет реализована.
- Запустить новый тест и убедиться, что он терпит неудачу. Это ожидаемо, т.к. на данный момент еще нет конкретной реализации.
- Написать простой код, чтобы новый тест отрабатывал без ошибок.
- Запустить все тесты и убедиться, что они отрабатывают без ошибок
- Улучшить код и убедиться, что все тесты все еще отрабатывают без ошибок
После того как это завершено, процесс повторяется снова для другой фичи или улучшения. Если существующая фича должна быть изменена, то и тесты также должны быть изменены.
Tip: Если вы чувствуете, что вы теряете время выполняя много мелких и простых итераций, попробуйте покрыть это
вашим тестовым сценарием перед следующим выполнением тестов. Если вы слишком много отлаживаете, попробуйте сделать обратное.
Написание тестов до реализации конкретного функционала позволяет нам сосредоточиться на том, что мы хотим достичь и полностью
погрузиться в "как это сделать" впоследствии.
Обычно это приводит к лучшим абстракциям и более легкой поддержке тестов, когда речь идет о корректировке фичи или уменьшении связанности компонентов.
Таким образом, плюсы этого подхода следующие:
- Позволяет вам сосредоточиться на одной вещи, что в свою очередь приводит к улучшению планирования и реализации.
- Более подробное покрытие тестами функционала. Таким образом, если все тесты отрабатывают без ошибок, скорее всего, ничего не сломано.
В долгосрочной перспективе это, как правило, дает вам хороший эффект экономии времени.
Tip: Если вы хотите узнать больше о принципах сбора требования программного обеспечения и моделирования
предметной области, рекомендуем изучить Проблемно-ориентированное проектирование (DDD).
Когда и как тестировать
Принцип разработки, описанный выше, имеет смысл применять для долгосрочных и относительно сложных проектов, в то время как для простых это может быть излишним. Есть несколько показателей того, когда данный подход уместен:
- Проект уже большой и сложный.
- Требования к проекту начинают усложняться. Проект постоянно растет.
- Долгосрочный проект.
- Цена ошибки очень высока
Нет ничего плохого в создании тестов, покрывающих поведение существующей реализации.
- Legacy-проект который постоянно обновляется.
- Вам поручили работу над проектом, в котором нет ни одного теста.
В некоторых случаях автоматизированное тестирование может быть излишним:
- Проект простой и не станет более сложным.
- Это одноразовый проект, который больше не будет дорабатываться.
Тем не менее, если у вас есть время, было бы хорошо автоматизировать тестирование и в этих случаях.
Что почитать
- Экстремальное программирование. Разработка через тестирование / Кент Бек. ISBN: 0321146530.
Guide Uk Structure Overview (`docs/guide-uk/structure-overview.md`)
Огляд
Додатки Yii організовані згідно архітектурного шаблону Модель-Представлення-Контролер (MVC).
Моделі являють собою дані, бізнес-логіку та бізнес-правила;
представлення відповідають за відображення даних моделей;
контролери приймають вхідні дані від користувача і перетворюють їх у команди для
моделей та представлень.
Окрім MVC, Yii додаток також має наступні сутності:
- вхідні скрипти: це PHP-скрипти, які доступні напряму кінцевому користувачу додатка.
Вони відповідають за запуск циклу обробки запиту. - додатки: це глобально доступні об’єкти, які відповідають за коректну роботу різних
компонентів додатка і їх координацію для обробки запиту. - компоненти додатку: це об’єкти, зареєстровані в додатку і які надають
різноманітні можливості для обробки запитів. - модулі: це самодостатні пакунки, що включають в себе повністю всі ресурси для MVC.
Додаток може бути організовано за допомогою декількох модулів. - фільтри: це код, який повинен бути виконаний до і після обробки запиту контролерами.
- віджети: це об’єкти, які можуть бути вбудованими у представлення.
Вони можуть містити логіку контролера і можуть бути повторно використаними у різних представленнях.
На наступній діаграмі наведена структурна схема додатку:
Guide Vi Structure Overview (`docs/guide-vi/structure-overview.md`)
Tổng quan về kiến trúc ứng dụng
Các ứng dụng Yii được tổ chức dựa theo mẫu thiết kế model-view-controller (MVC)
. Models chứa nghiệp vụ logic, truy xuất database và định nghĩa các quy tắc xác thực dữ liệu; views
đảm nhận việc hiển thị thôn tin của model; và controllers có nhiệm vụ điều hướng các yêu cầu và chuyển các tương tác giữa
models và views.
Ngoài mô hình MVC, ứng dụng Yii có những phần phần sau đây:
- entry scripts: là file đầu tiên chứa các mã nguồn để tiếp nhận các request của người dùng.
Thành phần này có trách nhiệm bắt đầu về chu trình xử lý các yêu cầu trong ứng dụng. - ứng dụng: là đối tượng có phạm vi truy cập toàn cục giúp quản lý các thành phần trong ứng dụng
và điều hướng chúng để thực hiện các yêu cầu. - thành phần: là đối tượng được đăng ký với ứng dụng
và cung cấp những dịch vụ cho các yêu cầu xử lý . - modules: là những gói có chứa mô hình MVC hoàn chỉnh.
Một ứng dụng có thể được tổ chức dưới dạng nhiều module. - filters: chứa những mã nguồn cần được gọi trước và sau việc xử lý của từng yêu cầu của bộ điều khiển
handling of each request by controllers. - widgets: các đối tượng được nhúng vào views. Các widget có thể chứa các nghiệp vụ logic
và có thể tái sử dụng ở những view khác.
Mô hình sau mô tả cấu trúc ứng dụng ở dạng tĩnh:
Guide Zh CN Caching Overview (`docs/guide-zh-CN/caching-overview.md`)
缓存
缓存是提升 Web 应用性能简便有效的方式。
通过将相对静态的数据存储到缓存并在收到请求时取回缓存,
应用程序便节省了每次重新生成这些数据所需的时间。
缓存可以应用在 Web 应用程序的任何层级任何位置。
在服务器端,在较的低层面,缓存可能用于存储基础数据,例如从数据库中取出的最新文章列表;
在较高的层面,缓存可能用于存储一段或整个 Web 页面,
例如最新文章的渲染结果。在客户端,HTTP 缓存可能用于
将最近访问的页面内容存储到浏览器缓存中。
Yii 支持如上所有缓存机制:
Guide Zh CN Helper Overview (`docs/guide-zh-CN/helper-overview.md`)
助手类(Helpers)
Note: 这部分正在开发中。
Yii 提供许多类来简化常见编码,如对字条串或数组的操作,
HTML 代码生成,等等。这些助手类被编写在命名空间 yii\helpers 下,并且
全是静态类 (就是说它们只包含静态属性和静态方法,而且不能实例化)。
可以通过调用其中一个静态方法来使用助手类,如下:
use yii\helpers\Html;
echo Html::encode('Test > test');Note: 为了支持 自定义助手类,Yii 将每一个助手类
分隔成两个类:一个基类 (例如BaseArrayHelper) 和一个具体的类 (例如ArrayHelper)。
当使用助手类时,应该仅使用具体的类版本而不使用基类。
核心助手类(Core Helper Classes)
Yii 发布版中提供以下核心助手类:
- ArrayHelper
- Console
- FileHelper
- Html
- HtmlPurifier
- Imagine(由 yii2-imagine 扩展提供)
- Inflector
- Json
- Markdown
- Security
- StringHelper
- Url
- VarDumper
自定义助手类(Customizing Helper Classes)
如果想要自定义一个核心助手类 (例如 [[yii\helpers\ArrayHelper]]),你应该创建一个新的类继承
helpers对应的基类 (例如 [[yii\helpers\BaseArrayHelper]]) 并同样的命
名你的这个类 (例如 [[yii\helpers\ArrayHelper]]),包括它的命名空间。这个类
会用来替换框架最初的实现。
下面示例显示了如何自定义 [[yii\helpers\ArrayHelper]] 类的
[[yii\helpers\ArrayHelper::merge()|merge()]] 方法:
<?php
namespace yii\helpers;
class ArrayHelper extends BaseArrayHelper
{
public static function merge($a, $b)
{
// 你自定义的实现
}
}将你的类保存在一个名为 ArrayHelper.php 的文件中。该文件可以在任何目录,例如 @app/components。
接下来,在你的应用程序 入口脚本 处,在引入的 yii.php 文件后面
添加以下代码行,用 Yii 自动加载器 来加载自定义类
代替框架的原始助手类:
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';注意,自定义助手类仅仅用于如果你想要更改助手类中
现有的函数的行为。如果你想为你的应用程序添加附加功能,最好为它创建一个单独的
助手类。
Guide Zh CN Runtime Overview (`docs/guide-zh-CN/runtime-overview.md`)
运行机制概述
每一次 Yii 应用开始处理 HTTP 请求时,它都会进行一个近似的流程。
- 用户提交指向 入口脚本
web/index.php的请求。 - 入口脚本会加载 配置数组 并创建一个
应用 实例用于处理该请求。 - 应用会通过 request(请求) 应用组件
解析被请求的 路由。 - 应用创建一个 controller(控制器) 实例具体处理请求。
- 控制器会创建一个 action(动作) 实例并为该动作执行相关的 Filters(访问过滤器)。
- 如果任何一个过滤器验证失败,该动作会被取消。
- 如果全部的过滤器都通过,该动作就会被执行。
- 动作会加载一个数据模型,一般是从数据库中加载。
- 动作会渲染一个 View(视图),并为其提供所需的数据模型。
- 渲染得到的结果会返回给 response(响应) 应用组件。
- 响应组件会把渲染结果发回给用户的浏览器。
下面的示意图展示了应用是如何处理一个请求的。
在这个版块中,我们会更加详细地描述某些步骤的具体运作。
Guide Zh CN Security Overview (`docs/guide-zh-CN/security-overview.md`)
安全(Security)
良好的安全性对于任何应用的健康和成功都至关重要。
不幸的是,许多开发人员在安全方面偷工减料,要么是由于缺乏理解,要么是由于实现过于困难。
为了尽可能保证您的 Yii 应用程序的安全,Yii 包含了一些优秀且易于使用的安全功能。
Guide Zh CN Structure Overview (`docs/guide-zh-CN/structure-overview.md`)
总览
Yii 应用参照模型-视图-控制器 (MVC)
设计模式来组织。 模型代表数据、业务逻辑和规则;
视图展示模型的输出;控制器
接受出入并将其转换为模型和视图命令。
除了 MVC, Yii 应用还有以下部分:
- 入口脚本:终端用户能直接访问的 PHP 脚本,
负责启动一个请求处理周期。 - 应用:能全局范围内访问的对象,
管理协调组件来完成请求. - 应用组件:在应用中注册的对象,
提供不同的功能来完成请求。 - 模块:包含完整 MVC 结构的独立包,
一个应用可以由多个模块组建。 - 过滤器:控制器在处理请求之前或之后
需要触发执行的代码。 - 小部件:可嵌入到视图中的对象,
可包含控制器逻辑,可被不同视图重复调用。
下面的示意图展示了 Yii 应用的静态结构:
Guide Zh CN Test Overview (`docs/guide-zh-CN/test-overview.md`)
测试
测试是软件开发的一个重要组成部分。不管我们是否意识到,我们一直在不断地进行测试。
例如,当我们在用 PHP 写一个类的时候,我们可能用 echo 或者 die 语句一步一步简单的调试
验证我们实现的代码是否按照最初的计划工作。在开发 web 应用的时候,我们在表单中输入
一些测试数据来确保页面能够如预期那样和我们进行交互。
测试过程可能是自动的,所以每次我们需要验证的时候,我们只需要调用它就可以测试代码了。
验证代码执行结果是否符合我们的计划叫做测试,
测试过程的创建以及进一步执行叫做自动化测试,
这是这些测试章节的主要主题。
带着测试进行开发
测试驱动开发(TDD)和行为驱动开发(BDD)在开始编写实际代码之前,
首先通过描述一段代码的行为或将其作为一组场景或测试的全部特征,
然后创建符合这些测试预期验证
的行为实现。
开发一个功能的过程如下:
- 创建一个描述一个功能被实现测试。
- 运行这个测试来确保功能失败,因为这是没有实现之前的预期。
- 编写简单代码确保这个测试通过。
- 运行所有测试确保所有测试都通过。
- 优化代码确保测试依然可以通过。
走完上面的过程之后,为其他功能或者扩展重复上面测试过程。如果功能发生变化,测试也需
要跟着变化。
Tip: 如果你觉得你做一些很小很简单的迭代是在浪费时间,请尝试覆盖更多的测试
场景,这样你就可以在执行测试之前做更多的尝试。如果你的调试过多,试着做相反的工作。
在做一些具体的实现之前创建测试的原因是,这允许我们后期专注于我们想要的实现,并且
可以花费更多的精力到实现细节。在涉及功能调整的时候,这会使得抽象更合理、测试维护
更简单或者使得耦合元件更少。
这种做法的优点如下:
- 在计划和实现发生变更的时候,可以让你在同一时间只专注于一件事情。
- 更多功能更详细的覆盖测试的结果,如果测试都通过好比再也没有什么问题了。
在很长一段时间内,这通常会给你提供一个有效的时间节省。
什么时候测试,怎么测试?
在测试的时候,对于一些相对复杂的项目上面的内容是非常有意义的,但对于一些比较
简单的项目就做的有些极端了。适用场景如下:
- 项目已经很大且复杂。
- 项目需求开始变得复杂起来。项目不断发展。
- 项目历时很长。
- 失败的代价非常高。
在现有的实现行为中进行覆盖测试是非常适合的。
- 项目是一个逐步更新的遗产。
- 你有一个还没有经过测试的项目要做。
在一些情况下,任何形式的自动化测试都是过于极端的:
- 项目很简单,也不会变得复杂。
- 过期不再工作的一次性项目。
假如你有很多的时间,在这种情况下进行自动测试也很好。
深度阅读
- 测试驱动开发:示例 / Kent Beck。 ISBN:0321146530。
Guide Caching Overview (`docs/guide/caching-overview.md`)
Caching
Caching is a cheap and effective way to improve the performance of a Web application. By storing relatively
static data in cache and serving it from cache when requested, the application saves the time that would be
required to generate the data from scratch every time.
Caching can occur at different levels and places in a Web application. On the server-side, at the lower level,
cache may be used to store basic data, such as a list of most recent article information fetched from database;
and at the higher level, cache may be used to store fragments or whole of Web pages, such as the rendering result
of the most recent articles. On the client-side, HTTP caching may be used to keep most recently visited page content in
the browser cache.
Yii supports all these caching mechanisms:
Guide Helper Overview (`docs/guide/helper-overview.md`)
Helpers
Note: This section is under development.
Yii provides many classes that help simplify common coding tasks, such as string or array manipulations,
HTML code generation, and so on. These helper classes are organized under the yii\helpers namespace and
are all static classes (meaning they contain only static properties and methods and should not be instantiated).
You use a helper class by directly calling one of its static methods, like the following:
use yii\helpers\Html;
echo Html::encode('Test > test');Note: To support customizing helper classes, Yii breaks each core helper class
into two classes: a base class (e.g.BaseArrayHelper) and a concrete class (e.g.ArrayHelper).
When you use a helper, you should only use the concrete version and never use the base class.
Core Helper Classes
The following core helper classes are provided in the Yii releases:
- ArrayHelper
- Console
- FileHelper
- FormatConverter
- Html
- HtmlPurifier
- Imagine (provided by yii2-imagine extension)
- Inflector
- Json
- Markdown
- StringHelper
- Url
- VarDumper
Customizing Helper Classes
To customize a core helper class (e.g. [[yii\helpers\ArrayHelper]]), you should create a new class extending
from the helpers corresponding base class (e.g. [[yii\helpers\BaseArrayHelper]]) and name your class the same
as the corresponding concrete class (e.g. [[yii\helpers\ArrayHelper]]), including its namespace. This class
will then be set up to replace the original implementation of the framework.
The following example shows how to customize the [[yii\helpers\ArrayHelper::merge()|merge()]] method of the
[[yii\helpers\ArrayHelper]] class:
<?php
namespace yii\helpers;
class ArrayHelper extends BaseArrayHelper
{
public static function merge($a, $b)
{
// your custom implementation
}
}Save your class in a file named ArrayHelper.php. The file can be in any directory, for example @app/components.
Next, in your application's entry script, add the following line of code
after including the yii.php file to tell the Yii class autoloader to load your custom
class instead of the original helper class from the framework:
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';Note that customizing of helper classes is only useful if you want to change the behavior of an existing function
of the helpers. If you want to add additional functions to use in your application, you may be better off creating a separate
helper for that.
Guide Runtime Overview (`docs/guide/runtime-overview.md`)
Overview
Each time when a Yii application handles a request, it undergoes a similar workflow.
- A user makes a request to the entry script
web/index.php. - The entry script loads the application configuration and creates
an application instance to handle the request. - The application resolves the requested route with the help of
the request application component. - The application creates a controller instance to handle the request.
- The controller creates an action instance and performs the filters for the action.
- If any filter fails, the action is cancelled.
- If all filters pass, the action is executed.
- The action loads a data model, possibly from a database.
- The action renders a view, providing it with the data model.
- The rendered result is returned to the response application component.
- The response component sends the rendered result to the user's browser.
The following diagram shows how an application handles a request.
In this section, we will describe in detail how some of these steps work.
Guide Security Overview (`docs/guide/security-overview.md`)
Security
Good security is vital to the health and success of any application. Unfortunately, many developers cut corners when it
comes to security, either due to a lack of understanding or because implementation is too much of a hurdle. To make your
Yii powered application as secure as possible, Yii has included several excellent and easy to use security features.
- Authentication
- Authorization
- Working with Passwords
- Cryptography
- Views security
- Auth Clients
- Best Practices
- Trusted proxies and headers
Guide Structure Overview (`docs/guide/structure-overview.md`)
Overview
Yii applications are organized according to the model-view-controller (MVC)
architectural pattern. Models represent data, business logic and rules; views
are output representation of models; and controllers take input and convert
it to commands for models and views.
Besides MVC, Yii applications also have the following entities:
- entry scripts: they are PHP scripts that are directly accessible by end users.
They are responsible for starting a request handling cycle. - applications: they are globally accessible objects that manage application components
and coordinate them to fulfill requests. - application components: they are objects registered with applications and
provide various services for fulfilling requests. - modules: they are self-contained packages that contain complete MVC by themselves.
An application can be organized in terms of multiple modules. - filters: they represent code that need to be invoked before and after the actual
handling of each request by controllers. - widgets: they are objects that can be embedded in views. They
may contain controller logic and can be reused in different views.
The following diagram shows the static structure of an application:
Guide Test Overview (`docs/guide/test-overview.md`)
Testing
Testing is an important part of software development. Whether we are aware of it or not, we conduct testing continuously.
For example, when we write a class in PHP, we may debug it step by step or simply use echo or die statements to verify
the implementation works according to our initial plan. In the case of a web application, we're entering some test data
in forms to ensure the page interacts with us as expected.
The testing process could be automated so that each time when we need to verify something, we just need to call up
the code that does it for us. The code that verifies the result matches what we've planned is called test and
the process of its creation and further execution is known as automated testing, which is the main topic of these
testing chapters.
Developing with tests
Test-Driven Development (TDD) and Behavior-Driven Development (BDD) are approaches of developing
software by describing behavior of a piece of code or the whole feature as a set of scenarios or tests before
writing actual code and only then creating the implementation that allows these tests to pass verifying that intended
behavior is achieved.
The process of developing a feature is the following:
- Create a new test that describes a feature to be implemented.
- Run the new test and make sure it fails. It is expected since there's no implementation yet.
- Write simple code to make the new test pass.
- Run all tests and make sure they all pass.
- Improve code and make sure tests are still OK.
After it's done the process is repeated again for another feature or improvement. If the existing feature is to be changed,
tests should be changed as well.
Tip: If you feel that you are losing time doing a lot of small and simple iterations, try covering more by your
test scenario so you do more before executing tests again. If you're debugging too much, try doing the opposite.
The reason to create tests before doing any implementation is that it allows us to focus on what we want to achieve
and fully dive into "how to do it" afterwards. Usually it leads to better abstractions and easier test maintenance when
it comes to feature adjustments or less coupled components.
So to sum up the advantages of such approach are the following:
- Keeps you focused on one thing at a time which results in improved planning and implementation.
- Results in test-covering more features in greater detail i.e. if tests are OK most likely nothing's broken.
In the long term it usually gives you a good time-saving effect.
When and how to test
While the test first approach described above makes sense for long term and relatively complex projects it could be overkill
for simpler ones. There are some indicators of when it's appropriate:
- Project is already large and complex.
- Project requirements are starting to get complex. Project grows constantly.
- Project is meant to be long term.
- The cost of the failure is too high.
There's nothing wrong in creating tests covering behavior of existing implementation.
- Project is a legacy one to be gradually renewed.
- You've got a project to work on and it has no tests.
In some cases any form of automated testing could be overkill:
- Project is simple and isn't getting any more complex.
- It's a one-time project that will no longer be worked on.
Still if you have time it's good to automate testing in these cases as well.
Further reading
- Test Driven Development: By Example / Kent Beck. ISBN: 0321146530.
Internals Ja Getting Started (`docs/internals-ja/getting-started.md`)
Yii 2 の開発を始めよう
環境をセットアップする方法については、Yii 2 寄稿者のための Git ワークフロー を参照してください。
Internals Pl Getting Started (`docs/internals-pl/getting-started.md`)
Jak zacząć proces współtworzenia Yii 2
Zobacz cykl produkcyjny Git dla kontrybutorów Yii 2, aby zapoznać się z informacjami o konfiguracji środowiska deweloperskiego.
Internals Ru Getting Started (`docs/internals-ru/getting-started.md`)
Подготовка к разработке Yii 2
Смотрите Рабочий процесс Git для разработчиков Yii 2 о том, как подготовить ваше рабочее окружение.
Internals Sr Latn Getting Started (`docs/internals-sr-Latn/getting-started.md`)
Kako započeti sa Yii 2 razvojem
Pogledajte Git proces rada za Yii 2 saradnike o tome kako podesiti vaše okruženje.
Internals Uk Getting Started (`docs/internals-uk/getting-started.md`)
Підготовка до розробки Yii 2
Інформація про те, як налаштувати середовище для розробки представлена у розділі Робота з Git для учасників Yii 2.
Internals Getting Started (`docs/internals/getting-started.md`)
Getting started with Yii 2 development
See Git workflow for Yii 2 contributors on how to set up your environment.
Documentation Style Guide (`docs/documentation_style_guide.md`)
Yii Documentation Style Guide
Guidelines to go by when writing or editing any Yii documentation.
This needs to be expanded.
General Style
- Try to use an active voice.
- Use short, declarative sentences.
- Demonstrate ideas using code as much as possible.
- Never use "we". It's the Yii development team or the Yii core team. Better yet to put things in terms of the framework or the guide.
- Use the Oxford comma (e.g., "this, that, and the other" not "this, that and the other").
Formatting
- Use italics for emphasis, never capitalization, bold, or underlines.
Lists
- Numeric lists should be complete sentences that end with periods.
- Bullet lists should be fragments that end with semicolon except the last item, which should end with a period.
Blocks
Blocks use the Markdown > Type: . There are four block types:
Warning, for bad security things and other problemsNote, to emphasize key concepts, things to avoidInfo, general information (an aside); not as strong as a "Note"Tip, pro tips, extras, can be useful but may not be needed by everyone all the time
The sentence after the colon should begin with a capital letter.
When translating documentation, these Block indicators should not be translated.
Keeps them intact as they are and only translate the block content.
For translating the Type word, each guide translation should have a blocktypes.json file
containing the translations. The following shows an example for German:
{
"Warning:": "Achtung:",
"Note:": "Hinweis:",
"Info:": "Info:",
"Tip:": "Tipp:"
}References
- Yii 2.0 or Yii 2 (not Yii2 or Yii2.0)
- Each "page" of the guide is referred to as a "section".
- References to Code objects:
- Refer to classes using the full namespace:
yii\base\Model - Refer to class properties using the static syntax even if they are not static:
yii\base\Model::$validators - Refer to class methods using the static syntax even if they are not static and include parenthesis to make it clear, that it is a method:
yii\base\Model::validate() - references to code objects should be written in
[[]]to generate links to the API documentation. E.g.[[yii\base\Model]],[[yii\base\Model::$validators]], or[[yii\base\Model::validate()]].
- Refer to classes using the full namespace:
Capitalizations
- Web, not web
- the guide or this guide, not the Guide
Validating the docs
The following are some scripts that help find broken links and other issues in the guide:
Find broken links (some false-positives may occur):
grep -rniP "\[\[[^\],']+?\][^\]]" docs/guide*
grep -rniP "[^\[]\[[^\]\[,']+?\]\]" docs/guide*Attribution of Translators
The names of the translators will be listed among the guide authors in the
rendered versions of the guide.
Therefor in each guide directory for a different language than english a translators.json file
should be created that contains an array of names of the people who have participated in the translation.
[
"Jane Doe",
"John Doe"
]If you have contributed a significant part to the translation, feel free to send a pull request adding your name.
Guide Ar Intro Yii (`docs/guide-ar/intro-yii.md`)
ما هي بيئة العمل Yii
Yii هو إطار PHP عالي الأداء يعتمد على المكونات لتطوير تطبيقات الويب الحديثة بسرعة.
إن الاسم "Yii" (يُنطق بـ "يي" أو "[جي:]" يعني "بسيطًا وتطوريًا" باللغة الصينية. ومن الممكن ايضا
اعتباره اختصارًا لـ Yes It Is!
ما هي أفضل التطبيقات أو البرمجيات التي يمكن برمجتها وتتناسب مع ال Yii
Yii هو إطار عام لبرمجة الويب ، مما يعني أنه يمكن استخدامه لتطوير كافة أنواع
تطبيقات الويب باستخدام PHP. وذلك بسبب البنية القائمة على البنية التركيبة لبيئة العمل وترابطها مع المكونات والتخزين المؤقت، وهو مناسب بشكل خاص لتطوير portals, forums, content management systems (CMS), e-commerce projects, RESTful Web services. وما إلى ذلك.
كيف يمكن مقارنة بيئة العمل الخاصة بال Yii مع الأطر أو بيئات العمل الأخرى؟
إذا كنت بالفعل على دراية بإطار العمل الأخرى ، فيمكنك معرفة كيف تتم مقارنة ال Yii:
<li> مثل معظم أطر عمل ال PHP ، يطبق Yii النمط المعماري MVC (Model-View-Controller).</li>ال Yii إطار عمل صمم من قبل فريق برمجي متكامل، فهو ليس مجرد عمل فردي ، بل يتكون من فريق تطوير أساسي وقوي ، بالإضافة إلى منتدى كبير
من المهنيين الذين يساهمون باستمرار في تطوير هذا الإطار. فريق المطورين الخاص بال Yii
يراقب عن كثب أحدث اتجاهات تطوير الويب وأفضل الممارسات والمميزات التي
وجدت في الأطر والمشاريع الأخرى. وتدرج بانتظام بإضافة أفضل الممارسات والميزات الى ال Yii عبر واجهات بسيطة وأنيقة.
الإصدارات الخاصة بال Yii
يتوفر لدى Yii حاليًا إصداران رئيسيان: 1.1 و 2.0. الإصدار 1.1 هو الجيل القديم وهو الآن في وضع الصيانة. الإصدار 2.0 هو إعادة كتابة وهيكلة كاملة لل Yii، تم اعتماد أحدث التقنيات والبروتوكولات فيها مثل including Composer, PSR, namespaces, traits والكثير من الأمور الأخرى، وفي هذه الإرشادات، سيكون الكلام كله موجها الى الإصدار الثاني من بيئة العمل ال Yii.المتطلبات الأساسية للعمل على إطار ال Yii
<li>الإصدار PHP 7.4.0 أو أكثر</li>
<li>المعرفة الأساسية بمفاهيم البرمجة كائنية التوجه OOP</li>
<li>المعرفة بآخر وأحدث التقنيات الموجودة بال php مثل ال namespaces, traits، الفهم لهذه المفاهيم سيسهل عليك العمل كثيرا</li>
ملاحظة: يمكن التحقق من توافق المتطلبات الخاصة بك مع ال yii من خلال الدخول الى الصفحة requirement الموجودة بال yiiGuide Ar Start Databases (`docs/guide-ar/start-databases.md`)
التعامل مع قواعد البيانات
في هذا الجزء التعليمي ستتعلم آلية إنشاء صفحة جديدة تعرض بيانات يتم جلبها من قاعدة البيانات -في هذا المثال، البيانات تخص ال country-، هذه البيانات سيتم جلبها من جدول موجود في قاعدة البيانات يسمى ب `country`. لتحقيق هذا المهمة، ستقوم بعمل ال config الخاص بالإتصال بقاعدة بيانات، بالإضافة لإنشاء ال [Active Record](../guide/db-active-record.md) class، وتعريف ال [action](../guide/structure-controllers.md)، وإنشاء [view](../guide/structure-views.md) لهذه الصفحة.في هذا الشرح ستتعلم كيف يمكنك القيام بما يلي:
<li>إعداد ال connection الخاص بقاعدة البيانات</li>
<li> التعرف على ال active record.</li>
<li>إنشاء جمل إستعلام عن البياتات بإستخدام ال active record class</li>
<li>عرض البيانات داخل ال view من خلال ال paginated fashion.</li>
ملاحظة: من أجل الانتهاء من هذا الجزء التعليمي، يجب أن يكون لديك المعرفة الأساسية والخبرة باستخدام قواعد البيانات. وعلى وجه الخصوص، يجب أن تعرف كيفية إنشاء قواعد البيانات، وكيفية تنفيذ ال statements SQL باستخدام أي DB client tool.إعداد قاعدة البيانات
في البداية، عليك إنشاء قاعدة بيانات تسمى ب `yii2basic`، والتي ستستخدم لجلب البيانات الخاصة بالتطبيق، ويمكنك إستخدام أي من ال SQLite, MySql, PostgreSQL, MSSQL or Oracle database, ال Yii بشكل افتراضي بدعم العديد من قواعد البيانات والتي يمكنك إستخدامها مباشرة في التطبيق الخاص بك، ولتبسيط الأمور، ال MySql هي التي سيتم إستخدامها في في هذا الشرح.
معلومة: إذا كنت ترغب بالحصول على خيارات متقدمة مثل دعم ال `JSON` الموجود داخل MariaDB، فيمكنك من إستخدام أحد ال Extension المذكوره بالأسفل للقيام بهذه المهمة بدلا من الإستغناء عن ال MySql، فإستخدام MariaDB بدلا عن ال MySql لم يعد صحيحا تماما.
بعد قيامك بإنشاء قاعدة البيانات، سنقوم بإنشاء جدول إسمه `country`، ومن ثم سنقوم بإدخال بعض البيانات كعينة للإختيار، وللقيام بذلك، قم بتنفيذ الأوامر التالية:CREATE TABLE `country` (
`code` CHAR(2) NOT NULL PRIMARY KEY,
`name` CHAR(52) NOT NULL,
`population` INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `country` VALUES ('AU','Australia',24016400);
INSERT INTO `country` VALUES ('BR','Brazil',205722000);
INSERT INTO `country` VALUES ('CA','Canada',35985751);
INSERT INTO `country` VALUES ('CN','China',1375210000);
INSERT INTO `country` VALUES ('DE','Germany',81459000);
INSERT INTO `country` VALUES ('FR','France',64513242);
INSERT INTO `country` VALUES ('GB','United Kingdom',65097000);
INSERT INTO `country` VALUES ('IN','India',1285400000);
INSERT INTO `country` VALUES ('RU','Russia',146519759);
INSERT INTO `country` VALUES ('US','United States',322976000);الآن، أصبح لديك قاعدة بيانات إسمها `yii2basic`، وتحوي بداخلها جدول بثلاث أعمدة يسمى ب `country`، وفيه 10 صفوف من البيانات.إعدادات الإتصال الخاصة بقواعد البيانات - Configuring a DB Connection
قبل أن تكمل الشرح، تأكد من تثبيت ال PHP [PDO](https://www.php.net/manual/en/book.pdo.php) وال PDO driver، بالنسبة لهذا المثال، فإننا سنستخدم ال driver الخاص بال MySql وهو ال `pdo_mysql`، وهذه هي المتطلبات الأساسية لبناء أي التطبيق اذا كان التطبيق يستخدم ال relational database. ملاحظة: يمكنك تقعيل ال PDO مباشرة من خلال الدخول الى php.ini ومن ثم حذف الفاصلة المنقوطة قبل السطر التالي: extension=php_pdo.dll
كما يمكنك تفعيل ال driver المطلوب عن طريق حذف الفاصلة المنقوطة قبل ال driver المقصود مثل:extension=php_pdo_mysql.dll
ويمكنك الإطلاع على المزيد من هنا:
pdo installation
بعد إتمام ما سبق، قم بفتح الملف `config/db.php` ومن ثم قم بتعديل ال parameters لتكون الإعدادات الخاصة بقاعدة البيانات صحيحة -الإعدادت الخاصة بك-، بشكل افتراضي، يحتوي الملف على ما يلي:<?php
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yii2basic',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
];يمثل ملف ال `config/db.php` أداة نموذجية تعتمد على الملفات للقيام بال [configuration](../guide/concept-configurations.md). يقوم ملف ال configuration بتحديد ال parameters المطلوبة لإنشاء وإعداد ال instance الخاص بال `[[yii\db\Connection]]`، ومن خلالها يمكنك إجراء عمليات الإستعلام على قاعدة البيانات. الإعدادات الخاصة بالإتصال بقاعدة البيانات والمذكورة في الملف أعلاه يمكن الوصول اليها من خلال التطبيق عن طريق تنفيذ الأمر التالي
Yii::$app->db
معلومة: سيتم تضمين ملف ال `config/db.php` من خلال ال main application configuration والذي يتمثل بالملف `config/web.php`، والذي يقوم بدوره بتحديد كيف يمكن تهيئة ال instance الخاص [بالتطبيق](../guide/concept-configurations.md)، لمزيد من المعلومات، يرجى الإطلاع على قسم ال [Configurations](../guide/concept-configurations.md).
إذا كنت بحاجة إلى العمل مع إحدى قواعد البيانات الغير مدعومة بشكل إفتراضي من ال Yii، فيمكنك التحقق من الإضافات التالية:
<li>[Informix](https://github.com/edgardmessias/yii2-informix)</li>إنشاء ال Active Record
لجلب البيانات وعرضها من جدول ال `country`، سنقوم بإضافة ال [Active Record](../guide/db-active-record.md) الى ال class المسمى ب `country`، والموجود في المسار `models/Country.php`.<?php
namespace app\models;
use yii\db\ActiveRecord;
class Country extends ActiveRecord
{
}يرث ال `Country` Class ال [[yii\db\ActiveRecord]]، ولذلك، أنت لست بحاجة لكتابة أي شيفرة برمجية بداخله، فقط الشيفرة التي تشاهدها بالأعلى. سيقوم ال Yii بشكل تلقائي بالحصول على إسم الجدول في قاعدة البيانات من خلال إسم ال Class.معلومة: إذا لم يكن من الممكن إجراء مطابقة مباشرة بين اسم ال class واسم الجدول، فيمكنك تجاوز هذه المشكلة من خلال إستخدام الدالة [[yii\db\ActiveRecord::tableName()]] ، والتي ستقوم بعمل override على اسم الجدول.
من خلال إستخدام ال `Country` class، يمكنك التحكم بكل سهولة بالبيانات الموجودة داخل جدول ال `country`، شاهد هذه الشيفرة البرمجية لتبسيط الفكرة:use app\models\Country;
// get all rows from the country table and order them by "name"
$countries = Country::find()->orderBy('name')->all();
// get the row whose primary key is "US"
$country = Country::findOne('US');
// displays "United States"
echo $country->name;
// modifies the country name to be "U.S.A." and save it to database
$country->name = 'U.S.A.';
$country->save();معلومة: يعتبر ال Active Record وسيلة قوية للوصول إلى بيانات قاعدة البيانات والتعامل معها بطريقة ال object oriented.
ستجد معلومات أكثر تفصيلاً في الجزء الخاص بال [Active Record](../guide/db-active-record.md). بالإضافة الى ذلك، يمكنك التفاعل مباشرة مع قاعدة البيانات باستخدام lower-level data accessing والتي تسمى ب [Database Access Objects](../guide/db-dao.md).إنشاء ال Action
لعرض بيانات ال country للمستخدمين، يلزمك إنشاء action جديد، وبدلاً من وضع ال action الجديد في ال site controller كما فعلنا في المرات السابقة، سنقوم بإنشاء controller جديد، ومن ثم سنقوم بوضع ال action بداخله، والسبب المنطقي لهذا العمل أنك ستقوم بتجميع الشيفرة البرمجية المسؤولة عن أداء وظائف معينة في مكان واحد، وبهذا فإن جميع الإجرائات التي تخص ال country من المنطقي أن تكون موجودة داخل ال CountryController، والآن لنقم بإنشاء هذا ال controller الجديد، وال action الجديد وسيكون باسم index، كما هو موضح أدناه:
<?php
namespace app\controllers;
use yii\web\Controller;
use yii\data\Pagination;
use app\models\Country;
class CountryController extends Controller
{
public function actionIndex()
{
$query = Country::find();
$pagination = new Pagination([
'defaultPageSize' => 5,
'totalCount' => $query->count(),
]);
$countries = $query->orderBy('name')
->offset($pagination->offset)
->limit($pagination->limit)
->all();
return $this->render('index', [
'countries' => $countries,
'pagination' => $pagination,
]);
}
}قم بحفظ الشيفرة البرمجية التي بالأعلى داخل هذا الملف `controllers/CountryController.php`
يقوم ال `index` action باستخدام ال `Country::find()`، وهذه الدالة موجودة من ضمن ال `active record`، وتقوم هذه الدالة على بناء الإستعلام الخاص بقاعدة البيانات مما يسمح باسترجاع جميع البيانات الموجودة بداخل جدول ال country، ولتحديد الحد الأعلى المسموح إرجاعه في كل request، يمكنك إستخدام ال `[[yii\data\Pagination]]` object كوسيلة مساعدة، ويقدم هذا ال object غرضين أساسيين وهما:
<li>كتابة جملة استعلام محددة بعدد صفوف معين، وتبدأ من مكان معين، ويتم ذلك من خلال ال `offset` وال `limit`، وبهذا التعيين فأنت ستقوم بإرجاع صفحة واحدة من البيانات وفي كل مرة سيتم عرض 5 صفوف على الأكثر. </li>
<li>كما يستخدم في صفحة ال view لعرض ال pager مع قائمة بال page buttons، وذلك كما ستشاهد في الجزء التالي من هذا الموضوع. </li>
في نهاية الشيفرة البرمجية الموجودة في ال `index` action، نقوم باستدعاء صفحة ال view المسمية ب `index`، ومن ثم نقوم بإرسال معلومات ال country المنظمة على شكل صفحات (pagination) ومن ثم عرضها.إنشاء View
الآن، سنقوم بإنشاء صفحة ال view والتي ستقوم بعرض المعلومات الخاصة بال country والقادمة من ال index action، ولذلك توجه الى المسار `views`, ومن ثم قم بإنشاء مجلد جديد بداخله باسم `country`، هذا المجلد سيحوي جمع ال views التي سيتم إستدعائها من ال `country` controller>. الآن، قم بإنشاء الصفحة index.php بداخل المسار `views/country`، ومن ثم قم بكتابة هذه الشيفرة البرمجية بداخلها:<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
?>
<h1>Countries</h1>
<ul>
<?php foreach ($countries as $country): ?>
<li>
<?= Html::encode("{$country->code} ({$country->name})") ?>:
<?= $country->population ?>
</li>
<?php endforeach; ?>
</ul>
<?= LinkPager::widget(['pagination' => $pagination]) ?>في هذه الصفحة، هناك جزئيين رئيسيين، الجزء الأول هو المسؤول عن طباعة المعلومات الخاصة بال country داخل قائمة من نوع ul، والجزء الثاني عبارة عن widget يستخدم المعلومات الخاصة بال pagination والتي تم إرسالها من ال action، ليقوم بعد ذلك بعرض قائمة من ال page buttons، والتي بدورها ستقوم بعمل تحديث للمعلومات الموجودة بالصفحة بنائا على الصفحة المطلوبة، هذا ال widget يسمى ب `LinkPager -[[yii\widgets\LinkPager]]-`.لنجرب المثال
لتشاهد آلية العمل لهذا المثال، والنتائج المتعلقة به، يمكنك إستخدام المتصفح والدخول الى الرابط التالي:https://hostname/index.php?r=country%2Findexفي البداية، ستشاهد البيانات الخاصة بخمسة دول، وأسفل هذه الدول، ستشاهد pager فيه 4 أزرار، اذا قمت بالضغط على الزر رقم 2، فإنك ستشاهد المعلومات الخاصة بخمسة دول أخرى، والتي تمثل صفوف أخرى من البيانات تم جلبها من قاعدة البيانات.
تابع بعناية أكبر وستجد أن عنوان ال URL في المتصفح قد تغير أيضًا:
https://hostname/index.php?r=country%2Findex&page=2بالخفاء، يقوم ال `[[yii\data\Pagination|Pagination]]` بتقديم الدعم اللازم لكل الوظائف المطلوب تنفيذها لعمل الترقيم الخاص بال pagination:
<li>في البداية، يمثل ال [[yii\data\Pagination|Pagination]] الصفحة الأولى التي تعكس جملة الإستعلام SELECT مع الجدول country مع العبارة `LIMIT 5 OFFSET 0`. ونتيجة لذلك، سيتم جلب البلدان الخمسة الأولى وعرضها.</li>
<li>ال [[yii\widgets\LinkPager|LinkPager]] widget يقوم على إستدعاء الأزرار الخاصة بأرقام الصفحات والتي يتم إنشاء ال Url الخاص بها من خلال ال [[yii\data\Pagination::createUrl()|Pagination]]، هذه ال Url تحتوي على parameter يسمى ب `page`، والذي يمثل بدورة مجموعة من الأرقام المختلفة والتي تمثل صفحات تعرض بيانات مختلفة كما هو في مثالنا عندما قمنا بالضغط على رقم 2.</li>
<li>عند قيامك بالنقر على الزر رقم 2، سينطلق request جديد الى ال `country/index` route، وحينها يقوم ال [[yii\data\Pagination|Pagination]] على قرائة ال `page` parameter من ال URL ,من ثم يقوم بتغيير رقم الصفحة الحالية الى الرقم الجديد، وهنا الرقم الجديد هو 2 بدلا من 1. كما أن جملة الإستعلام الجديدة ستحوي الشرط التالي `LIMIT 5 OFFSET 5` لتقم بذلك بجلب الصفوف الخمسة الأخرى من البلدان لعرضها.</li>الخلاصة
في هذا الجزء من التوثيق، لقد تعلمنا كيف يمكننا التعامل مع قواعد البيانات، وكيف يمكننا جلب البيانات وعرضها وتجزئتها لصفحات من خلال إستخدام ال [[yii\data\Pagination]] وال [[yii\widgets\LinkPager]].في الجزء القادم من هذا التوثيق، ستتعلم كيف يمكنك إستخدام إخدى الوسائل المميزة والموجودة في ال Yii لإنشاء الشيفرة البرمجية الخاصة بك، والتي يطلق عليها اسم Gii، هذه الأداة ستساعدك على إنشاء وتنفيذ الشيفرات البرمجية التي يكثر كتابتها وإستخدامها بشكل دوري، مثل مجموعة العمليات Create-Read-Update-Delete، والتي يتم اختصارها ب CRUD، هذه الأداة ستقوم بالتعامل مع البيانات الموجدة بقاعدة البيانات، وفي الحقيقة، الشيفرة البرمجية الذي قمت بكتابته بالأعلى، يمكنك إنشائه بسهولة من خلال ال Gii بنقرة زر، لذلك فلننطلق الى الجزء التالي بأسرع وقت.
Guide Ar Start Forms (`docs/guide-ar/start-forms.md`)
العمل مع ال Forms
في هذا الموضوع سنتعلم كيفية إنشاء صفحة تحتوي على form للحصول على البيانات من خلال المستخدمين، وستعرض هذه الصفحة form يحتوي على حقل لإدخال الإسم وحقل إدخال للبريد الإلكتروني.
وبعد الحصول على المعلومات الخاصة بهذه الحقول من المستخدم، ستقوم الصفحة بطباعة القيم التي تم إدخالها.
في هذا الشرح، ستقوم بإضافة [action](../guide/structure-controllers.md) وصحفتين [views](../guide/structure-views.md)، وستتعرف أيضا على طريقة إنشاء ال [model](../guide/structure-models.md).من خلال هذا البرنامج التعليمي ، ستتعلم كيفية:
<li>إنشاء model لتمثيل البيانات التي تم إدخالها من خلال المستخدم عن طريق ال form.</li>
<li>إنشاء rules للتحقق من صحة البيانات التي تم إدخالها.</li>
<li>بناء html form داخل صفحة ال view.</li>إنشاء ال Model
يتم تمثيل البيانات التي يتم طلبها من خلال المستخدم عن طريق ال `EntryForm` model class كما هو موضح أدناه، ويتم حفظ هذا الملف داخل المسار models، ويكون إسم ال model ومساره في مثالنا هذا هو `models/EntryForm.php`. يرجى الرجوع إلى صفحة ال [Class Autoloading](../guide/concept-autoloading.md) للحصول على مزيد من التفاصيل حول طريقة التعامل مع التسمية الخاصة بال class في Yii.<?php
namespace app\models;
use Yii;
use yii\base\Model;
class EntryForm extends Model
{
public $name;
public $email;
public function rules()
{
return [
[['name', 'email'], 'required'],
['email', 'email'],
];
}
}هذا ال class يرث ال [[yii\base\Model]], وهو base class تم تصميمه من خلال ال Yii, وبشكل عام وظيفته هي تثمثيل البيانات الخاصة بأي نموذج.معلومة: يتم إستخدام ال [[yii\base\Model]] كأصل لل model class ولا يرتبط بجداول قواعد البيانات. ويستخدم ال [[yii\db\ActiveRecord]] بالشكل الإعتيادي ليكون هو الأصل الذي من خلاله يتم الإرتباط بجداول بقواعد البيانات.
يحتوي class ال `EntryForm` على متغيرين إثنين من نوع Public، هما `name` و `email`، واللذان يستخدمان في تخزين البيانات التي أدخلها المستخدم. كما يحتوي أيضًا على method باسم `rules()`، والتي تُرجع مجموعةالشروط الخاصة بالبيانات للتحقق من صحتها. والشيفرة البرمجية الموجودة داخل ال rules method تعني:
<li>كل من ال `name` وال `email` حقول الزامية (required).</li>
<li>ال `email` حقل يجب أن يحتوي بداخله قيمة صحيحة تعبر عن البريد الإلكتروني (القواعد النحوية لكتابة البريد الإلكتروني).</li>
إذا كان لديك object من ال `EntryForm` ويحتوي على البيانات التي أدخلها المستخدم، فيمكنك حينها إستدعاء الدالة [[yii\base\Model::validate()|validate()]] للتحقق من صحة البيانات. اذا فشلت عملية التحقق من صحة البيانات، فسيؤدي ذلك إلى تغيير قيمة ال [[yii\base\Model::hasErrors|hasErrors]] إلى `true` ، بالإضافة الى ذلك يمكنك التعرف الى الأخطاء المتعلقة بهذه البيانات من خلال الدالة [[yii\base\Model::getErrors|errors]].<?php
$model = new EntryForm();
$model->name = 'Qiang';
$model->email = 'bad';
if ($model->validate()) {
// Good!
} else {
// Failure!
// Use $model->getErrors()
}إنشاء Action
الآن، ستحتاج إلى إنشاء `action` جديد في ال `site` controller وليكن إسمه `entry`، والذي سيقوم بدوره باستخدام ال model الجديد الذي قمنا بإنشائه. هذه العملية تم شرحها سابقا في الجزء التالي من التوثيق [Saying Hello - قل مرحبا](start-hello.md).<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\EntryForm;
class SiteController extends Controller
{
// ...existing code...
public function actionEntry()
{
$model = new EntryForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
// valid data received in $model
// do something meaningful here about $model ...
return $this->render('entry-confirm', ['model' => $model]);
} else {
// either the page is initially displayed or there is some validation error
return $this->render('entry', ['model' => $model]);
}
}
}أولا، يقوم ال action بإنشاء object من ال `EntryForm`. ثم يحاول تعبئة البيانات لل object من خلال ال `$ _POST`، والتي يتم تقديمها في ال Yii من خلال ال [[yii\web\Request::post()]].إذا تم ملء ال object بنجاح (على سبيل المثال، إذا قام المستخدم بإدخال البيانات داخل ال form ومن ثم قام بإرسالها(submitted html form))، فسيتم استدعاء ال [[yii\base\Model::validate()|validate()]] من خلال ال action للتأكد من صلاحية القيم المدخلة.
معلومة: يمثل التعبير Yii::$app ال [Application](../guide/structure-applications.md) instance الذي يمكن الوصول اليه من خلال ال singleton (singleton globally accessible). وهو أيضا [service locator](../guide/concept-service-locator.md) بحيث يوفر الدعم لل components مثل ال request, response, db..الخ، لدعم وظائف محددة. مثلا في المثال الموجود في الأعلى، فإن ال request هو component من ال application instance والذي يستخدم للوصول الى البيانات الموجودة داخل ال $_POST.
إذا كان كل شيء على ما يرام، فسوف يقوم ال action بجلب ال view التالية: `entry-confirm`، وذلك لتأكيد أن العملية قد تمت بنجاح بالنسبة للمستخدم، أما إن كانت البيانات غير صحيحة، أو لم يتم إرسال أي بيانات، فإن ال view `entry` هي التي سيتم جلبها وعرضها للمستخدم، حيث يتم عرض ال Html form، مع أي رسائل تحذير بخصوص الأخطاء التي تم العثور عليها من عملية التحقق.ملاحظة: في هذا المثال البسيط، نعرض صفحة التأكيد فقط عند إرسال البيانات بشكل صحيح. عند الممارسة العملية، يجب عليك استخدام [[yii\web\Controller::refresh()|refresh()]] أو [[yii\web\Controller::redirect()|redirect()]] لتجنب أي مشكلة تحصل عن طريق ال resubmission والتي تندرج تحت العنوان form resubmission problems.
إنشاء ال views
أخيرا، سنقوم بإنشاء صفحتين لل views الأولى بإسم `entry-confirm` والثانية `entry`. وهاتين الصفحتين سيتم جلبهم من خلال ال `entry` action.
ال `entry-confirm` ستقوم بكل بساطة بعرض الإسم والبريد الإلكتروني الذي تم إدخالهم من قبل المستخدم. ويجب حفظ هذه الصفحة بالمسار التالي: `views/site/entry-confirm.php`<?php
use yii\helpers\Html;
?>
<p>You have entered the following information:</p>
<ul>
<li><label>Name</label>: <?= Html::encode($model->name) ?></li>
<li><label>Email</label>: <?= Html::encode($model->email) ?></li>
</ul> صفحة ال entry ستقوم بعرض ال HTML form. هذه الصفحة يجب أن يتم حفظها داخل المسار التالي: views/site/entry.php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'email') ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>تستخدم ال view أسلوب مميز لبناء ال Forms، وذلك عن طريق ال [widget](../guide/structure-widgets.md) الذي يسمى ب [[yii\widgets\ActiveForm|ActiveForm]]. إن الأسلوب المستخدم في هذا ال widget يقوم على إستخدام كل من الدالة `begin()` و `end()` لجلب ال opening وال closing form tags على التوالي (فتحة ال tag، ثم الإغلاق الخاص بهذا ال tag)، وبين الفتحة والإغلاق يمكنك إنشاء الحقول عن طريق إستخدام الدالة [[yii\widgets\ActiveForm::field()|field()]]. في هذا المثال كان الحقل الأول في ال form يشير الى name data، والثاني يشير الى ال email data، وبعد هذه الحقول ستجد الدالة المستخدمة لإنشاء ال Submit button وهي [[yii\helpers\Html::submitButton()]].لنجرب المثال
لتشاهد آلية العمل لهذا المثال، والنتائج المتعلقة به، يمكنك إستخدام المتصفح والدخول الى الرابط التالي:
https://hostname/index.php?r=site%2Fentryعند دخولك الى الرابط السابق، سترى صفحة تعرض Html form يحتوي على حقلين لإدخال المعلومات. أمام كل حقل إدخال ستجد label يشير إلى البيانات المطلوب إدخالها. إذا قمت بالنقر فوق الزر "submit" بدون
أي إدخال، أو إذا لم تقم بكتابة عنوان البريد الإلكتروني بشكل صحيح، فستظهر لك رسالة خطأ بجوار الحقل المقصود.
بعد إدخالك لإسم وبريد الكتروني صحيح، وقيامك بالنقر على زر submit، فإنك ستشاهد صفحة جديدة تقوم بعرض البيانات التي قمت بإدخالها.كيف ظهر الخطأ؟ هل هو سحر؟!
قد تتساءل كيف يعمل ال Html form بالخفاء، وقد يبدو ذلك سحرا للوهلة الأولى، فهو يعرض ال label لكل حقل إدخال، ويعرض رسائل الخطأ إذا لم تقم بإدخال البيانات بشكل صحيح، وكل ذلك دون الحاجة لإعادة تحميل الصفحة.
إن السحر الموجود لدينا هنا، هو كيفية العمل الخاصة بالشيفرة البرمجية لل form، والتي تعمل بالخفاء، إن إجراء التحقق عن صحة البيانات يتم في البداية من جانب العميل -client side- وذلك باستخدام الجافا سكربت، ومن ثم -بعد تجاوز التحقق الخاص بالجافا سكربت- بتم تنفيذ التحقق من جانب ال server-side عبر ال PHP. ال [[yii\widgets\ActiveForm]] ذكية بما فيه الكفاية لاستخراج ال rule الخاصة بالتحقق والتي قمت بإنشائها وتعريفها داخل ال `EntryForm`، ومن ثم تحويل هذه القواعد إلى شيفرة برمجية بالجافا سكربت قابلة للتنفيذ، ومن ثم استخدام هذه الشيفرة من قبل الجافا سكربت لإجراء التحقق من صحة البيانات. في حال قمت بإيقاف الجافا سكربت في المتصفح الخاص بك، سوف يستمر إجراء التحقق من جانب الخادم -server side-، كما هو موضح في ال action المسمى `actionEntry()`. وهذا يضمن صحة البيانات في جميع الظروف.
تحذير: التحقق من جانب العميل -client side- يوفر تجربة أفضل للمستخدم، لكن يجب الأخذ بعين الإعتبار أن التحقق من جانب الخادم -server- مطلوب دائمًا، سواء تم التحقق من جانب العميل أم لا.
يتم إنشاء ال labels الخاصة بحقول الإدخال بواسطة الدالة `field()`، وذلك من خلال إستخدام أسماء ال property الموجودة داخل ال model. على سبيل المثال، سيتم إنشاء ال label التالي `Name` للproperty التالية: `name`.
كما يمكنك تعديل ال label الإفتراضي لأي حقل من خلال الشيفرة البرمجية التالية:<?= $form->field($model, 'name')->label('Your Name') ?>
<?= $form->field($model, 'email')->label('Your Email') ?>معلومة: يوفر ال Yii العديد من ال widgets لمساعدتك في إنشاء views معقدة وديناميكية بسرعة. كما أنك ستتعلم في وقت لاحق كيف يمكنك إنشاء widget جديد، وستكتشف أن الموضوع سهل وبسيط، مما سيدفعك إلى كتابة الشيفرة البرمجية الخاصة بك داخل ال widget، والذي بدوره سيجعل من هذه الشيفرة قابلة للتطوير والإستخدام في أكثر من مكان في المستقبل.الخلاصة
في هذا الجزء من التوثيق، تحدثنا عن كل جزء في ال MVC architectural pattern، لقد تعلمت الآن كيف يمكنك إنشاء model class ليقوم بتمثيل البيانات الخاصة بالمستخدمين، ومن ثم التحقق منها.
لقد تعلمت أيضًا كيفية الحصول على البيانات من المستخدمين، وكيفية عرض البيانات مرة أخرى في المتصفح. هذه المهمة يمكن أن تأخذ الكثير من الوقت عند تطوير أي تطبيق، ولكن، يوفر ال Yii العديد من ال widgets القوية، والتي تجعل من هذه المهمة أمرا سهلا للغاية.
في الجزء القادم من هذا التوثيق، ستتعلم كيف يمكنك التعامل مع قواعد البيانات، والتي سنحتاجها -غالبا- مع كل تطبيق ستعمل عليه تقريبا.Guide Ar Start Gii (`docs/guide-ar/start-gii.md`)
إنشاء الشيفرة البرمجية من خلال ال gii
في هذا الجزء التعليمي سنتعرف على آلية التعامل مع ال [Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide)، والذي يستخدم لإنتاج الشيفرة البرمجية الخاصة بمعظم الميزات والخصائص المشتركة في أغلب المواقع بشكل تلقائي، بالإضافة الى ذلك، فإن استخدام ال Gii لإنشاء الشيفرة البرمجية بشكل تلقائي يمثل مجموعة من المعلومات الصحيحة التي بتم إدخالها إعتمادا على التعليمات الموجودة في ال Gii Web Pages.
من خلال هذا البرنامج التعليمي، ستتعلم كيفية:
<li>تفعيل ال Gii داخل التطبيق الخاص بك</li>
<li>إستخدام ال Gii لإنشاء ال Active Record class</li>
<li>إستخدام ال Gii لإنشاء الشيفرة البرمجية الخاصة بال CRUD إعتمادا على الجداول الموجودة في قاعدة البيانات</li>
<li>تخصيص (customize) الشيفرة البرمجية التي سيتم إنتاجها من خلال ال Gii.</li>البدء باستخدام ال Gii
يتم تقديم ال [Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide) داخل على ال Yii على أنه [module](../guide/structure-modules.md)، ويمكنك تفعيله من خلال الإعدادات الخاصة به والتي تجدها داخل ال application، وبالتحديد داخل ال property التالية [[yii\base\Application::modules|modules]]، واعتمادا على كيفية إنشائك للمشروع، فيمكنك إيجاد الشيفرة البرمجية التالية موجودة بشكل مسبق داخل ال `config/web.php`:$config = [ ... ];
if (YII_ENV_DEV) {
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
];
}في الإعدادت الموجودة في الأعلى، فإن التطبيق سيقوم بتضمين وتفعيل ال gii في حال كانت الحالة الخاصة بالتطبيق هي [development enviroment](../guide/concept-configurations.md#environment-constants)، بالإضافة الى ذلك، فإنه يجب تضمين واستخدام ال module `gii`، والموجود ضمن ال class التالي [[yii\gii\Module]].
اذا قمت بالتحقق من ال [entry script](../guide/structure-entry-scripts.md) وبالتحديد صفحة ال `web/index.php` في التطبيق الخاص بك، ستجد هذه الأسطر، والتي يجب أن تجعل من ال `YII_ENV_DEV` ذات قيمة `true`.defined('YII_ENV') or define('YII_ENV', 'dev');كل الشكر لهذا السطر البرمجي، التطبيق الآن أصبح بحالة ال development mode، وأصبح لديك ال Gii enabled بالفعل، والآن، يمكنك الوصول الى ال Gii من خلال عنوان ال URL التالي:https://hostname/index.php?r=giiملاحظة: إذا كنت تحاول الوصول إلى Gii من جهاز آخر غير ال localhost، فسيتم رفض الوصول افتراضيًا لأغراض أمنية، ولكن، يمكنك إعداد ال Gii لإضافة مجموعة من ال IP Addresses المسموح لها بالوصول وذلك من خلال:'gii' => [
'class' => 'yii\gii\Module',
'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // عدل هذه حسب إحتياجاتك
],إنشاء ال Active Record Class من خلال ال Gii
لإستخدام ال Gii لإنشاء ال Active Record class, قم باختيار ال "Model Generator" (من خلال النقر على الرابط الموجود بالصفحة الرئيسية لل Gii)، ومن ثم قم بتعبئة ال form كما يلي:
<li>إسم الجدول: `country`</li>
<li>`Country` :Model Class</li>
والآن، قم بالنقر على الزر "Preview"، ستشاهد الآن `models/Country.php` قد تم إنشائها وإضافتها الى قائمة النتائج، اذا قمت بالنقر على إسم ال class، فإن المحتوى الخاص بهذا ال class سيتم عرضه.
عند استخدام ال Gii، إذا كنت قد قمت بالفعل بإنشاء نفس الملف وستقوم بعمل overwriting عليه، فيمكنك النقر على زر `diff` الموجود بعد إسم ال class، لتشاهد الفرق بين الشيفرة البرمجية الحالية، والشيفرة البرمجية الجديدة.
عند قيامك بعمل overwriting على ملف موجود، قم بالضغط على ال ckeckbox الموجودة بجانب كلمة overwrite، ومن ثم قم بالنقر على زر "Generate", اذا كان هذا الملف جديد، وغير موجود مسبقا، فيمكنك النقر مباشرة على "Generate"، بعد ذلك ستشاهد صفحة ال confirmation والتي تبين الشيفرات البرمجية التي تم إنشائها بنجاح.
بعد فيامك بالنقر على زر Generate، فإنك ستشاهد صفحة ال confirmation page، والتي تقوم بدورها بتوضيح الشيفرات البرمجية التي تم إنشائها بنجاح، واذا كان الملف موجود، فإنك ستشاهد أيضا رسالة تعلمك بأن الملف قد تم تعديله وتمت إضافة الشيفرة الجديدة مكان القديمة.إنشاء ال CRUD Code
ال CRUD هي اختصار ل Create, Read, Update, And Delete (إنشاء، وقرائة، وتحديث، وحذف)، والتي تمثل أكثر المهمات المطلوبة للتعامل مع البيانات على مواقع الويب. ولإنشاء ال CRUD باستخدام ال Gii، قم باختيار ال "CRUD Generator" (من خلال النقر على الرابط الموجود بالصفحة الرئيسية لل Gii)، وهنا وبالبنسبة للمثال الخاص بال "country"، يمكنك تعبئة ال from بما يلي:Model Class:
app\models\CountrySearch Model Class:
app\models\CountrySearchController Class:
app\controllers\CountryControllerبعد ذلك، قم بالنقر على زر ال "Preivew"، وستشاهد قائمة بالملفات التي سيتم إنشائها كما في الصورة أدناه.
اذا قمت إنشاء الصفحتين
controllers/CountryController.phpوviews/country/index.phpعند حديثنا سابقا عند موضوع (التعامل مع قواعد البيانات)، فقم بالضغط على ال "overwrite" ليتم إستبدالهم. (الصفحات القديمة لا توجد فيها كل الخصائص التي سيتم إنتاجها من خلال ال Gii CRUD).
لنجرب المثال
لتشاهد آلية العمل لهذا المثال، والنتائج المتعلقة به، يمكنك إستخدام المتصفح والدخول الى الرابط التالي:
https://hostname/index.php?r=country%2Findexعند دخولك إلى الرابط أعلاه، ستشاهد مجموعة الدول التي تم إستدعائها من جدول ال country من قاعدة البيانات، ويمكنك التعامل مع هذا ال grid من حيث الترتيب أو التصفية بنائا على الشروط التي ستقوم بإدخالها في مربعات النص أعلى الأعمدة.لكل دولة تم جلبها وعرضها داخل ال Grid، هناك مجموعة من الخيارات التي يمكنك التعامل معها بشكل إفتراضي، مثل ال view لعرض التفاصيل الخاصة بالدولة المختارة، أو تحديث المعلومات، الخاصة بالدولة، أو حذف هذه الدولة، بالإضافة إلى ذلك يمكنك النقر على "Create Country" الموجودة في أعلى ال Grid والتي ستأخذك بدورها الى صفحة تحتوي form لإنشاء ال country.
فيما يلي قائمة بالملفات التي تم إنشاؤها من خلال ال Gii، في حالة رغبتك في التحقق من كيفية عمل هذه الميزات والإطلاع على الشيفرة البرمجية وتخصيصها حسب الرغبة:- Controller:
controllers/CountryController.php - Models:
models/Country.phpandmodels/CountrySearch.php - Views:
views/country/*.php
معلومة: تم تصميم ال Gii لتكون أداة إنشاء شيفرات برمجية قابلة للتخصيص بشكل كبير للغاية. اذا قمت باستخدامه بحكمة،فإنك ستقوم بتسريع وتيرة التطوير الخاصة بالتطبيق الخاص بك. لمزيد من التفاصيل، يرجى الذهاب إلى الجزء الخاص بال Gii.
الخلاصة
في هذا الجزء من التوثيق، لقد تعلمنا آلية استخدام ال Gii لإنشاء الشيفرة البرمجية الخاصة بال CRUD، وتحدثنا عن الوظائف التي تقوم فيها، وكيف يمكننا من خلالها إتمام العمليات الخاصة بالبيانات من إدخال وتحديث وحذف وعرض للبيانات من قاعدة البيانات.
Guide Ar Start Hello (`docs/guide-ar/start-hello.md`)
قل مرحبا - Saying Hello
في هذا الموضوع سنتعرف على كيفية إنشاء صفحة "Hello" جديدة في التطبيق الذي قمت بتثبيته، ولتحقيق ذلك، يجب عليك القيام بإنشاء [action](../guide/structure-controllers.md#creating-actions) و [view](../guide/structure-views.md) لهذه الصفحة:
<li>سيقوم التطبيق بإرسال ال request الخاص بالصفحة إلى ال action.</li>
<li>وسيقوم ال action بدوره في جلب ال view التي تعرض كلمة "Hello" إلى المستخدم النهائي.</li>
من خلال هذا البرنامج التعليمي ، ستتعلم ثلاثة أشياء:- كيفية إنشاء [action](../guide/structure-controllers.md#creating-actions) ليقوم بإستقبال ال request ومن ثم الرد (respond) عليها.
- كيفية إنشاء [view](../guide/structure-views.md) وإضافة المحتوى الى ال respond.
- و كيفية إنشاء التطبيق لل requests التي يوجهها لل [actions](../guide/structure-controllers.md#creating-actions).
إنشاء ال Action
لإنشاء صفحة "Hello"، ستقوم بإنشاء `say` [action](../guide/structure-controllers.md#creating-actions) والذي بدوره سيقوم بقراءة ال `message` parameter من ال request، ومن ثم عرض ال `message` مرة أخرى إلى المستخدم. إذا كان ال request لا يحمل معه ال message parameter فإن ال action سيقوم بطباعة message إفتراضية وهي "Hello".
معلومة: ال [Actions](../guide/structure-controllers.md#creating-actions) هي الكائنات(objects) التي يمكن للمستخدمين من الوصول اليها وتنفيذ ما في بداخلها بشكل مباشر. يتم تجميع هذه ال Actions بواسطة ال [controllers](../guide/structure-controllers.md). ونتيجة لذلك فإن ال response الراجعة للمستخدم ستكون هي نتيجة التنفيذ الخاصة بال action.
يجب تعريف ال actions داخل ال [controller](../guide/structure-controllers.md)، ولتبسيط الفكرة، سنقوم بتعريف ال `say` action داخل أحد ال controller الموجود مسبقا وهو ال `siteController`. هذا ال controller ستجده داخل المسار `controllers/siteController.php`. ومن هنا سنبدأ بإضافة ال action الجديد:<?php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
// ...existing code...
public function actionSay($message = 'Hello')
{
return $this->render('say', ['message' => $message]);
}
}في الشيفرة البرمجية السابقة ، تم تعريف ال `say` action من خلال إنشاء الدالة `actionSay` داخل الكلاس `siteController`. يستخدم ال Yii كلمة action ك prefix للدوال للتميز بين الدوال ال action و ال non-action في ال controller، كما يستخدم الإسم الخاص بال action مباشرة بعد ال prefix، ويتم عمل mapping بين ال action method name وال action id ليستطيع المستخدم من الوصول للدالة المنشئة من خلال ال action id.
عندما يتعلق الأمر بتسمية ال action الخاصة بك، يجب عليك أن تفهم كيف يقوم ال Yii بالتعامل مع ال action id، ال action id يجب أن يكون دائما أحرف lower case، وإذا إحتوى ال action id على عدة كلمات فإن الفاصل بينهم سيكون الداش (dashes) مثل `create-comment`، ويتم ربط ال action id بال action method name من خلال حذف ال dashes من ال IDs، ويتم عمل capitalizing لأول خرف من كل كلمة، وإضافة ال prefix الى الناتج السابق من التحويل. مثال: ال action id المسمى ب `create-comment` سيتم تحويله الى ال action method name التالي: `actionCreateComment`.
في المثال السابق، يقوم ال action method على إستقبال parameter يسمى ب `$message`، والذي يملك قيمة إفتراضية وهي `"Hello"` (وهي مشابة تماما لطريقة وضع القيم الإفتراضية لل argument في ال PHP). عندما يستقبل التطبيق ال request ويحدد أن ال action المطلوب للتعامل مع الطلب (request) هو `say`، فإن التطبيق سيقوم بإسناد القيمة الموجودة بال request الى ال parameter الموجود بال action بشرط أن يكون الإسم الموجود بال request هو نفسه الموجود في ال action. ولتبسيط الموضوع يمكن القول أن ال request اذا احتوى على كلمة `message` وقيمة هذا ال parameter هي `"GoodBye"`، فإن ال `$message` الموجودة في ال action ستصبح قيمتها `"GoodBye"`.
من خلال ال action method، يتم استدعاء ال [[yii\web\Controller::render()|render()]] لتقديمالملف الخاص بال view والمسمى هنا ب say. أيضا فإن ال message يتم تمرريرها الى ال view مما يسمح لك باستخدام هذا ال parameter داخل ال view. النتيجة المرجعة لل view تتم معالجتها وإرجاعها من خلال ال action method، وهذه النتائج سيتم إستقبالها من خلال المتصفح الخاص بالمستخدم ليتم عرضها وكأنها (جزء من صفحة Html كاملة).
إنشاء ال View
ال [Views](../guide/structure-views.md) هي شيفرات برمجية كتبت ﻹنشاء المحتوى المناسب بنائا على ال response الراجع اليها من خلال ال action.
بالنسبة إلى مثال "Hello" ، الآن سنقوم بإنشاء view مسمى ب `say`، والذي سيقوم بدوره بطباعة ال `message` التي تم إستلامها من ال action، شاهد المثال:<?php
use yii\helpers\Html;
?>
<?= Html::encode($message) ?>صفحة ال view `say` يجب أن يتم حفظها داخل المسار التالي: `views/site/say.php`. عندما يتم إستدعاء الدالة [[yii\web\Controller::render()|render()]] من قبل ال action، فإنه سينظر للمسار على الشكل التالي: `views/ControllerID/ViewName.php`، بحيث يكون في مثالنا السابق ال ContollerID هو ال `site` وال viewName هو `say`.
ملاحظة: في الشيفرة البرمجية أعلاه، تكون ال `message` مضمنة داخل ال [[yii\helpers\Html::encode()]] قبل أن يتم طباعتها، هذا الأمر ضروري لأن ال parameter التي تأتي من المستخدم النهائي لا يجب الوثوق بها، فهي يمكن أن تحتوي على شيفرات برمجية تستغل الضعف الحاص بك بموضوع الأمان مثل [vulnerable to XSS attack](https://en.wikipedia.org/wiki/Cross-site_scripting) عن طريق دمج JS code مع ال parameter.
وبطبيعة الحال، يمكنك وضع المزيد من المحتوى في صفحة ال `say` view. ويمكن أن يتكون هذا المحتوى من HTML tag و plain text وحتى PHP statements.في الواقع، تعد ال say view مجرد شيفرة برمجية بلغة ال PHP والتي يتم تنفيذها بواسطة [[yii\web\Controller::render()|render()]].
المحتوى الذي سيتم طباعته من خلال ال view سيتم إرجاعه الى التطبيق من خلال ال response، وسيقوم التطبيق بدوره بإخراج هذه النتيجة إلى المستخدم النهائي.
تطبيق المثال
بعد إنشاء ال action وصفحة ال view، يمكنك الوصول إلى الصفحة الجديدة عن طريق عنوان URL التالي:
https://hostname/index.php?r=site%2Fsay&message=Hello+Worldسينتج عن هذا ال URL صفحة تعرض "Hello World". هذه الصفحة لديها نفس ال Header و ال Footer لصفحات التطبيق الأخرى.
إذا قمت بحذف ال `message` parameter من ال URL ، فسترى الصفحة تعرض كلمة `" Hello "` فقط. ويرجع ذلك إلى أن "message" يتم تمريرها ك parameter إلى ال `actionSay()`، وعندما يتم حذفها، سيتم استخدام القيمة الافتراضية وهي `"Hello"` بدلاً من ذلك.
معلومة: تتشارك الصفحة الجديدة مع الصفحات الأخرى بالتطبيق بنفس ال Header وال Footer وذلك بسبب الدالة [[yii\web\Controller::render() | render ()]] والتي ستقوم بشكل تلقائي بتضمين النتيجة الخاصة بصفحة ال view `say` مع صفحة ال [Layout](../guide/structure-views.md#layouts)، والتي يمكنك أن تجدها داخل المسار التالي: `views/layouts/main.php`
ال `r` الموجودة في ال URL أعلاه يتطلب الكثير من الشرح. ولكن باختصار يمكن القوم أنها اختصار ل [route](../guide/runtime-routing.md) ، وهو معرف فريد من نوعه(unique ID) للتطبيق بحيث يقوم بالتأشير على ال action، والصيغة الخاصة بال route هي `ControllerID/ActionID`. عندما يتلقى التطبيق request، فإنه سيتم التحقق من `r` parameter، فيقوم باستخدام الجزء `ControllerID` لتحديد ال controller class المطلوب ليقوم بعمل instance منه، ومن ثم يقوم ال controller باستخدام ال `"ActionID"` لتحديد ال action المطلوب والذي سيقوم بالعمل الفعلي. في المثال الخاص بنا، فإن ال route هو "site/say"، وهذا ال route يتم معالجته ليستدعي ال controller class المسمى ب SiteController و ال action المسمى ب actionSay داخل هذا ال controller، ونتيجة لذلك سيتم فعليا إستدعاء الدالة SiteController::actionSay() لتقوم بمعالجة ال request كما يلزم.
معلومة: مثل ال actions، تحتوي ال controllers أيضًا على Uniquely IDs يتم تعريفها واستخدامها من خلال التطبيق. تستخدم ال Controllers IDs نفس قواعد التسمية الخاصة بال action IDs، ويتم ذلك من خلال حذف ال dashes و capitalizing أول حرف من كل كلمة، ثم إضافة كلمة `Controller` الى الإسم الناتج -وهنا الإختلاف عن ال action ID-. مثال: ال controller ID المسمى ب `"post-comment"` ستم معالجته ليصبح `PostCommentController`.الخلاصة
في هذا الموضوع، قمنا بالتعرف على ال controller وال view كأجزاء من MVC architectural pattern، كما قمنا بإنشاء action داخل controller موجود ليستقبل specific request ويتحكم فيه، وقمنا أيضا بإنشاء view لعرض المحتوى. في هذا المثال البسيط، لم نتطرق الى ال model، وقمنا فقط باستخدام ال data بشكل مباشر من خلال ال `message` parameter.
كما تعرفنا أيضا على ال routes في ال Yii، والتي تعمل بدورها كجسر بين ال user request وال controller actions.
في الموضوع القادم، ستتعلم كيف يمكنك إنشاء model وكيف يمكنك إنشاء صفحة جديدة تحتوي على Html form.Guide Ar Start Installation (`docs/guide-ar/start-installation.md`)
تثبيت ال Yii
يمكنك تثبيت ال Yii بطريقتين ، الأولى باستخدام مدير الحزم Composer أو عن طريق تنزيل Archive File. الطريقة الأولى هي الطريقة المفضلة للعمل، ، لأنها تتيح لك تثبيت [extensions - ملحقات أو اضافات] جديدة، أو تحديث إطار العمل Yii ببساطة عن طريق تشغيل أمر واحد فقط.
التثبيت الإفتراضي لل Yii ينتج عنه بنية تركيبة منظمة ومرتبة للمجلدات والملفات التي بداخلها، ويوفر هذا الكلام بعض المميزات التي يتم إضافتها وإنشائها بشكل تلقائي مثل صفحة تسجيل الدخول، ونموذج اتصل بنا...الخ، هذا الأمر سيشكل نقطة إنطلاق جيدة لبدء العمل على أي مشروع.
في هذه الصفحة من التوثيق سنقوم بشرح ووصف كيف يمكن تثبيت إطار العمل Yii وبالتحديد Yii2 Basic Project Template.
هناك Template آخر موجود بإطار العمل Yii وهو [Yii2 Advanced Project Template](https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide)، وهو الأفضل للعمل وإنشاء المشاريع لفريق عمل برمجي، ولتطوير المشاريع متعددة الطبقات(multiple tires).معلومة: قالب المشروع الأساسي (Basic) مناسب لتطوير 90% من تطبيقات الويب. ويختلف القالب المتقدم (Advanced Template) عن القالب الأساسي في كيفية تنظيم وهيكلة الشيفرة البرمجية.
اذا كنت جديدا في عالم تطوير تطبيقات الويب باستخدام ال Yii، فإننا نوصيك بقوة بأن تستخدم القالب الأساسي في بناء المشروع الخاص بك.
تثبيت ال Yii من خلال (Composer)
تثبيت ال Composer
إن لم يكن لديك Composer مثبت مسبقا، فيمكنك السير بخطوات تثبيته من خلال الدخول الى هذا الرابط https://getcomposer.org/download/.
لتثبيت ال Composer في كل من نظامي Linux و Max OS X، يمكنك تنفيذ الأوامر التالية:
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composerولنظام ويندوز يمكنك تثبيت ال [Composer-Setup.exe](https://getcomposer.org/Composer-Setup.exe) ومن ثم عمل runيرجى الدخول الى Troubleshooting section of the Composer Documentation في حال واجهتك أي مشاكل متعلقة بال composer, وإذا كنت مستخدمًا جديدًا لل composer، ننصحك أيضًا بقراءة قسم الاستخدام الأساسي على الأقل من التوثيف الخاص بال composer.
في هذا الدليل ، نفترض أنك قمت بتثبيت ال composer على مستوى جميع المشاريع ([globally](https://getcomposer.org/doc/00-intro.md#globally)) بحيث تكون أوامر ال composer متاحة لجميع المشاريع من أي مكان. أما إذا كنت تستخدم ال composer.phar لمسار محدد فقط(local directory)، فيجب عليك ضبط الأومر وفقًا لذلك.إذا كان ال composer مثبتًا من قبل، فتأكد من استخدام إصدار حديث. يمكنك تحديث ال composer عن طريق تنفيذ الأمر التالي composer self-update
ملاحظة مهمة: أثناء تثبيت ال Yii ، سيحتاج ال composer إلى طلب(request) الكثير من المعلومات من ال Github Api. يعتمد عدد الطلبات على عدد dependencies التي يمتلكها التطبيق الخاص بك، وقد يكون هذا العدد أكبر من الحد المسموح به من قبل ال Github Api (Github API rate limit). إذا وصلت الى الحد الأعلى المسموح به من الطلبات، فقد يطلب منك ال composer بيانات تسجيل الدخول إلى Github، وذلك للحصول على رمز (token) للدخول إلى Github Api. اذا كانت عمليات الإتصال سريعة، فقد تصل إلى هذا الحد(limit) قبل أن يتمكن ال composer من التعامل معه ، لذالك نوصي بتكوين رمز الدخول(access token) قبل تثبيت ال Yii. يرجى الرجوع إلى التوثيق الخاص بال Composer والإطلاع على التعليمات الخاصة Github API tokens للحصول على الإرشادات اللازمة للقيام بذلك.
تثبيت ال Yii
من خلال ال Composer، يمكنك الآن تثبيت ال Yii من خلال تنفيذ سطر الأوامر التالي داخل أي مسار يمكن الوصول اليه من قبل الويبcomposer create-project --prefer-dist yiisoft/yii2-app-basic basicسطر الأوامر السابق سيقوم بتثبيت أحدث نسخة مستقرة(stable) من إطار العمل Yii داخل مسار جديد اسمه basic، ويمكنك التعديل على سطر الأوامر السابق لتغيير اسم المشروع لأي اسم ترغب فيه.معلومة: اذا واجهتك أي مشكلة عند تنفيذ السطر composer create-project فيمكنك الذهاب إلى قسم استكشاف الأخطاء في ال composer.
في معظم الأخطاء الشائعة، وعند حل المشكلة أو الخطأ، يمكنك إكمال التثبيت من خلال الدخول الى المسار basic ومن ثم تنفيذ الأمر التالي: composer update.
تلميح: اذا كنت ترغب بتثبيت أحدث نسخة خاصة بالمطورين من ال Yii، فيمكنك ذلك من خلال إضافة الخيار [stability](https://getcomposer.org/doc/04-schema.md#minimum-stability) وذلك من خلال سطر الأوامر التالي:composer create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basicملاحظة: نسخة المطورين من ال Yii يجب أن يتم إستخدامها للمواقع الإلكترونية التي لن تصدر كنسخة نهائية للمستخدم(Not for production) لأن ذلك يمكن أن يسبب بإيقاف المشروع أو الشيفرة البرمجية الخاصة بك.تثبيت ال Yii من خلال ال Archive File
يتضمن تثبيت Yii من ملف أرشيف ثلاث خطوات وهي:
- تثبت الملف من خلال الموقع الرسمي [yiiframework.com](https://www.yiiframework.com/download/).
- قم بفك ضغط الملف الذي تم تنزيله إلى مجلد يمكن الوصول إليه عبر الويب.
- قم بتعديل ملف `config/web.php` عن طريق إدخال secret key ل` cookieValidationKey` (يتم ذلك تلقائيًا إذا قمت بتثبيت ال Yii باستخدام Composer):
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'enter your secret key here',خيارات تثبيت أخرى
توضح تعليمات التثبيت أعلاه كيفية تثبيت ال Yii ، والذي يقوم أيضًا بإنشاء تطبيق ويب أساسي(basic).
هذا النهج هو نقطة انطلاق جيدة لمعظم المشاريع، صغيرة كانت أو كبيرة. خصوصا اذا كنت قد بدأت تعلم ال Yii من وقت قريب.
لكن، هناك خيارات أخرى متاحة لتثبيت ال Yii وهي:
تثبيت ال Assets
تعتمد ال Yii على حزم [Bower](https://bower.io/) و/أو [NPM](https://www.npmjs.com/) لتثبيت مكتبات ال (CSS و JavaScript). ويستخدم ال composer للحصول على هذه المكتبات ، مما يسمح بالحصول على إصدارات ال PHP و CSS/JavaScript في نفس الوقت. ويمكن تحقيق ذلك إما عن طريق استخدام [asset-packagist.org](https://asset-packagist.org/) أو من خلال ال [composer asset plugin](https://github.com/fxpio/composer-asset-plugin)، يرجى الرجوع إلى [Assets documentation](../guide/structure-assets.md) لمزيد من التفاصيل.قد ترغب في إدارة ال assets عبر ال native Bower/NPM أو استخدام ال CDN أو تجنب تثبيت ال assets بالكامل من حلال ال Composer ، ويمكن ذلك من خلال إضافة الأسطر التالية إلى "composer.json":
"replace": {
"bower-asset/jquery": ">=1.11.0",
"bower-asset/inputmask": ">=3.2.0",
"bower-asset/punycode": ">=1.3.0",
"bower-asset/yii2-pjax": ">=2.0.0"
},ملاحظة: في حالة تجاوز تثبيت ال assets عبر ال Composer، فأنت المسؤول عن تثبيت ال assets وحل مشكلات التعارض بين الإصدارات والمكتبات المختلفة. وكن مستعدًا لعدم تناسق محتمل بين ملفات ال asstes والإضافات المختلفة.
التحقق من التثبيت
بعد الانتهاء من التثبيت، ستحتاج الى القيام بإعداد خادم الويب الخاص بك(your web server) (انظر القسم التالي) أو قم باستخدام [built-in PHP web server](https://www.php.net/manual/en/features.commandline.webserver.php) عن طريق تنفيذ الأمر التالي داخل المسار web في المشروع الخاص بك:php yii serveملاحظة: افتراضيًا ال HTTP-server يعمل على البورت 8080. ومع ذلك ، إذا كان هذا البورت قيد الاستخدام بالفعل أو كنت ترغب في تشغيل أكثر من تطبيق بهذه الطريقة، حينها سيلزمك تحديد البورت الذي يجب استخدامه. ما عليك سوى إضافة --port:
php yii serve --port=8888يمكنك استخدام الرابط الموجود في الأسفل للوصول الى تطبيق ال Yii الذي قمت بتثبيته وتنفيذ الأوامر السابقة عليه.http://localhost:8080/اذا كانت كل الإعدادات السابقة تعمل بشكل صحيح، فيجب أن ترى الصورة الموجودة بالأعلى "Congratulations!" على المتصفح. إذا لم يكن كذلك، يرجى التحقق مما إذا كان تثبيت الPHP الخاص بك متوافق مع متطلبات ال Yii. يمكنك التحقق من ذلك باستخدام أحد الأساليب التالية:
<li>قم بنسخ الملف `/requirements.php` الى المسار `/web/requirements.php` بحيث يمكنك الوصول الى الصفحة من خلال الرابط التالي: `http://localhost/requirements.php`</li>
<li>قم بتنفيذ الأوامر التالية: <code>
cd basic
</code>`php requirements.php`</li>
يجب عليك أن تقوم بتثبيت وإعداد ال PHP الخاص بك بحيث تلبي الحد الأدنى من متطلبات ال Yii. الأهم من ذلك يجب أن يكون الإصدار الخاص بال PHP أعلى أو يساوي 5.4. من الناحية المثالية أحدث إصدار يعمل مع ال Yii هو ال PHP 7. يجب عليك أيضًا تثبيت ال [PDO PHP Extension](https://www.php.net/manual/en/pdo.installation.php).إعداد ال Web Servers
معلومة: يمكنك تخطي هذا الجزء الآن إذا كنت تختبر فقط إطار العمل Yii دون أي نية لنشر هذا التطبيق على الويب(بدون رفع التطبيق على production server).
يجب أن يعمل التطبيق الذي تم تثبيته وفقًا للتعليمات المذكورة أعلاه مع أي من الخوادم ال [Apache HTTP](https://httpd.apache.org/) أو ال [Nginx HTTP](https://nginx.org/) في كل من أنظمة التشغيل Windows, Mac OS X أو Linux ممن لديها إصدار أعلى أو يساوي PHP 5.4، كما أن ال Yii 2.0 متوافق مع ال Facebook [HHVM](https://hhvm.com/)، لكن، يجب أن تأخذ بعين الإعتبار أن ال HHVM يسلك في بعض الأحيان بطريقة مختلفة عن ال Native PHP، لذلك يجب أن تأخذ عناية إضافية عندما تعمل على ال HHVM.
على ال production server، قد ترغب في إعداد خادم الويب الخاص بك بحيث يمكن الوصول إلى التطبيقالخاص بك عبر ال URL التالي https://www.example.com/index.php بدلاً من https://www.example.com/basic/web/index.php. هذا الكلام يتطلب إنشاء إعداد يقوم بتوجيه ال document root الموجود على ال web server الى مجلد ال basic/web، كما قد ترغب أيضا بإخفاء ال index.php من ال URL كما هو موضح في ال Routing and URL Creation. في هذا الموضوع ستتعلم كيف يمكنك إعداد ال Apache أو ال Nginx server لتحقيق هذه الأهداف.
معلومة: من خلال تعيين ال `basic/web` ك `document root`، فإنك بذلك تمنع أيضًا المستخدمين النهائيين من الوصول الى الشيفرة البرمجية الخاصة بالتطبيق الخاص بك، وتمنعهم من الوصول الى الملفات الحساسة والمهمة والمخزنة في sibling directories من `basic/web`، ويعبر رفض الوصول الى المجلدات الأخرى تحسينا أمنيا مهما، يساعد في الحفاظ على مستوى أعلى من الحماية.معلومة: إذا كان سيتم تشغيل التطبيق الخاص بك في بيئة استضافة مشتركة(shared hosting) حيث ليس لديك الصلاحية لتعديل الإعدادات الخاصة بال web server، ستحتاج حينها الى تعديل في البنية الخاصة بالمشروع للحصول على أفضل أمان ممكن. يرجى الرجوع إلى Shared Hosting Environment لمزيد من المعلومات.
معلومة: إذا كنت تقوم بتشغيل تطبيق ال Yii بوجود ال proxy، فقد تحتاج إلى إعداد التطبيق ليكون ضمن ال [trusted proxies and header](../guide/runtime-requests.md#trusted-proxies).الإعدادات الموصى بها لل Apache
استخدم الإعدادات التالية في ملف ال `httpd.conf` في Apache أو ضمن إعدادات ال virtual host.
ملاحظة: يجب عليك استبدال المسار التالي `path/to/basic/web` بالمسار الفعلي للتطبيق الخاص بك وصولا الى ال `basic/web`.# Set document root to be "basic/web"
DocumentRoot "path/to/basic/web"
<Directory "path/to/basic/web">
# use mod_rewrite for pretty URL support
RewriteEngine on
# If a directory or a file exists, use the request directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward the request to index.php
RewriteRule . index.php
# if $showScriptName is false in UrlManager, do not allow accessing URLs with script name
RewriteRule ^index.php/ - [L,R=404]
# ...other settings...
</Directory>الإعدادات الموصى بها لل Nginx
لاستخدام [Nginx](https://wiki.nginx.org/)، يجب تثبيت PHP على أنه [FPM SAPI](https://www.php.net/install.fpm)، ويمكنك استخدام إعدادات ال Nginx التالية، مع الإنتباه على استبدال المسار من `path/to/basic/web` الى المسار الفعلي وصولا إلى `basic/web` بالإضافة الى إستبدال `mysite.test` إلى ال hostname الخاص بالتطبيق.server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name mysite.test;
root /path/to/basic/web;
index index.php;
access_log /path/to/basic/log/access.log;
error_log /path/to/basic/log/error.log;
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# uncomment to avoid processing of calls to non-existing static files by Yii
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
# deny accessing php files for the /assets directory
location ~ ^/assets/.*\.php$ {
deny all;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
try_files $uri =404;
}
location ~* /\. {
deny all;
}
}عند استخدامك لهذا الإعداد، يجب عليك أيضًا تعيين `cgi.fix_pathinfo = 0` في ملف php.ini
من أجل تجنب العديد من طلبات ال `stat()` الغير الضرورية للنظام.
لاحظ أيضًا أنه عند تشغيل خادم HTTPS، تحتاج إلى إضافة `fastcgi_param HTTPS on;`بحيث يمكنك إكتشاف إذا ما كان الاتصال آمنًا أم لا.
Guide Ar Start Looking Ahead (`docs/guide-ar/start-looking-ahead.md`)
ماذا الآن - الخطوة القادمة
إذا قمت بقرائة الفصل الخاص ب "البداية من هنا"، فأنت الآن قادر على بناء تطبيق Yii متكامل، لقد تعلمت كيف يمكنك تنفيذ وإستخدام أكثر الخصائص والمميزات المشتركة، مثل جلب البيانات من قاعدة البيانات، وأخذ البيانات من المستخدمين، ومن ثم عرضها، كما تعلمت كيف يمكنك تقسيم البيانات الى صفحات، وقمنا باستخدام ال Gii وتعلمنا كيف يمكننا إنشاء شيفرة برمجية من خلاله بشكل تلقائي، ومن الممارسة تعلمنا أن إنشاء الشيفرة البرمجية من خلال ال Gii يجعل من عملية تطوير المواقع والوظائف المطلوبة أمرا بسيطا وسهلا للغابة، كل ما عليك القيام به هو تعبئة ال forms.
في هذا الجزء من التوثيق سنعرض ملخص للمصادر المتاحة لل Yii، والتي ستساعدك في تحسين إنتاجيتك عند إستخدامك لبيئة العمل Yii.
<li>
التوثيق
<li>[The Definitive Guide - الدليل الشامل](https://www.yiiframework.com/doc-2.0/guide-README.html): كما يشير الإسم، فإن هذا الدليل يحدد آلية عمل ال Yii بدقة عالية، ويوفر إرشادات حول كيفية إستخدام ال Yii، هذا الجزء الأكثر أهمية في ال Yii، والذي يجب عليك قرائته قبل كتابة أي Yii code (ملاحظة: جزء البداية من هنا، والذي قمنا بدراسته هو أحد هذه الأجزاء، ومن أهمها للبدء بإنشاء التطبيقات من خلال ال Yii).</li>
<li>[The Class Reference - المرجع الخاص بال Class](https://www.yiiframework.com/doc-2.0/index.html) في هذا الجزء يتم تحديد الية إستخدام كل Class يقدمه ال Yii، في العادة يتم إستخدام هذا المرجع عند كتابة شيفرة برمجية وأنت ترغب في فهم آلية العمل ل Class معين، أو Method, او فهم Proporty معينة...الخ، من الأفضل إستخدام المرجع الخاص بال Class فقط عند فهم آلية العمل لل Yii. </li>
<li>[The Wiki Articles - مقالات الويكي](https://www.yiiframework.com/wiki/?tag=yii2) مقالات الويكي هي مجموعة من الخبرات العملية للمستخدمين، تمت كتابتها ونشرها على شكل مقالات لمشاركة الخبرات، ومعظم هذه الكتابات تكون مثل الوصفات الخاصة بالطبخ، موجودة لخدمة هدف معين، وحل مشكلة محددة باستخدام ال Yii، وبالرغم من أن هذه الكتابات قد لا تكون بجودة ودقة الدليل الشامل، الا أنها قد تغطي مواضيع أكثر، وتطرح أيضا حلولا مباشرة للإستخدام.</li>
<li>[الكتب](https://www.yiiframework.com/doc/)</li>
</li>
<li>[Extensions - الملحقات](https://www.yiiframework.com/extensions/): تفتخر ال Yii بوجود مكتبة ضخمة من الملحقات التي تمت برمجتها وإضافتها من قبل المستخدمين المتطوعين الذين شاركوا أعمالهم وطورها لتجعل مهمة المطورين الآخرين أسهل وأسرع في تطوير التطبيفات المبنية بواسطة ال Yii.</li>
<li>
المجتمع
<li>المنتدى: [https://forum.yiiframework.com/](https://forum.yiiframework.com/)</li>
<li>IRC chat: The #yii channel on the Libera (ircs://irc.libera.chat:6697/yii)</li>
<li>Slack chanel: [https://yii.slack.com](https://yii.slack.com)</li>
<li>Gitter chat: [https://gitter.im/yiisoft/yii2](https://gitter.im/yiisoft/yii2)</li>
<li>GitHub: [https://github.com/yiisoft/yii2](https://github.com/yiisoft/yii2)</li>
<li>Facebook: [https://www.facebook.com/groups/yiitalk/](https://www.facebook.com/groups/yiitalk/)</li>
<li>Twitter: [https://twitter.com/yiiframework](https://twitter.com/yiiframework)</li>
<li>LinkedIn: [https://www.linkedin.com/groups/yii-framework-1483367](https://www.linkedin.com/groups/yii-framework-1483367)</li>
<li>Stackoverflow: [https://stackoverflow.com/questions/tagged/yii2](https://stackoverflow.com/questions/tagged/yii2)</li>
</li>Guide Ar Start Prerequisites (`docs/guide-ar/start-prerequisites.md`)
ماذا يجب أن تعرف قبل البدء بال Yii
منحنى التعلم الخاص بال Yii ليس حادًا مثل أطر PHP الأخرى، ولكن لا يزال هناك بعض الأشياء التي يجب أن تتعلمها قبل البدء بـال Yii.PHP
ال Yii هو إطار عمل PHP، لذا تأكد من قراءة وفهم المرجع الرسمي الخاص بلغة ال [PHP](https://www.php.net/manual/en/langref.php). عند البدء بتطوير المشاريع أو التطبيقات باستخدام ال Yii ، ستكتب التعليمات البرمجية بطريقة كائنية التوجه OOP، لذا تأكد من أنك على دراية بـمفاهيم ال [OOP](https://www.php.net/manual/en/language.oop5.basic.php) وكذلك ال [namespaces](https://www.php.net/manual/en/language.namespaces.php).البرمجة كائنية التوجه object oriented programming
كمبرمج أو مطور يرغب بالعمل على ال Yii، يجب عليك أن تمتلك المعرفة الأساسية للبرمجة كائنية التوجه OOP. إذا لم تكن على دراية بها ، فيمكنك تعلم ذلك من خلال واحدة من هذه الدورات المنتشرة مثل هذه الدورة من [tuts+](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762).ملاحظة: كلما زاد تعقيد التطبيق أو المشروع الذي تعمل عليه، كلما احتجت الى مستوى أعلى وإحترافي أكثر من مفاهيم ال OOP لحل وإدارة التعقديات التي ستترب على مثل هذه المشاريع.
Command line and composer
تستخدم ال Yii بشكل كبير de-facto standard PHP package manager، ال Composer، لذلك تأكد من قرائتك وفهمك لهذا الموضوع قبل أن تبدء. بالإضافة الى ذلك إذا لم تكن على دراية باستخدام سطر الأوامر (command line) ، فقد حان الوقت لبدء المحاولة. بمجرد تعلم الأساسيات ، لن ترغب في العمل بدون إستخدام سطر الأوامر.
ال composer: ويترجم حرفيا الى كلمة "الملحن"، وهي عبارة عن أداة لإدارة المشاريع البرمجية والتي تسمح لك بتحديث وتنزيل المكتبات البرمجية المطلوبة للمشروع الخاص بك.
Guide Ar Start Workflow (`docs/guide-ar/start-workflow.md`)
تشغيل التطبيقات
بعد تثبيت ال Yii، سيكون لديك تطبيق Yii جاهز للعمل عليه ويمكن الوصول إليه عبر
الرابط التالي: https://hostname/basic/web/index.php أو https://hostname/index.php إعتمادا على الإعدادات
الخاصة بك (إعدادت ال web server). في هذا الجزء سنستعرض الوظائف ال built-in الموجودة في التطبيق الإفتراضي لإطار العمل Yii، وكيف يقوم بتنظيم الشيفرة البرمجية، وكيف يعالج (handling) هذا التطبيق الطلبات (requests) بشكل عام.
معلومة: من أجل تبسيط الطرح، ومن خلال هذا البرنامج التعليمي " Getting Started - البداية من هنا"، من المفترض أنك قمت بتعيين `basic/web` ك `document root` لل Web server، وقد قمت أيضا بإعداد ال Url الذي يسمح لك بالوصول الى التطبيق المثبت من خلاله ليكون على الشكل التالي: `https://hostname/index.php` أو ما شابه ذلك.اذا لم تقم بذلك، ولتلبية إحتياجاتك في هذا البرنامج التعليمي، يرجى ضبط ال Url كما هو موضح في هذه الصفحة.
يمكنك معرفة الضبط الخاص بال Web server من هنا: تثبيت ال Yii
ملاحظة: بخلاف إطار العمل نفسه(Yii framework)، بعد تثبيت ال template الخاص بالمشروع، يكون كل شيء في هذا التطبيق يخصك أنت، بحيث تملك الحرية في إضافة أو حذف أو تعديل كل ما تحتاج اليه.
خصائص / وظائف التطبيق المثبت - Functionality
يحتوي ال Basic ِApplication Template الذي قمنا بتثبيته على أربع صفحات:
<li>الصفحة الرئيسية(Homepage): يتم عرض هذه الصفحة من خلال الرابط التالي `https://hostname/index.php` </li>
<li>صفحة من نحن(About)</li>
<li>صفحة اتصل بنا (Contact): في هذه الصفحة يتم عرض form يسمح للأعشاء بالإتصال بك من خلال البريد الإلكتروني.</li>
<li>صفحة تسجيل الدخول (Login): في هذه الصفحة يتم عرض form يسمح للأعضاء بالحصول على الإذن لإستخدام الخصائص التي لا يجوز لغيرهم من الوصول اليها، قم بتجربة تسجيل الدخول من خلال استخدام `admin/admin` ولاحظ أن كلمة "Login" ستختفي من القائمة الرئيسية وستظهر محلها الكلمة "Logout"</li>هذه الصفحات تشترك بامتلاكها common header and footer -الترويسة أعلى الصفحة، والذيل أسفل الصفحة-. ويحتوي ال header على القائمة الرئيسية (main menu) والتي بدورها تسمح لك بالتنقل بين الصفحات المختلفة.
أيضا، يجب عليك أن تنظر الى ال toolbar الموجود في أسفل نافذة المتصفح. ال [debugger tool](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md) هذه تعتبر كأداة مفيدة مقدمة من ال Yii لتسجيل وعرض الكثير من المعلومات وتصحيح الأخطاء، مثل log messages, response statuses, the database queries run وما إلى ذلك.
بالإضافة إلى ال web application، يوجد هناك "console script" يسمى ب `yii`، والذي ستجده في المسار الرئيسي للتطبيق. هذا السكربت يمكن استخدامه لتشغيل المهام التي تعمل في الخفاء (background) أو لتنفيذ مهام الصيانة (ال maintenance). ستجد الوصف الخاص بهذا السكربت
داخل هذه الصفحة [Console Application Section](tutorial-console.md).هيكلية التطبيق - Application Structure
أكثر المسارات والملفات أهمية الموجودة داخل التطبيق (بافتراض أن ال application's root directory هو `basic`) هي:basic/ application base path
composer.json used by Composer, describes package information
config/ contains application and other configurations
console.php the console application configuration
web.php the Web application configuration
commands/ contains console command classes
controllers/ contains controller classes
models/ contains model classes
runtime/ contains files generated by Yii during runtime, such as logs and cache files
vendor/ contains the installed Composer packages, including the Yii framework itself
views/ contains view files
web/ application Web root, contains Web accessible files
assets/ contains published asset files (javascript and css) by Yii
index.php the entry (or bootstrap) script for the application
yii the Yii console command execution scriptبشكل عام، يمكن تقسيم الملفات داخل التطبيق إلى نوعين: الاول تجده تحت المسار التالي: basic/web والثاني تجده بالمسارات الأخرى.
وبنائا على ذلك، فإنه من الممكن الوصول إلى النوع الأول مباشرة عبر ال HTTP (أي من خلال المتصفح) ، بينما لا يمكن أن يكون ذلك للنوع الثاني.
يعتمد ال Yii على إستخدام ال MVC، وال MVC هو أحد ال Architectural Pattern، وهي اختصار ل [model-view-controller](https://wikipedia.org/wiki/Model-view-controller)،هذا الأسلوب ينعكس في تنظيم المسارات الخاصة بالملفات كما في الشكل أعلاه. يحتوي المسار models على جميع الكلاس (model classes) ، ويحتوي مسار ال views على جميع الصفحات التي ستستخدم في العرض (view scripts)، ويحتوي مسار الcontrollers على
جميع (controller classes)
يوضح المخطط التالي ال static structure للتطبيق.
يحتوي كل تطبيق على نص برمجي يستخدم للدخول الى التطبيق (كبوابة بعدها يظهر التطبيق للناظر)، ويسمى هذا الجزء بال entry script، وهو يمثل الصفحة `web/index.php`، ويعد هذا المدخل النص البرمجي الوحيد الذي يمكن الوصول إليه من خلال ال PHP في التطبيق، ويعمل هذا ال entry script على أخذ ال request ومن ثم إنشاء instance خاص بالتطبيق ليستطيع التعامل معه (التعامل مع التطبيق ومكوناته).
يقوم [application](../guide/structure-applications.md) على معالجة ال request بمساعدة من ال [components](../guide/concept-components.md)، ومن ثم بقوم التطبيق بإرسال ال request الى عناصر ال MVC، كما يتم استخدام ال [Widgets](../guide/structure-widgets.md) في ال [views](../guide/structure-views.md) للمساعدة في إنشاء العناصر المعقدة والمتغيرة (Complex & Dynamic user interface) لواجهة المستخدم.دورة الحياة الخاصة بال request
يوضح المخطط التالي كيفية معالجة التطبيق ل request معين.
- يقوم المستخدم بعمل request لل [entry script](../guide/structure-entry-scripts.md) `web/index.php`.
- يقوم ال entry script على جلب [الإعدادات](../guide/concept-configurations.md) الخاصة بالتطبيق ومن ثم إنشاء ال instance الخاص بالتطبيق ليستطيع التحكم ب request وإدارتها.
- يقوم التطبيق بمعالجة ال [requested route](../guide/runtime-routing.md) بمساعدة من ال [request](../guide/runtime-requests.md) application component.
- يقوم التطبيق على إنشاء instance من ال [controller](../guide/structure-controllers.md) للتحكم بال request.
- يقوم ال controller على إنشاء [action](../guide/structure-controllers.md) instance مع مجموعة من الفلاتر(المرشحات) الخاصة بهذا ال action.
- في حالة فشل أي فلتر، يتم إلغاء الإجراء.
- في حال نجاح جميع الفلاتر ، يتم تنفيذ الإجراء.
- يقوم ال action بجلب بعض البيانات الخاصة بال models, وفي الغالب ستكون من قاعدة البيانات إن أمكن ذلك.
- سيقوم ال action بجلب ال view ليقوم بتقديم البيانات التي تم جلبها لل view.
- عملية الجلب السابقة ستقوم على إرجاع النتائج الى [response](../guide/runtime-responses.md) application component
- بعد ذلك سيقوم ال response component بإرسال النتيجة النهائية الى المتصفح الخاص بالمستخدم.
Guide De Blocktypes.Json (`docs/guide-de/blocktypes.json`)
{
"Warning:": "Achtung:",
"Note:": "Hinweis:",
"Info:": "Info:",
"Tip:": "Tipp:"
}
Guide De Intro Yii (`docs/guide-de/intro-yii.md`)
Was ist Yii?
Yii ist ein leistungsstarkes, komponentenbasiertes PHP-Framework zur schnellen Entwicklung moderner Webanwendungen.
Der Name Yii (ausgesprochen Ji oder [ji:]) bedeutet im Chinesischen "einfach und evolutionär". Er kann außerdem
als Akronym für Yes It Is! (zu Deutsch Ja, ist es!) verstanden werden.
Wofür ist Yii am besten geeignet?
Yii ist universell einsetzbar: Mit ihm lassen sich Webanwendungen aller Art entwickeln. Dank seiner komponentenbasierten
Architektur und seiner ausgefeilten Caching-Unterstützung eignet es sich besonders für umfangreiche Anwendungen wie
Portale, Foren, Content-Management-Systeme (CMS), E-Commerce-Projekte, RESTful Web Services und vieles mehr.
Wie unterscheidet sich Yii von anderen Frameworks?
Wenn Sie bereits mit einem anderen Framework vertraut sind, wird es Sie vermutlich interessieren, wie Yii im Vergleich
dazu abschneidet:
- Wie die meisten PHP-Frameworks implementiert Yii das Architekturmuster MVC (Model-View-Controller) und fördert eine
Organisation des Codes, die auf diesem Muster basiert. - Yii vertritt die Philosophie, dass Code auf eine einfache und dennoch elegante Weise geschrieben werden sollte.
Yii wird nie versuchen, Strukturen zu verkomplizieren, nur um ein bestimmtes Entwurfsmuster strikt einzuhalten. - Yii ist ein Full-Stack-Framework: Seine Komponenten decken alle Schichten einer Anwendung ab und bieten viele
bewährte und sofort einsatzbereite Funktionen, darunter Query Builder und ActiveRecord für relationale und
NoSQL-Datenbanken, Unterstützung für die Entwicklung von RESTful APIs, mehrstufiges Caching und mehr. - Yii ist sehr gut erweiterbar. Sie können fast jeden Teil des Kerncodes anpassen oder ersetzen. Sie können außerdem
die solide Erweiterungsarchitektur von Yii nutzen, um weiterverteilbare Erweiterungen einzusetzen oder zu entwickeln. - Hohe Performance ist immer ein vorrangiges Ziel von Yii.
Yii ist keine One-Man-Show, sondern wird von einem starken Kern-Entwicklerteam
sowie einer großen Community von Fachleuten unterstützt, die
ständig zur Entwicklung von Yii beitragen. Das Yii-Entwicklerteam behält die neuesten Webentwicklungstrends sowie die
Best Practices und Funktionen im Auge, die in anderen Frameworks und Projekten zu finden sind. Die relevantesten
Best Practices und Funktionen, die anderswo zu finden sind, werden regelmäßig in das Kernframework integriert und über
einfache und elegante Schnittstellen zugänglich gemacht.
Yii-Versionen
Yii steht derzeit in zwei Major-Versionen zur Verfügung: 1.1 und 2.0. Version 1.1 ist die alte Generation und befindet
sich nun im Wartungsmodus. Version 2.0 ist eine komplette Neufassung von Yii, die die neuesten Technologien und
Protokolle aufgreift, einschließlich Composer, PSR, Namespaces, Traits usw. Version 2.0 ist die aktuelle Generation
des Frameworks und wird in den nächsten Jahren der Hauptfokus der Entwicklung sein.
In diesem Handbuch geht es hauptsächlich um die Version 2.0.
Info: Mit Yii3 ist inzwischen auch die nächste Generation des Frameworks verfügbar. Sie wird in diesem Handbuch
nicht behandelt. Weitere Informationen finden Sie im Handbuch zu Yii3.
Anforderungen und Voraussetzungen
Yii 2.0 erfordert PHP 7.4.0 oder höher und läuft am besten mit der neuesten Version von PHP. Detailliertere
Informationen über die Anforderungen einzelner Funktionen erhalten Sie, indem Sie den "Requirement Checker" ausführen,
der in jedem Yii-Release enthalten ist.
Die Verwendung von Yii erfordert Grundkenntnisse in der objektorientierten Programmierung (OOP), da es sich bei Yii um
ein rein OOP-basiertes Framework handelt. Yii 2.0 nutzt auch die neuesten Funktionen von PHP, wie z. B.
Namespaces und
Traits. Das Verständnis dieser Konzepte wird Ihnen helfen,
sich leichter in Yii 2.0 zurechtzufinden.
Guide De Start Gii (`docs/guide-de/start-gii.md`)
Code generieren mit Gii
Dieser Abschnitt beschreibt, wie Gii zur
automatischen Generierung von Code verwendet werden kann, der gängige Webseitenfunktionen abdeckt. Die Verwendung von
Gii erfordert nur die Eingabe der richtigen Informationen, wie auf den Gii-Seiten beschrieben.
In diesem Tutorial lernen Sie:
- die Aktivierung von Gii in Ihrer Anwendung
- die Verwendung von Gii zur Generierung einer Active-Record-Klasse
- die Verwendung von Gii zur Generierung des Codes zur Implementierung von CRUD-Operationen für eine Datenbanktabelle
- die individuelle Anpassung des Codes, der von Gii generiert wird
Gii starten
Gii wird als Modul für Yii
angeboten. Sie können Gii durch die Konfiguration der [[yii\base\Application::modules|modules]]-Eigenschaft der
Anwendung aktivieren. Abhängig davon, wie Sie Ihre Anwendung aufgesetzt haben, finden Sie den folgenden Code
möglicherweise bereits in der Konfigurationsdatei config/web.php:
$config = [ ... ];
if (YII_ENV_DEV) {
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
];
}Die obenstehende Konfiguration legt fest, dass die Anwendung in der
Entwicklungsumgebung ein Modul mit dem Namen gii lädt, das durch
die Klasse [[yii\gii\Module]] abgebildet wird.
Prüfen Sie das Einstiegsskript web/index.php Ihrer Anwendung. Dort finden Sie die
folgende Zeile, die im Wesentlichen bewirkt, dass YII_ENV_DEV den Wert true hat:
defined('YII_ENV') or define('YII_ENV', 'dev');Aufgrund dieser Zeile befindet sich Ihre Anwendung im Entwicklungsmodus. Dadurch ist sichergestellt, dass Gii mittels
obenstehender Konfiguration aktiviert wird. Sie können nun mittels folgender URL darauf zugreifen:
https://hostname/index.php?r=giiNote: Falls Sie von einem anderen Computer als
localhostauf Gii zugreifen, wird Ihnen der Zugriff aus
Sicherheitsgründen standardmäßig verweigert. Fügen Sie Ihre IP-Adresse wie folgt zu denallowedIPshinzu, um den
Zugriff zu erlauben:
'gii' => [
'class' => 'yii\gii\Module',
'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // Passen Sie dies an Ihre Bedürfnisse an
],Generieren einer Active-Record-Klasse
Um mittels Gii eine Active-Record-Klasse zu generieren, klicken Sie auf den "Model Generator"-Link auf der Startseite
von Gii. Füllen Sie das Formular daraufhin wie folgt aus:
- Table Name:
country - Model Class:
Country
Klicken Sie dann auf den "Preview"-Button. Daraufhin sehen Sie in der Ergebnisliste die zu erstellende Dateimodels/Country.php. Klicken Sie auf den Dateinamen, um sich eine Vorschau des Inhalts der Datei anzusehen.
Wenn bereits eine Datei mit demselben Namen existiert und Sie diese überschreiben würden, können Sie vorher auf dendiff-Button neben dem Dateinamen klicken, um sich die Unterschiede zwischen dem zu generierenden Code und der
bestehenden Version anzusehen.
Zum Überschreiben einer existierenden Datei aktivieren Sie die Checkbox neben "overwrite" und klicken Sie dann auf den
"Generate"-Button. Beim Generieren einer neuen Datei können Sie einfach auf den "Generate"-Button klicken.
Daraufhin erscheint eine Seite, die Ihnen bestätigt, dass der Code erfolgreich generiert wurde. Falls die Datei bereits
existierte, erscheint zusätzlich eine Meldung, dass diese mit dem neu generierten Code überschrieben wurde.
Generieren von CRUD-Code
CRUD steht für Create, Read, Update und Delete. Dies sind die englischen Begriffe für die vier Standardaufgaben in der
Datenverarbeitung der meisten Webseiten. Um mittels Gii Code mit CRUD-Funktionalität zu generieren, klicken Sie auf
"CRUD Generator" auf der Startseite von Gii. Im "country"-Beispiel füllen Sie das Formular wie folgt aus:
- Model Class:
app\models\Country - Search Model Class:
app\models\CountrySearch - Controller Class:
app\controllers\CountryController
Klicken Sie dann auf den "Preview"-Button. Daraufhin sehen Sie eine Liste der zu generierenden Dateien (siehe Bild
unten).
Falls Sie zuvor den Controller controllers/CountryController.php und die Datei views/country/index.php erstellt
haben (im Datenbank-Abschnitt des Handbuchs), aktivieren Sie die Checkboxen "overwrite", um die beiden Dateien zu
ersetzen (die bisherigen Versionen bieten keine vollständige CRUD-Unterstützung).
Probieren Sie es aus
Um die generierten Dateien in Aktion zu sehen, navigieren Sie in Ihrem Browser zu folgender URL:
https://hostname/index.php?r=country%2FindexSie sehen hier eine Datentabelle, die Ihnen die Länder aus der Datenbanktabelle anzeigt. Sie können die Daten sortieren
oder durch die Eingabe von Filterbedingungen im Tabellenkopf filtern.
Für jedes Land in der Tabelle gibt es rechts Aktionslinks zum Anzeigen der Details, zum Bearbeiten oder zum Löschen des
Datensatzes. Sie können auch auf den "Create Country"-Button oberhalb der Tabelle klicken, um ein Formular zum Anlegen
eines neuen Landes zu öffnen.
Für den Fall, dass Sie die Dateien analysieren oder verändern möchten, finden Sie nachfolgend eine Liste der Dateien,
die von Gii generiert wurden:
- Controller:
controllers/CountryController.php - Models:
models/Country.phpundmodels/CountrySearch.php - Views:
views/country/*.php
Info: Gii ist so aufgebaut, dass es einfach angepasst und erweitert werden kann. Durch kluges Einsetzen von Gii
kann sich Ihr Entwicklungsprozess drastisch verkürzen. Weitere Informationen finden Sie im Abschnitt
Gii.
Zusammenfassung
In diesem Abschnitt haben Sie gelernt, wie man mit Gii Code generieren kann, der die vollständige CRUD-Funktionalität
für die in einer Datenbanktabelle gespeicherten Inhalte implementiert.
Guide De Start Looking Ahead (`docs/guide-de/start-looking-ahead.md`)
Ausblick
Wenn Sie sich durch das gesamte "Einstieg"-Kapitel durchgearbeitet haben, haben Sie nun eine fertige Yii-Anwendung
erstellt. Dabei haben Sie gelernt, häufig benötigte Funktionen wie z. B. das Erfassen von Benutzerdaten mittels
HTML-Formularen, das Lesen von Daten aus einer Datenbank und deren seitenweise Darstellung umzusetzen. Sie wissen jetzt
auch, wie man mittels Gii automatisch Code
generieren kann. Die Verwendung von Gii zur Code-Generierung macht einen Großteil Ihres Webentwicklungsprozesses so
einfach wie das Ausfüllen einiger Formulare.
Dieser Abschnitt fasst die verfügbaren Yii-Ressourcen zusammen, die Ihnen helfen, bei der Verwendung des Frameworks
produktiver zu sein.
- Dokumentation
- Das umfassende Handbuch:
Wie der Name vermuten lässt, definiert dieses Handbuch genau, wie Yii funktionieren soll, und bietet eine
allgemeine Anleitung zur Verwendung von Yii. Es ist das wichtigste Yii-Tutorial, und Sie sollten es lesen, bevor
Sie Yii-Code schreiben. - Die Klassenreferenz:
Hier finden Sie die Dokumentation aller Klassen, die von Yii bereitgestellt werden. Sie kommt hauptsächlich dann
zur Anwendung, wenn Sie beim Programmieren die Verwendung bestimmter Klassen, Methoden oder Eigenschaften
verstehen möchten. Die Verwendung dieser Dokumentation empfiehlt sich erst, wenn Sie ein Kontextverständnis des
gesamten Frameworks entwickelt haben. - Die Wiki-Artikel:
Die Wiki-Artikel wurden von Yii-Benutzern auf Basis ihrer eigenen Erfahrungen geschrieben. Die meisten dieser
Artikel sind im Stile von "Kochrezepten" verfasst und demonstrieren damit exemplarisch die Lösung eines
spezifischen Problems mittels Yii. Während die Qualität dieser Artikel unter Umständen die des Handbuchs nicht
erreicht, sind sie insofern nützlich, als sie ein breiteres Themenspektrum abdecken und oftmals
"Ready-to-use"-Lösungen anbieten. - Bücher
- Das umfassende Handbuch:
- Erweiterungen:
Yii bietet eine Bibliothek mit tausenden Erweiterungen, die von Yii-Benutzern beigesteuert wurden und einfach in Ihre
Anwendungen integriert werden können. Damit lässt sich Ihr Entwicklungsprozess weiter beschleunigen und vereinfachen. - Gemeinschaft
- Forum: https://forum.yiiframework.com/
- IRC-Chat: Der #yii-Channel im Libera-Netzwerk ()
- Slack-Channel: https://www.yiiframework.com/go/slack
- Gitter-Chat: https://gitter.im/yiisoft/yii2
- GitHub: https://github.com/yiisoft/yii2
- Facebook: https://www.facebook.com/groups/yiitalk/
- Twitter: https://twitter.com/yiiframework
- LinkedIn: https://www.linkedin.com/groups/yii-framework-1483367
- Stackoverflow: https://stackoverflow.com/questions/tagged/yii2
Guide Es Blocktypes.Json (`docs/guide-es/blocktypes.json`)
{
"Warning:": "Aviso:",
"Note:": "Nota:",
"Info:": "Información:",
"Tip:": "Consejo:"
}
Guide Es Caching Data (`docs/guide-es/caching-data.md`)
Almacenamiento de Datos en Caché
El almacenamiento de datos en caché trata del almacenamiento de alguna variable PHP en caché y recuperarla más tarde del mismo. También es la base de algunas de las características avanzadas de almacenamiento en caché, tales como el almacenamiento en caché de consultas a la base de datos y el almacenamiento en caché de contenido.
El siguiente código muestra el típico patrón de uso para el almacenamiento en caché, donde la variable $cache se refiere al componente caché:
// intenta recuperar $data de la caché
$data = $cache->get($key);
if ($data === false) {
// $data no ha sido encontrada en la caché, calcularla desde cero
// guardar $data en caché para así recuperarla la próxima vez
$cache->set($key, $data);
}
// $data está disponible aquíComponentes de Caché
El almacenamiento de datos en caché depende de los llamados cache components (componentes de caché) los cuales
representan diferentes tipos de almacenamiento en caché, como por ejemplo en memoria, en archivos o en base de datos.
Los Componentes de Caché están normalmente registrados como componentes de la aplicación para que de esta forma puedan
ser configurados y accesibles globalmente. El siguiente código muestra cómo configurar el componente de aplicacióncache para usar memcached con dos servidores caché:
'components' => [
'cache' => [
'class' => 'yii\caching\MemCache',
'servers' => [
[
'host' => 'server1',
'port' => 11211,
'weight' => 100,
],
[
'host' => 'server2',
'port' => 11211,
'weight' => 50,
],
],
],
],Puedes acceder al componente de caché usando la expresión Yii::$app->cache.
Debido a que todos los componentes de caché soportan el mismo conjunto de APIs, podrías cambiar el componente de caché
subyacente por otro diferente mediante su reconfiguración en la configuración de la aplicación sin tener que modificar
el código que utiliza la caché. Por ejemplo, podrías modificar la configuración anterior para usar [[yii\caching\ApcCache|APC cache]]:
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
],
],Tip: Puedes registrar múltiples componentes de aplicación de caché. El componente llamado
cachees usado por defecto por muchas clases caché-dependiente (ej. [[yii\web\UrlManager]]).
Almacenamientos de Caché Soportados
Yii proporciona varios componentes de caché que pueden almacenar datos en diferentes medios. A continuación
se muestra un listado con los componentes de caché disponibles:
- [[yii\caching\ApcCache]]: utiliza la extensión de PHP APC. Esta opción puede ser considerada como la más rápida de entre todas las disponibles para una aplicación centralizada. (ej. un servidor, no dedicado al balance de carga, etc).
- [[yii\caching\DbCache]]: utiliza una tabla de base de datos para almacenar los datos. Por defecto, se creará y usará como base de datos SQLite3 en el directorio runtime. Se puede especificar explícitamente que base de datos va a ser utilizada configurando la propiedad
db. - [[yii\caching\DummyCache]]: dummy cache (caché tonta) que no almacena en caché nada. El propósito de este componente es simplificar el código necesario para chequear la disponibilidad de caché. Por ejemplo, durante el desarrollo o si el servidor no tiene soporte de caché actualmente, puede utilizarse este componente de caché. Cuando este disponible un soporte en caché, puede cambiarse el componente correspondiente. En ambos casos, puede utilizarse el mismo código
Yii::$app->cache->get($key)para recuperar un dato sin la preocupación de queYii::$app->cachepueda sernull. - [[yii\caching\FileCache]]: utiliza un fichero estándar para almacenar los datos. Esto es adecuado para almacenar grandes bloques de datos (como páginas).
- [[yii\caching\MemCache]]: utiliza las extensiones de PHP memcache y memcached. Esta opción puede ser considerada como la más rápida cuando la caché es manejada en una aplicación distribuida (ej. con varios servidores, con balance de carga, etc..)
- [[yii\redis\Cache]]: implementa un componente de caché basado en Redis que almacenan pares clave-valor (requiere la versión 2.6.12 de redis).
- [[yii\caching\WinCache]]: utiliza la extensión de PHP WinCache (ver también).
Tip: Puedes utilizar diferentes tipos de almacenamiento de caché en la misma aplicación. Una estrategia común es la de usar almacenamiento de caché en memoria para almacenar datos que son pequeños pero que son utilizados constantemente (ej. datos estadísticos), y utilizar el almacenamiento de caché en archivos o en base de datos para guardar datos que son grandes y utilizados con menor frecuencia (ej. contenido de página).
API de Caché
Todos los componentes de almacenamiento de caché provienen de la misma clase "padre" [[yii\caching\Cache]] y por lo tanto soportan la siguiente API:
- [[yii\caching\Cache::get()|get()]]: recupera un elemento de datos de la memoria caché con una clave especificada.
Un valor nulo será devuelto si el elemento de datos no ha sido encontrado en la memoria caché o si ha expirado o ha sido invalidado. - [[yii\caching\Cache::set()|set()]]: almacena un elemento de datos identificado por una clave en la memoria caché.
- [[yii\caching\Cache::add()|add()]]: almacena un elemento de datos identificado por una clave en la memoria caché si la clave no se encuentra en la memoria caché.
- [[yii\caching\Cache::mget()|mget()]]: recupera varios elementos de datos de la memoria caché con las claves especificadas.
- [[yii\caching\Cache::mset()|mset()]]: almacena múltiples elementos de datos en la memoria caché. Cada elemento se identifica por una clave.
- [[yii\caching\Cache::madd()|madd()]]: almacena múltiples elementos de datos en la memoria caché. Cada elemento se identifica con una clave. Si una clave ya existe en la caché, el elemento será omitido.
- [[yii\caching\Cache::exists()|exists()]]: devuelve un valor que indica si la clave especificada se encuentra en la memoria caché.
- [[yii\caching\Cache::delete()|delete()]]: elimina un elemento de datos identificado por una clave de la caché.
- [[yii\caching\Cache::flush()|flush()]]: elimina todos los elementos de datos de la cache.
Note: No Almacenes el valor boolean
falseen caché directamente porque el método [[yii\caching\Cache::get()|get()]] devuelve
el valorfalsepara indicar que el dato no ha sido encontrado en la caché. Puedes ponerfalsedentro de un array y cachear
este array para evitar este problema.
Algunos sistemas de almacenamiento de caché, como por ejemplo MemCache, APC, pueden recuperar múltiples valores almacenados en modo de lote (batch), lo que puede reducir considerablemente la sobrecarga que implica la recuperación de datos almacenados en la caché. Las API [[yii\caching\Cache::mget()|mget()]] y [[yii\caching\Cache::madd()|madd()]]
se proporcionan para utilizar esta característica. En el caso de que el sistema de memoria caché no lo soportara, ésta sería simulada.
Puesto que [[yii\caching\Cache]] implementa ArrayAccess, un componente de caché puede ser usado como un array.
El siguiente código muestra unos ejemplos:
$cache['var1'] = $value1; // equivalente a: $cache->set('var1', $value1);
$value2 = $cache['var2']; // equivalente a: $value2 = $cache->get('var2');Claves de Caché
Cada elemento de datos almacenado en caché se identifica por una clave. Cuando se almacena un elemento de datos en la memoria caché, se debe especificar una clave. Más tarde, cuando se recupera el elemento de datos de la memoria caché, se debe proporcionar la clave correspondiente.
Puedes utilizar una cadena o un valor arbitrario como una clave de caché. Cuando una clave no es una cadena de texto, ésta será automáticamente serializada en una cadena.
Una estrategia común para definir una clave de caché es incluir en ella todos los factores determinantes en términos de un array. Por ejemplo, [[yii\db\Schema]] utiliza la siguiente clave para almacenar en caché la información del esquema de una tabla de base de datos:
[
__CLASS__, // nombre de la clase del esquema
$this->db->dsn, // nombre del origen de datos de la conexión BD
$this->db->username, // usuario para la conexión BD
$name, // nombre de la tabla
];Como puedes ver, la clave incluye toda la información necesaria para especificar de una forma exclusiva una tabla de base de datos.
Cuando en un mismo almacenamiento en caché es utilizado por diferentes aplicaciones, se debería especificar un prefijo único para las claves de la caché por cada una de las aplicaciones para así evitar conflictos. Esto puede hacerse mediante la configuración de la propiedad [[yii\caching\Cache::keyPrefix]]. Por ejemplo, en la configuración de la aplicación podrías escribir el siguiente código:
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
'keyPrefix' => 'myapp', // un prefijo de clave de caché único
],
],Para garantizar la interoperabilidad, deberían utilizarse sólo caracteres alfanuméricos.
Caducidad de Caché
Un elemento de datos almacenado en la memoria caché permanecerá en ella para siempre, a menos que sea removida de alguna manera debido a alguna directiva de caché (ej. el espacio de almacenamiento en caché está lleno y los datos más antiguos se eliminan). Para cambiar este comportamiento, podrías proporcionar un parámetro de caducidad al llamar [[yii\caching\Cache::set()|set()]] para guardar el elemento de datos. El parámetro nos indica por cuántos segundos el elemento se mantendrá válido en memoria caché. Cuando llames [[yii\caching\Cache::get()|get()]] para recuperar el elemento, si el tiempo de caducidad ha pasado, el método devolverá false, indicando que el elemento de datos no ha sido encontrado en la memoria caché. Por ejemplo,
// guardar los datos en memoria caché al menos 45 segundos
$cache->set($key, $data, 45);
sleep(50);
$data = $cache->get($key);
if ($data === false) {
// $data ha caducado o no ha sido encontrado en la memoria caché
}Dependencias de Caché
Además de configurar el tiempo de caducidad, los datos almacenados en caché pueden también ser invalidados conforme a algunos cambios en la caché de dependencias. Por ejemplo, [[yii\caching\FileDependency]] representa la dependencia del tiempo de modificación del archivo. Cuando esta dependencia cambia, significa que el archivo correspondiente ha cambiado. Como resultado, cualquier contenido anticuado que sea encontrado en la caché debería ser invalidado y la llamada a [[yii\caching\Cache::get()|get()]] debería retornar falso.
Una dependencia es representada como una instancia de [[yii\caching\Dependency]] o su clase hija. Cuando llamas [[yii\caching\Cache::set()|set()]] para almacenar un elemento de datos en la caché, puedes pasar el objeto de dependencia asociado. Por ejemplo,
// Crear una dependencia sobre el tiempo de modificación del archivo example.txt.
$dependency = new \yii\caching\FileDependency(['fileName' => 'example.txt']);
// Los datos expirarán en 30 segundos.
// También podría ser invalidada antes si example.txt es modificado.
$cache->set($key, $data, 30, $dependency);
// La caché comprobará si los datos han expirado.
// También comprobará si la dependencia ha cambiado.
// Devolverá `false` si se encuentran algunas de esas condiciones.
$data = $cache->get($key);Aquí abajo se muestra un sumario de las dependencias disponibles:
- [[yii\caching\ChainedDependency]]: la dependencia cambia si cualquiera de las dependencias en la cadena cambia.
- [[yii\caching\DbDependency]]: la dependencia cambia si el resultado de la consulta de la sentencia SQL especificada cambia.
- [[yii\caching\ExpressionDependency]]: la dependencia cambia si el resultado de la expresión de PHP especificada cambia.
- [[yii\caching\CallbackDependency]]: la dipendenza viene modificata se il risultato della callback PHP specificata cambia.
- [[yii\caching\FileDependency]]: la dependencia cambia si se modifica la última fecha de modificación del archivo.
- [[yii\caching\TagDependency]]: marca un elemento de datos en caché con un nombre de grupo. Puedes invalidar los elementos de datos almacenados en caché
con el mismo nombre del grupo a la vez llamando a [[yii\caching\TagDependency::invalidate()]].
Consultas en Caché
Las consultas en caché es una característica especial de caché construido sobre el almacenamiento de caché de datos. Se
proporciona para almacenar en caché el resultado de consultas a la base de datos.
Las consultas en caché requieren una [[yii\db\Connection|DB connection]] y un componente de aplicación caché válido. El uso básico de las consultas en memoria caché es el siguiente, asumiendo que db es una instancia de [[yii\db\Connection]]:
$result = $db->cache(function ($db) {
// el resultado de la consulta SQL será servida de la caché
// si el cacheo de consultas está habilitado y el resultado de la consulta se encuentra en la caché
return $db->createCommand('SELECT * FROM customer WHERE id=1')->queryOne();
});El cacheo de consultas puede ser usado tanto para DAO como para ActiveRecord:
$result = Customer::getDb()->cache(function ($db) {
return Customer::find()->where(['id' => 1])->one();
});Note: Algunos DBMS (ej. MySQL) también soporta el almacenamiento en caché desde el mismo servidor de la BD. Puedes optar por utilizar cualquiera de los mecanismos de memoria caché. El almacenamiento en caché de consultas previamente descrito tiene la ventaja que de que se puede especificar dependencias de caché de una forma flexible y son potencialmente mucho más eficientes.
Configuraciones
Las consultas en caché tienen tres opciones configurables globales a través de [[yii\db\Connection]]:
- [[yii\db\Connection::enableQueryCache|enableQueryCache]]: activa o desactiva el cacheo de consultas.
Por defecto estrue. Tenga en cuenta que para activar el cacheo de consultas, también necesitas tener una caché válida, especificada por [[yii\db\Connection::queryCache|queryCache]]. - [[yii\db\Connection::queryCacheDuration|queryCacheDuration]]: representa el número de segundos que un resultado de la consulta permanecerá válida en la memoria caché. Puedes usar 0 para indicar que el resultado de la consulta debe permanecer en la caché para siempre. Esta propiedad es el valor usado por defecto cuando [[yii\db\Connection::cache()]] es llamada sin especificar una duración.
- [[yii\db\Connection::queryCache|queryCache]]: representa el ID del componente de aplicación de caché.
Por defecto es'cache'. El almacenamiento en caché de consultas se habilita sólo si hay un componente de la aplicación de caché válida.
Usos
Puedes usar [[yii\db\Connection::cache()]] si tienes multiples consultas SQL que necesitas a aprovechar el cacheo de consultas. El uso es de la siguiente manera,
$duration = 60; // resultado de la consulta de caché durante 60 segundos.
$dependency = ...; // dependencia opcional
$result = $db->cache(function ($db) {
// ... realiza consultas SQL aquí ...
return $result;
}, $duration, $dependency);Cualquier consulta SQL en una función anónima será cacheada durante el tiempo indicado con la dependencia especificada.
Si el resultado de la consulta se encuentra válida en la caché, la consulta se omitirá y el resultado se servirá de la caché en su lugar. Si no especificar el parámetro $duration, el valor [[yii\db\Connection::queryCacheDuration|queryCacheDuration]] será usado en su lugar.
A veces dentro de cache(), puedes querer desactivar el cacheo de consultas para algunas consultas especificas. Puedes usar [[yii\db\Connection::noCache()]] en este caso.
$result = $db->cache(function ($db) {
// consultas SQL que usan el cacheo de consultas
$db->noCache(function ($db) {
// consultas SQL que no usan el cacheo de consultas
});
// ...
return $result;
});Si lo deseas puedes usar el cacheo de consultas para una simple consulta, puedes llamar a [[yii\db\Command::cache()]] cuando construyas el comando. Por ejemplo,
// usa el cacheo de consultas y asigna la duración de la consulta de caché por 60 segundos
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->cache(60)->queryOne();También puedes usar [[yii\db\Command::noCache()]] para desactivar el cacheo de consultas de un simple comando. Por ejemplo,
$result = $db->cache(function ($db) {
// consultas SQL que usan cacheo de consultas
// no usa cacheo de consultas para este comando
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->noCache()->queryOne();
// ...
return $result;
});Limitaciones
El almacenamiento en caché de consultas no funciona con los resultados de consulta que contienen controladores de recursos.
Por ejemplo, cuando se utiliza el tipo de columna BLOB en algunos DBMS, el resultado de la consulta devolverá un recurso para manejar los datos de la columna.
Algunos sistemas de almacenamiento caché tienen limitación de tamaño. Por ejemplo, memcache limita el tamaño máximo de cada entrada a 1MB. Por lo tanto, si el tamaño de un resultado de la consulta excede ese límite, el almacenamiento en caché fallará.
Guide Es Caching Fragment (`docs/guide-es/caching-fragment.md`)
Caché de Fragmentos
La Caché de Fragmentos se refiere al almacenamiento en caché de un fragmento, o sección, de una página Web. Por ejemplo, si
una página muestra un sumario de las ventas anuales en una tabla, podrías guardar esta tabla en memoria caché para
eliminar el tiempo necesario para generar esta tabla en cada petición (request). La caché de fragmentos está construido
sobre la caché de datos.
Para usar la caché de fragmentos, utiliza el siguiente código en tu vista (view):
if ($this->beginCache($id)) {
// ... generar contenido aquí ...
$this->endCache();
}Es decir, encierra la lógica de la generación del contenido entre las llamadas [[yii\base\View::beginCache()|beginCache()]] y
[[yii\base\View::endCache()|endCache()]]. Si el contenido se encuentra en la memoria caché, [[yii\base\View::beginCache()|beginCache()]]
mostrará el contenido y devolverá false, saltandose así la lógica de generación del contenido. De lo contrario, el
código de generación se ejecutaría y al alcanzar la llamada [[yii\base\View::endCache()|endCache()]], el contenido
generado será capturado y almacenado en la memoria caché.
Como en la caché de datos, un $id (clave) único es necesario para identificar un contenido guardado en
caché.
Opciones de Caché
Puedes especificar opciones adicionales para la caché de fragmentos pasando el array de opciones como segundo
parametro del método [[yii\base\View::beginCache()|beginCache()]]. Entre bastidores, este array de opciones se utiliza
para configurar el widget [[yii\widgets\FragmentCache]] que es en realidad el que implementa la funcionalidad de la caché
de fragmentos.
Duración
Quizás la opción más utilizada en la caché de fragmentos es [[yii\widgets\FragmentCache::duration|duración]]. Ésta
especifica cuántos segundos el contenido puede permanecer como válido en la memoria caché. El siguiente código almacena
en la caché el fragmento de contenido para una hora a lo sumo:
if ($this->beginCache($id, ['duration' => 3600])) {
// ... generar contenido aquí ...
$this->endCache();
}Si la opción no está activada, se tomará el valor por defecto 60, lo que significa que el contenido almacenado en caché expirará en 60 segundos.
Dependencias
Como en la caché de datos, el fragmento de contenido que está siendo almacenado en caché
también puede tener dependencias. Por ejemplo, el contenido de un artículo que se muestre depende de si el mensaje se
modifica o no.
Para especificar una dependencia, activa la opción [[yii\widgets\FragmentCache::dependency|dependencia]] (dependency),
que puede ser un objecto [[yii\caching\Dependency]] o un array de configuración para crear un objecto Dependency. El
siguiente código especifica que la caché de fragmento depende del cambio del valor de la columna updated_at:
$dependency = [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT MAX(updated_at) FROM post',
];
if ($this->beginCache($id, ['dependency' => $dependency])) {
// ... generar contenido aquí ...
$this->endCache();
}Variaciones
El contenido almacenado en caché puede variar de acuerdo a ciertos parámetros. Por ejemplo, para una aplicación Web que
soporte multiples idiomas, la misma pieza del código de la vista puede generar el contenido almacenado en caché
en diferentes idiomas. Por lo tanto, es posible que desees hacer variaciones del mismo contenido almacenado en caché de
acuerdo con la actual selección del idioma en la aplicación.
Para especificar variaciones en la memoria caché, configura la opción [[yii\widgets\FragmentCache::variations|variaciones]]
(variations), la cual deberá ser un array de valores escalares, cada uno de ellos representando un factor de variación.
Por ejemplo, para hacer que el contenido almacenado en la caché varíe por lenguaje, podrías usar el siguiente código:
if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) {
// ... generar código aquí ...
$this->endCache();
}Alternando el Almacenamiento en Caché
Puede que a veces quieras habilitar la caché de fragmentos únicamente cuando ciertas condiciones se cumplan. Por ejemplo,
para una página que muestra un formulario, tal vez quieras guardarlo en la caché cuando es inicialmente solicitado (a
través de una petición GET). Cualquier muestra posterior (a través de una petición POST) del formulario no debería ser
almacenada en caché ya que el formulario puede que contenga entradas del usuario. Para hacerlo, podrías configurar la
opción de [[yii\widgets\FragmentCache::enabled|activado]] (enabled), de la siguiente manera:
if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) {
// ... generar contenido aquí ...
$this->endCache();
}Almacenamiento en Caché Anidada
El almacenamiento en caché de fragmentos se puede anidar. Es decir, un fragmento de caché puede ser encerrado dentro de
otro fragmento que también se almacena en caché. Por ejemplo, los comentarios se almacenan en una caché de fragmento
interno, y se almacenan conjuntamente con el contenido del artículo en un fragmento de caché exterior. El siguiente
código muestra cómo dos fragmentos de caché pueden ser anidados:
if ($this->beginCache($id1)) {
// ... lógica de generación de contenido externa ...
if ($this->beginCache($id2, $options2)) {
// ... lógica de generación de contenido anidada ...
$this->endCache();
}
// ... lógica de generación de contenido externa ...
$this->endCache();
}Existen diferentes opciones de configuración para las cachés anidadas. Por ejemplo, las cachés internas y las cachés
externas pueden usar diferentes valores de duración. Aún cuando los datos almacenados en la caché externa sean invalidados,
la caché interna puede todavía proporcionar un fragmento válido. Sin embargo, al revés no es cierto. Si la caché externa
es evaluada como válida, seguiría proporcionando la misma copia en caché incluso después de que el contenido en la
caché interna haya sido invalidada. Por lo tanto, hay que tener mucho cuidado al configurar el tiempo de duración o las
dependencias de las cachés anidadas, de lo contrario los fragmentos internos que ya estén obsoletos se pueden seguir
manteniendo en el fragmento externo.
Contenido Dinámico
Cuando se usa la caché de fragmentos, podrías encontrarte en la situación que un fragmento grande de contenido es
relavitamente estático excepto en uno u otro lugar. Por ejemplo, la cabeza de una página (header) puede que muestre el
menú principal junto al nombre del usuario actual. Otro problema es que el contenido que está siendo almacenado en caché
puede que contenga código PHP que debe ser ejecutado en cada petición (por ejemplo, el código para registrar
un paquete de recursos (asset bundle)). En ambos casos, podríamos resolver el problema con lo que llamamos la
característica de contenido dinámico.
Entendemos contenido dinámico como un fragmento de salida que no debería ser guardado en caché incluso si está
encerrado dentro de un fragmento de caché. Para hacer el contenido dinámico todo el tiempo, éste ha de ser generado ejecutando
cierto código PHP en cada petición, incluso si el contenido está siendo mostrado desde la caché.
Puedes llamar a [[yii\base\View::renderDynamic()]] dentro de un fragmento almacenado en caché para insertar código
dinámico en el lugar deseado como, por ejemplo, de la siguiente manera,
if ($this->beginCache($id1)) {
// ... lógica de generación de contenido ...
echo $this->renderDynamic('return Yii::$app->user->identity->name;');
// ... lógica de generación de contenido ...
$this->endCache();
}El método [[yii\base\View::renderDynamic()|renderDynamic()]] toma una pieza de código PHP como su parámetro. El valor
devuelto del código PHP se trata como contenido dinámico. El mismo código PHP será ejecutado en cada petición,
sin importar que esté dentro de un fragmento que está siendo servido desde la caché o no.
Guide Es Caching Http (`docs/guide-es/caching-http.md`)
Caché HTTP
Además del almacenamiento de caché en el servidor que hemos descrito en secciones anteriores, las aplicaciones Web
pueden hacer uso de la caché en el lado del cliente para así ahorrar tiempo y recursos para generar y transmitir el
mismo contenido una y otra vez.
Para usar la caché del lado del cliente, puedes configurar [[yii\filters\HttpCache]] como un filtro en el controlador
para aquellas acciones cuyo resultado deba estar almacenado en la caché en el lado del cliente. [[yii\filters\HttpCache|HttpCache]]
solo funciona en peticiones GET y HEAD. Puede manejar tres tipos de cabeceras (headers) HTTP relacionadas en este tipo de
consultas:
- [[yii\filters\HttpCache::lastModified|Last-Modified]]
- [[yii\filters\HttpCache::etagSeed|Etag]]
- [[yii\filters\HttpCache::cacheControlHeader|Cache-Control]]
La Cabecera `Last-Modified`
La cabecera Last-Modified usa un sello de tiempo para indicar si la página ha sido modificada desde que el cliente la
almacena en la caché.
Puedes configurar la propiedad [[yii\filters\HttpCache::lastModified]] para activar el envío de la cabecera Last-Modified.
La propiedad debe ser una llamada de retorno (callable) PHP que devuelva un timestamp UNIX sobre el tiempo de modificación de
la página. El formato de la función de llamada de retorno debe ser el siguiente,
/**
* @param Action $action el objeto acción que se está controlando actualmente
* @param array $params el valor de la propiedad "params"
* @return int un sello de tiempo UNIX que representa el tiempo de modificación de la página
*/
function ($action, $params)El siguiente es un ejemplo haciendo uso de la cabecera Last-Modified:
public function behaviors()
{
return [
[
'class' => 'yii\filters\HttpCache',
'only' => ['index'],
'lastModified' => function ($action, $params) {
$q = new \yii\db\Query();
return $q->from('post')->max('updated_at');
},
],
];
}El código anterior establece que la memoria caché HTTP debe ser habilitada únicamente por la acción index. Se debe
generar una cabecera HTTP Last-Modified basado en el último tiempo de actualización de los artículos. Cuando un
navegador visita la página index la primera vez, la página será generada en el servidor y enviada al navegador; Si el
navegador visita la misma página de nuevo y no ningún artículo modificado durante el período, el servidor no volverá a
regenerar la página, y el navegador usará la versión caché del lado del cliente. Como resultado, la representación del
lado del servidor y la transmisión del contenido de la página son ambos omitidos.
La Cabecera `ETag`
La cabecera "Entity Tag" (o para abreviar ETag) usa un hash para representar el contenido de una página. Si la página
ha sido cambiada, el hash también cambiará. Al comparar el hash guardado en el lado del cliente con el hash generado en
el servidor, la caché puede determinar si la página ha cambiado y deber ser retransmitida.
Puedes configurar la propiedad [[yii\filters\HttpCache::etagSeed]] para activar el envío de la cabecera ETag.
La propiedad debe ser una función de retorno (callable) PHP que devuelva una semilla para la generación del hash de ETag.
El formato de la función de retorno es el siguiente:
/**
* @param Action $action el objeto acción que se está controlando actualmente
* @param array $params el valor de la propiedad "params"
* @return string una cadena usada como semilla para la generación del hash de ETag
*/
function ($action, $params)El siguiente es un ejemplo de cómo usar la cabecera ETag:
public function behaviors()
{
return [
[
'class' => 'yii\filters\HttpCache',
'only' => ['view'],
'etagSeed' => function ($action, $params) {
$post = $this->findModel(\Yii::$app->request->get('id'));
return serialize([$post->title, $post->content]);
},
],
];
}El código anterior establece que la caché HTTP debe ser activada únicamente para la acción view. Debería generar una
cabecera HTTP ETag basándose en el título y contenido del artículo consultado. Cuando un navegador visita la páginaview por primera vez, la página se generará en el servidor y será enviada al navegador; Si el navegador visita la
misma página de nuevo y no ha ocurrido un cambio en el título o contenido del artículo, el servidor no volverá a generar
la página, y el navegador usará la versión guardada en la caché del lado del cliente. Como resultado, la representación del
lado del servidor y la transmisión del contenido de la página son ambos omitidos.
ETags permiten estrategias de almacenamiento de caché más complejas y/o mucho más precisas que las cabeceras Last-Modified.
Por ejemplo, un ETag puede ser invalidado si el sitio Web ha cambiado de tema (theme).
La generación de un ETag que requiera muchos recursos puede echar por tierra el propósito de estar usando HttpCache e
introducir una sobrecarga innecesaria, ya que debe ser re-evaluada en cada solicitud (request). Trata de encontrar una
expresión sencilla para invalidar la caché si la página ha sido modificada.
Note: En cumplimiento con RFC 7232,
HttpCacheenviará ambas cabecerasETagyLast-Modifiedsi ambas están configuradas. Y si el clientes envía tanto la cabeceraIf-None-Matchcomo la cabeceraIf-Modified-Since, solo la primera será respetada.
La Cabecera `Cache-Control`
La cabecera Cache-Control especifica la directiva general de la caché para páginas. Puedes enviarla configurando la
propiedad [[yii\filters\HttpCache::cacheControlHeader]] con el valor de la cabecera. Por defecto, la siguiente cabecera
será enviada:
Cache-Control: public, max-age=3600Limitador de la Sesión de Caché
Cuando una página utiliza la sesión, PHP enviará automáticamente cabeceras HTTP relacionadas con la caché tal y como se
especifican en session.cache_limiter de la configuración INI de PHP. Estas cabeceras pueden interferir o deshabilitar
el almacenamiento de caché que desees de HttpCache. Para evitar este problema, por defecto HttpCache deshabilitará
automáticamente el envío de estas cabeceras. Si deseas modificar este comportamiento, tienes que configurar la propiedad
[[yii\filters\HttpCache::sessionCacheLimiter]]. La propiedad puede tomar un valor de cadena, incluyendo public, private,private_no_expire, and nocache. Por favor, consulta el manual PHP acerca de session_cache_limiter()
para una mejor explicación sobre esos valores.
Implicaciones SEO
Los robots de motores de búsqueda tienden a respetar las cabeceras de caché. Dado que algunos crawlers tienen limitado
el número de páginas que pueden rastrear por dominios dentro de un cierto período de tiempo, la introducción de cabeceras
de caché pueden ayudar a la indexación del sitio Web y reducir el número de páginas que deben ser procesadas.
Guide Es Caching Page (`docs/guide-es/caching-page.md`)
Caché de Páginas
La caché de páginas se refiere a guardar el contenido de toda una página en el almacenamiento de caché del servidor.
Posteriormente, cuando la misma página sea requerida de nuevo, su contenido será devuelto desde la caché en vez de
volver a generarlo desde cero.
El almacenamiento en caché de páginas está soportado por [[yii\filters\PageCache]], un filtro de acción.
Puede ser utilizado de la siguiente forma en un controlador:
public function behaviors()
{
return [
[
'class' => 'yii\filters\PageCache',
'only' => ['index'],
'duration' => 60,
'variations' => [
\Yii::$app->language,
],
'dependency' => [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT COUNT(*) FROM post',
],
],
];
}El código anterior establece que el almacenamiento de páginas en caché debe ser utilizado sólo en la acción index; el
contenido de la página debería almacenarse durante un máximo de 60 segundos y ser variado por el idioma actual de la
aplicación; además, el almacenamiento de la página en caché debería ser invalidado si el número total de
artículos ha cambiado.
Como puedes ver, la caché de páginas es muy similar a la caché de fragmentos. Ambos soportan opciones
tales como duration, dependencies, variations, y enabled. Su principal diferencia es que la caché de páginas está
implementado como un filtro de acción mientras que la caché de fragmentos se hace en un widget.
Puedes usar la caché de fragmentos así como el contenido dinámico
junto con la caché de páginas.
Guide Es Concept Aliases (`docs/guide-es/concept-aliases.md`)
Alias
Loa alias son utilizados para representar rutas o URLs de manera que no tengas que escribir explícitamente rutas absolutas o URLs en tu
proyecto. Un alias debe comenzar con el signo @ para ser diferenciado de una ruta normal de archivo y de URLs. Los alias definidos
sin el @ del principio, serán prefijados con el signo @.
Yii trae disponibles varios alias predefinidos. Por ejemplo, el alias @yii representa la ruta de instalación del
framework Yii; @web representa la URL base para la aplicación Web ejecutándose.
Definir Alias
Para definir un alias puedes llamar a [[Yii::setAlias()]] para una determinada ruta de archivo o URL. Por ejemplo,
// un alias de una ruta de archivos
Yii::setAlias('@foo', '/path/to/foo');
// una alias de un URL
Yii::setAlias('@bar', 'https://www.example.com');Note: Una ruta de archivo o URL en alias NO debe necesariamente referirse a un archivo o recurso existente.
Dado un alias, puedes derivar un nuevo alias (sin necesidad de llamar [[Yii::setAlias()]]) anexando una barra diagonal /
seguida por uno o varios segmentos de la ruta. Llamamos los alias definidos a través de [[Yii::setAlias()]]
alias de raíz (root alias), mientras que los alias derivados de ellos alias derivados (derived aliases). Por ejemplo,@foo es un alias de raíz, mientras que @foo/bar/file.php es un alias derivado.
Puedes definir un alias usando otro alias (ya sea un alias de raíz o derivado):
Yii::setAlias('@foobar', '@foo/bar');Los alias de raíz están usualmente definidos durante la etapa bootstrapping de la aplicación.
Por ejemplo, puedes llamar a [[Yii::setAlias()]] en el script de entrada.
Por conveniencia, Application provee una propiedad modificable llamada aliases que puedes
configurar en la configuración de la aplicación, como por ejemplo,
return [
// ...
'aliases' => [
'@foo' => '/path/to/foo',
'@bar' => 'https://www.example.com',
],
];Resolución de Alias
Puedes llamar [[Yii::getAlias()]] para resolver un alias de raíz en la ruta o URL que representa. El mismo método puede
además resolver un alias derivado en su correspondiente ruta de archivo o URL. Por ejemplo,
echo Yii::getAlias('@foo'); // muestra: /path/to/foo
echo Yii::getAlias('@bar'); // muestra: https://www.example.com
echo Yii::getAlias('@foo/bar/file.php'); // muestra: /path/to/foo/bar/file.phpLa ruta de archivo/URL representado por un alias derivado está determinado por la sustitución de la parte de su alias raíz
con su correspondiente ruta/Url en el alias derivado.
Note: El método [[Yii::getAlias()]] no comprueba si la ruta/URL resultante hacer referencia a un archivo o recurso existente.
Un alias de raíz puede contener carácteres /. El método [[Yii::getAlias()]] es lo suficientemente inteligente para saber
qué parte de un alias es un alias de raíz y por lo tanto determinar correctamente la correspondiente ruta de archivo o URL.
Por ejemplo,
Yii::setAlias('@foo', '/path/to/foo');
Yii::setAlias('@foo/bar', '/path2/bar');
Yii::getAlias('@foo/test/file.php'); // muestra: /path/to/foo/test/file.php
Yii::getAlias('@foo/bar/file.php'); // muestra: /path2/bar/file.phpSi @foo/bar no está definido como un alias de raíz, la última declaración mostraría /path/to/foo/bar/file.php.
Usando Alias
Los alias son utilizados en muchos lugares en Yii sin necesidad de llamar [[Yii::getAlias()]] para convertirlos
en rutas/URLs. Por ejemplo, [[yii\caching\FileCache::cachePath]] puede aceptar tanto una ruta de archivo como un alias
que represente la ruta de archivo, gracias al prefijo @ el cual permite diferenciar una ruta de archivo
de un alias.
use yii\caching\FileCache;
$cache = new FileCache([
'cachePath' => '@runtime/cache',
]);Por favor, presta atención a la documentación API para ver si una propiedad o el parámetro de un método soporta alias.
Alias Predefinidos
Yii predefine un conjunto de alias para aliviar la necesidad de hacer referencia a rutas de archivo o URLs que son
utilizadas regularmente. La siguiente es la lista de alias predefinidos por Yii:
@yii: el directorio donde el archivoBaseYii.phpse encuentra (también llamado el directorio del framework).@app: la [[yii\base\Application::basePath|ruta base]] de la aplicación que se está ejecutando actualmente.@runtime: la [[yii\base\Application::runtimePath|ruta de ejecución]] de la aplicación en ejecución. Por defecto@app/runtime.@webroot: el directorio raíz Web de la aplicación Web se está ejecutando actualmente.@web: la URL base de la aplicación web se ejecuta actualmente. Tiene el mismo valor que [[yii\web\Request::baseUrl]].@vendor: el [[yii\base\Application::vendorPath|directorio vendor de Composer]]. Por defecto@app/vendor.@bower, el directorio raíz que contiene paquetes bower. Por defecto@vendor/bower.@npm, el directorio raíz que contiene paquetes npm. Por defecto@vendor/npm.
El alias @yii se define cuando incluyes el archivo Yii.php en tu script de entrada,
mientras que el resto de los alias están definidos en el constructor de la aplicación cuando se aplica la
configuración de la aplicación.
Alias en Extensiones
Un alias se define automáticamente por cada extensión que ha sido instalada a través de Composer.
El alias es nombrado tras el namespace de raíz de la extensión instalada tal y como está declarada en su archivo composer.json,
y representa el directorio raíz de la extensión. Por ejemplo, si instalas la extensión yiisoft/yii2-jui, tendrás
automáticamente definido el alias @yii/jui durante la etapa bootstrapping de la aplicación:
Yii::setAlias('@yii/jui', 'VendorPath/yiisoft/yii2-jui');Guide Es Concept Autoloading (`docs/guide-es/concept-autoloading.md`)
Autocarga de clases
Yii depende del mecanismo de autocarga de clases para localizar
e incluir los archivos de las clases requiridas. Proporciona un cargador de clases de alto rendimiento que cumple con el
estandard PSR-4.
El cargador se instala cuando incluyes el archivo Yii.php.
Note: Para simplificar la descripción, en esta sección sólo hablaremos de la carga automática de clases. Sin embargo,
ten en cuenta que el contenido que describimos aquí también se aplica a la autocarga de interfaces y rasgos (Traits).
Usando el Autocargador de Yii
Para utilizar el cargador automático de clases de Yii, deberías seguir dos reglas básicas cuando desarrolles y nombres tus
clases:
- Cada clase debe estar bajo un espacio de nombre (namespace). Por ejemplo
foo\bar\MyClass. - Cada clase debe estar guardada en un archivo individual cuya ruta está determinada por el siguiente algoritmo:
// $className es un nombre completo de clase con las iniciales barras invertidas.
$classFile = Yii::getAlias('@' . str_replace('\\', '/', $className) . '.php');Por ejemplo, si el nombre de una clase es foo\bar\MyClass, el alias la correspondiente ruta de
archivo de la clase sería @foo/bar/MyClass.php. Para que este sea capaz de ser resuelto como una ruta de archivo, ya sea@foo o @foo/bar debe ser un alias de raíz (root alias).
Cuando utilizas la Plantilla de Aplicación Básica, puede que pongas tus clases bajo el nivel superior
de espacio de nombres app para que de esta manera pueda ser automáticamente cargado por Yii sin tener la necesidad de
definir un nuevo alias. Esto es porque @app es un alias predefinido, y el
nombre de una clase tal como app\components\MyClass puede ser resuelto en el archivo de la clase AppBasePath/components/MyClass.php,
de acuerdo con el algoritmo previamente descrito.
En la Plantilla de Aplicación Avanzada, cada nivel tiene su propio alias. Por ejemplo, el nivelfront-end tiene un alias de raíz @frontend mientras que el nivel back-end tiene @backend. Como resultado, es posible
poner las clases front-end bajo el espacio de nombres frontend mientras que las clases back-end pueden hacerlo bajobackend. Esto permitirá que estas clases sean automaticamente cargadas por el autocargador de Yii.
Mapa de Clases
El autocargador de clases de Yii soporta el mapa de clases, que mapea nombres de clases to sus correpondientes rutas de
archvios. Cuando el autocargador esta cargando una clase, primero chequeará si la clase se encuentra en el mapa. Si es así,
el correspondiente archivo será incluido directamente sin más comprobación. Esto hace que la clase se cargue muy rápidamente.
De hecho, todas las clases de Yii son autocargadas de esta manera.
Puedes añadir una clase al mapa de clases Yii::$classMap de la siguiente forma,
Yii::$classMap['foo\bar\MyClass'] = 'path/to/MyClass.php';Alias puede ser usado para especificar la ruta de archivos de clases. Deberías iniciar el mapeo de
clases en el proceso bootstrapping de la aplicación para que de esta manera el mapa esté listo
antes de que tus clases sean usadas.
Usando otros Autocargadores
Debido a que Yii incluye Composer como un gestor de dependencias y extensions, es recomendado que también instales el
autocargador de Composer. Si estás usando alguna librería externa que requiere sus autocargadores, también deberías
instalarlos.
Cuando se utiliza el cargador de clases automático de Yii conjuntamente con otros autocargadores, deberías incluir el
archivo Yii.php después de que todos los demás autocargadores se hayan instalado. Esto hará que el autocargador de
Yii sea el primero en responder a cualquier petición de carga automática de clases. Por ejemplo, el siguiente código ha
sido extraido del script de entrada de la Plantilla de Aplicación Básica.
La primera línea instala el autocargador de Composer, mientras que la segunda línea instala el autocargador de Yii.
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';Puedes usar el autocargador de Composer sin el autocargador de Yii. Sin embargo, al hacerlo, la eficacia de la carga de
tus clases puede que se degrade, y además deberías seguir las reglas establecidas por Composer para que tus clases pudieran
ser autocargables.
Note: Si no deseas utilizar el autocargador de Yii, tendrás que crear tu propia versión del archivo
Yii.phpe
incluirlo en tu script de entrada.
Carga Automática de Clases de Extensiones
El autocargador de Yii es capaz de autocargar clases de extensiones. El único requirimiento es
que la extensión especifique correctamente la sección de autoload (autocarga) en su archivo composer.json. Por favor,
consulta la documentación de Composer para más detalles acerca de la
especificación autoload.
En el caso de que no quieras usar el autocargador de Yii, el autocargador de Composer podría cargar las clases de extensiones
por tí.
Guide Es Concept Behaviors (`docs/guide-es/concept-behaviors.md`)
Comportamientos
Comportamientos son instancias de [[yii\base\Behavior]] o sus clases "hija". Comportamientos, también conocido como
mixins, te permiten mejorar la funcionalidad de un [[yii\base\Component|componente]]
existente sin necesidad de modificar su herencia de clases.
Cuando un comportamiento se une a un componente, "inyectará" sus métodos y propiedades dentro del componente, y podrás
acceder a esos métodos y propiedades como si hubieran estado definidos por la clase de componente. Además, un
comportamiento puede responder a eventos disparados por el componente de modo que se pueda personalizar
o adaptar a la ejecución normal del código del componente.
Definiendo comportamientos
Para definir un comportamiento, se debe crear una clase que exiende [[yii\base\Behavior]], o se extiende una clase hija. Por ejemplo:
namespace app\components;
use yii\base\Behavior;
class MyBehavior extends Behavior
{
public $prop1;
private $_prop2;
public function getProp2()
{
return $this->_prop2;
}
public function setProp2($value)
{
$this->_prop2 = $value;
}
public function foo()
{
// ...
}
}El código anterior define la clase de comportamiento (behavior) app\components\MyBehavior, con dos propiedades -- prop1yprop2--y un método foo(). Tenga en cuenta que la propiedad prop2se define a través de la gettergetProp2()y el settersetProp2()`. Este caso es porque [[yii\base\Behavior]] extiende [[yii\base\BaseObject]] y por lo tanto se apoya en la definición de propiedades via getters y setters.
Debido a que esta clase es un comportamiento, cuando está unido a un componente, el componente también tienen la propiedad prop1 y prop2 y el método foo().
Tip: Dentro de un comportamiento, puede acceder al componente que el comportamiento está unido a través de la propiedad [[yii\base\Behavior::owner]].
Gestión de eventos de componentes
Si un comportamiento necesita responder a los acontecimientos desencadenados por el componente al que está unido, se debe reemplazar el método [[yii\base\Behavior::events()]]. Por ejemplo:
namespace app\components;
use yii\db\ActiveRecord;
use yii\base\Behavior;
class MyBehavior extends Behavior
{
// ...
public function events()
{
return [
ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
];
}
public function beforeValidate($event)
{
// ...
}
}El método [[yii\base\Behavior::events()|events()]] debe devolver una lista de eventos y sus correspondientes controladores.
El ejemplo anterior declara que el evento [[yii\db\ActiveRecord::EVENT_BEFORE_VALIDATE|EVENT_BEFORE_VALIDATE]] existe y esta exists y define su controlador, beforeValidate(). Al especificar un controlador de eventos, puede utilizar uno de los siguientes formatos:
- una cadena que se refiere al nombre de un método de la clase del comportamiento, como el ejemplo anterior
- un arreglo de objeto o nombre de clase, y un nombre de método como una cadena (sin paréntesis), ej.,
[$object, 'methodName']; - una función anónima
La firma de un controlador de eventos debe ser la siguiente, donde $ event refiere al parámetro de evento. Por favor, consulte la sección Eventos para más detalles sobre los eventos.
function ($event) {
}Vinculando Comportamientos
Puedes vincular un comportamiento a un [[yii\base\Component|componente]] ya sea estática o dinámicamente. La primera forma
es la más comúnmente utilizada en la práctica.
Para unir un comportamiento estáticamente, reemplaza el método [[yii\base\Component::behaviors()|behaviors()]] dde la clase de componente a la que se une el comportamiento. El método [[yii\base\Component::behaviors()|behaviors()]] debe devolver una lista de comportamiento configuraciones.
Cada configuración de comportamiento puede ser un nombre de clase de comportamiento o un arreglo de configuración:
namespace app\models;
use yii\db\ActiveRecord;
use app\components\MyBehavior;
class User extends ActiveRecord
{
public function behaviors()
{
return [
// anonymous behavior, behavior class name only
MyBehavior::class,
// named behavior, behavior class name only
'myBehavior2' => MyBehavior::class,
// anonymous behavior, configuration array
[
'class' => MyBehavior::class,
'prop1' => 'value1',
'prop2' => 'value2',
],
// named behavior, configuration array
'myBehavior4' => [
'class' => MyBehavior::class,
'prop1' => 'value1',
'prop2' => 'value2',
]
];
}
}Puedes asociciar un nombre a un comportamiento especificándolo en la clave de la matriz correspondiente a la configuración
del comportamiento. En este caso, el comportamiento puede ser llamado un comportamiento nombrado (named behavior). En
el ejemplo anterior, hay dos tipos de comportamientos nombrados: myBehavior2 y myBehavior4. Si un comportamiento
no está asociado con un nombre, se le llama comportamiento anónimo (anonymous behavior).
Para vincular un comportamiento dinámicamente, llama al método [[yii\base\Component::attachBehavior()]] desde el componente al
que se le va a unir el comportamiento:
use app\components\MyBehavior;
// vincular un objeto comportamiento "behavior"
$component->attachBehavior('myBehavior1', new MyBehavior());
// vincular una clase comportamiento
$component->attachBehavior('myBehavior2', MyBehavior::class);
// asociar una matriz de configuración
$component->attachBehavior('myBehavior3', [
'class' => MyBehavior::class,
'prop1' => 'value1',
'prop2' => 'value2',
]);Puede vincular múltiples comportamientos a la vez mediante el uso del método [[yii\base\Component::attachBehaviors()]]. Por ejemplo,
$component->attachBehaviors([
'myBehavior1' => new MyBehavior(), // un comportamiento nombrado
MyBehavior::class, // un comportamiento anónimo
]);También puedes asociar comportamientos a traves de configuraciones como el siguiente:
[
'as myBehavior2' => MyBehavior::class,
'as myBehavior3' => [
'class' => MyBehavior::class,
'prop1' => 'value1',
'prop2' => 'value2',
],
]Para más detalles, por favor visita la sección Configuraciones.
Usando comportamientos
Para poder utilizar un comportamiento, primero tienes que unirlo a un [[yii\base\Component|componente]] según las instrucciones anteriores. Una vez que un comportamiento ha sido vinculado a un componente, su uso es sencillo.
Puedes usar a una variable pública o a una propiedad definida por un getter y/o un setter
del comportamiento a través del componente con el que se ha vinculado:
// "prop1" es una propiedad definida en la clase comportamiento
echo $component->prop1;
$component->prop1 = $value;También puedes llamar métodos públicos del comportamiento de una forma similar:
// foo() es un método público definido dentro de la clase comportamiento
$component->foo();Como puedes ver, aunque $component no tiene definida prop1 y bar(), que se pueden utilizar como si son parte
de la definición de componentes debido al comportamiento vinculado.
Si dos comportamientos definen la misma propiedad o método y ambos están vinculados con el mismo componente, el
comportamiento que ha sido vinculado primero tendrá preferencia cuando se esté accediendo a la propiedad o método.
Un comportamiento puede estar asociado con un nombre cuando se une a un componente. Si este es el caso, es posible
acceder al objeto de comportamiento mediante el nombre, como se muestra a continuación,
$behavior = $component->getBehavior('myBehavior');También puedes acceder a todos los comportamientos vinculados al componente:
$behaviors = $component->getBehaviors();Desasociar Comportamientos
Para desasociar un comportamiento, puedes llamar el método [[yii\base\Component::detachBehavior()]] con el nombre con el
que se le asoció:
$component->detachBehavior('myBehavior1');También puedes desvincular todos los comportamientos:
$component->detachBehaviors();Utilizando `TimestampBehavior`
Para terminar, vamos a echar un vistazo a [[yii\behaviors\TimestampBehavior]]. Este comportamiento soporta de forma
automática la actualización de atributos timestamp de un modelo [[yii\db\ActiveRecord|Registro Activo]]
(Active Record) en cualquier momento donde se guarda el modelo (ej., en la inserción o actualización).
Primero, vincula este comportamiento a la clase [[yii\db\ActiveRecord|Active Record]] que desees utilizar.
namespace app\models\User;
use yii\db\ActiveRecord;
use yii\behaviors\TimestampBehavior;
class User extends ActiveRecord
{
// ...
public function behaviors()
{
return [
[
'class' => TimestampBehavior::class,
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
],
],
];
}
}La configuración del comportamiento anterior especifica que
- cuando el registro está siendo insertado, el comportamiento debe asignar el sello de tiempo actual a los atributos
created_atyupdated_at; - cuando el registro está siendo actualizado, el comportamiento debe asignar el sello de tiempo actual al atributo
updated_at.
Ahora si tienes un objeto User e intentas guardarlo, descubrirás que sus campos created_at y updated_at están
automáticamente actualizados con el sello de tiempo actual:
$user = new User;
$user->email = '[email protected]';
$user->save();
echo $user->created_at; // muestra el sello tiempo actual (timestamp)El comportamiento [[yii\behaviors\TimestampBehavior|TimestampBehavior]] también ofrece un método muy útil llamado
[[yii\behaviors\TimestampBehavior::touch()|touch()]], que asigna el sello de tiempo actual a un atributo especificado y lo guarda automáticamente en la base de datos:
$user->touch('login_time');Comparación con Traits
Mientras que los comportamientos son similares a traits en cuanto que ambos "inyectan" sus
métodos y propiedades a la clase primaria, son diferentes en muchos aspectos. Tal y como se describe abajo, los dos
tienen sus ventajas y desventajas. Son más como complementos el uno al otro en lugar de alternativas.
Razones para utilizar comportamientos
Las clases de comportamientos, como todas las clases, soportan herencias. Traits, por otro lado, pueden ser
considerados como un copia-y-pega de PHP. Ellos no soportan la herencia de clases.
Los comportamientos pueden ser asociados y desasociados a un componente dinámicamente sin necesidad de que la clase del
componente sea modificada. Para usar un trait, debes modificar la clase que la usa.
Los comportamientos son configurables mientras que los traits no.
Los comportamientos pueden personalizar la ejecución de un componente al responder a sus eventos.
Cuando hay un conflicto de nombre entre los diferentes comportamientos vinculados a un mismo componente, el conflicto es
automáticamente resuelto respetando al que ha sido asociado primero.
El conflicto de nombres en traits requiere que manualmente sean resueltos cambiando el nombre de las propiedades o métodos afectados.
Razones para utilizar los Traits
Los Traits son mucho más eficientes que los comportamientos debido a que los últimos son objetos que consumen tiempo y
memoria.
Los IDEs (Programas de desarrollo) son más amigables con traits ya que son una construcción del lenguaje nativo.
Guide Es Concept Components (`docs/guide-es/concept-components.md`)
Componentes
Los componentes son los principales bloques de construcción de las aplicaciones Yii. Los componentes son instancias de [[yii\base\Component]] o de una clase extendida. Las tres características principales que los componentes proporcionan
a las otras clases son:
Por separado y combinadas, estas características hacen que las clases Yii sean mucho mas personalizables y sean mucho más fáciles de usar. Por ejemplo, el incluido [[yii\jui\DatePicker|widget de selección de fecha]], un componente de la interfaz de usuario, puede ser utilizado en una vista para generar un DatePicker interactivo:
use yii\jui\DatePicker;
echo DatePicker::widget([
'language' => 'ru',
'name' => 'country',
'clientOptions' => [
'dateFormat' => 'yy-mm-dd',
],
]);Las propiedades del widget son fácilmente modificables porque la clase se extiende de [[yii\base\Component]].
Mientras que los componentes son muy potentes, son un poco más pesados que los objetos normales, debido al hecho de que necesitan más memoria y tiempo de CPU para poder soportar eventos y comportamientos en particular.
Si tus componentes no necesitan estas dos características, deberías considerar extender tu componente directamente de [[yii\base\BaseObject]] en vez de [[yii\base\Component]]. De esta manera harás que tus componentes sean mucho más eficientes que objetos PHP normales, pero con el añadido soporte para propiedades.
Cuando extiendes tu clase de [[yii\base\Component]] o [[yii\base\BaseObject]], se recomienda que sigas las siguientes convenciones:
- Si sobrescribes el constructor, especifica un parámetro
$configcomo el último parámetro del constructor, y después pasa este parámetro al constructor padre. - Siempre llama al constructor padre al final de su propio constructor.
- Si sobrescribes el método [[yii\base\BaseObject::init()]], asegúrese de llamar la implementación padre de
init* al principio * de su métodoinit.
Por ejemplo:
namespace yii\components\MyClass;
use yii\base\BaseObject;
class MyClass extends BaseObject
{
public $prop1;
public $prop2;
public function __construct($param1, $param2, $config = [])
{
// ... inicialización antes de la configuración está siendo aplicada
parent::__construct($config);
}
public function init()
{
parent::init();
// ... inicialización después de la configuración esta siendo aplicada
}
}Siguiendo esas directrices hará que tus componentes sean configurables cuando son creados. Por ejemplo:
$component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]);
// alternativamente
$component = \Yii::createObject([
'class' => MyClass::class,
'prop1' => 3,
'prop2' => 4,
], [1, 2]);Info: Mientras que el enfoque de llamar [[Yii::createObject()]] parece mucho más complicado, es mucho más potente debido al hecho de que se implementa en la parte superior de un contenedor de inyección de dependencia.
La clase [[yii\base\BaseObject]] hace cumplir el siguiente ciclo de vida del objeto:
- Pre-inicialización en el constructor. Puedes establecer los valores predeterminados de propiedades aquí.
- Configuración del objeto a través de
$config. La configuración puede sobrescribir los valores prdeterminados dentro del constructor. - Post-inicialización dentro de [[yii\base\BaseObject::init()|init()]]. Puedes sobrescribir este método para realizar comprobaciones de validez y normalización de las propiedades.
- Llamadas a métodos del objeto.
Los tres primeros pasos ocurren dentro del constructor del objeto. Esto significa que una vez obtengas la instancia de un objeto, ésta ha sido inicializada para que puedas utilizarla adecuadamente.
Guide Es Concept Configurations (`docs/guide-es/concept-configurations.md`)
Configuración
Las configuraciones se utilizan ampliamente en Yii al crear nuevos objetos o inicializar los objetos existentes. Las configuraciones por lo general incluyen el nombre de la clase del objeto que se está creando, y una lista de los valores iniciales que deberían ser asignadas a las del propiedades objeto. Las configuraciones también pueden incluir una lista de manipuladores que deban imponerse a del objeto eventos y/o una lista de comportamientos que también ha de atribuirse al objeto.
A continuación, una configuración que se utiliza para crear e inicializar una conexión a base de datos:
$config = [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
];
$db = Yii::createObject($config);El método [[Yii::createObject()]] toma una matriz de configuración como su argumento, y crea un objeto intanciando la clase llamada en la configuración. Cuando se crea una instancia del objeto, el resto de la configuración se utilizará para inicializar las propiedades del objeto, controladores de eventos y comportamientos.
Si usted ya tiene un objeto, puede usar [[Yii::configure()]] para inicializar las propiedades del objeto con una matriz de configuración:
Yii::configure($object, $config);Tenga en cuenta que en este caso, la matriz de configuración no debe contener un elemento class.
Formato de Configuración
El formato de una configuración se puede describir formalmente como:
[
'class' => 'ClassName',
'propertyName' => 'propertyValue',
'on eventName' => $eventHandler,
'as behaviorName' => $behaviorConfig,
]donde
- El elemento
classespecifica un nombre de clase completo para el objeto que se está creando. - Los elementos
propertyNameespecifica los valores iniciales de la propiedad con nombre. Las claves son los nombres de las propiedades y los valores son los valores iniciales correspondientes. Sólo los miembros de variables públicas y propiedades definidas por getters/setters se pueden configurar. - Los elementos
on eventNameespecifican qué manipuladores deberán adjuntarse al del objeto eventos. Observe que las claves de matriz se forman prefijando nombres de eventos conon. Por favor, consulte la sección Eventos para los formatos de controlador de eventos compatibles. - Los elementos
as behaviorNameespecifican qué comportamientos deben adjuntarse al objeto. Observe que las claves de matriz se forman prefijando nombres de comportamiento conas; el valor,$behaviorConfig, representa la configuración para la creación de un comportamiento, como una configuración normal descrita aquí.
A continuación se muestra un ejemplo de una configuración con los valores de propiedad iniciales, controladores de eventos y comportamientos:
[
'class' => 'app\components\SearchEngine',
'apiKey' => 'xxxxxxxx',
'on search' => function ($event) {
Yii::info("Keyword searched: " . $event->keyword);
},
'as indexer' => [
'class' => 'app\components\IndexerBehavior',
// ... property init values ...
],
]Usando Configuraciones
Las configuraciones se utilizan en muchos lugares en Yii. Al comienzo de esta sección, hemos demostrado cómo crear un objeto según una configuración mediante el uso de [[Yii::createObject()]]. En este apartado, vamos a describir configuraciones de aplicaciones y configuraciones widget - dos principales usos de configuraciones.
Configuraciones de aplicación
Configuración para una aplicación es probablemente una de las configuraciones más complejas. Esto se debe a que la clase [[yii\web\Application|aplicación]] tiene un montón de propiedades y eventos configurables. Más importante aún, su propiedad [[yii\web\Application::components|componentes]] que puede recibir una gran variedad de configuraciones para crear componentes que se registran a través de la aplicación. Lo siguiente es un resumen del archivo de configuración de la aplicación para la plantilla básica de la aplicación.
$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'extensions' => require __DIR__ . '/../vendor/yiisoft/extensions.php',
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
],
'log' => [
'class' => 'yii\log\Dispatcher',
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
],
],
],
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=stay2',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
],
];La configuración no tiene una clave class. Esto es porque se utiliza como sigue en un script de entrada, donde ya se le da el nombre de la clase,
(new yii\web\Application($config))->run();Para más detalles sobre la configuración de la propiedad components de una aplicación se puede encontrar en la sección Aplicación y la sección Localizador de Servicio.
Configuración Widget
Cuando se utiliza widgets, a menudo es necesario utilizar las configuraciones para personalizar las propiedades de widgets. Tanto los metodos [[yii\base\Widget::widget()]] y [[yii\base\Widget::begin()]] pueden usarse para crear un widget. Toman un arreglo de configuración, como el siguiente,
use yii\widgets\Menu;
echo Menu::widget([
'activateItems' => false,
'items' => [
['label' => 'Home', 'url' => ['site/index']],
['label' => 'Products', 'url' => ['product/index']],
['label' => 'Login', 'url' => ['site/login'], 'visible' => Yii::$app->user->isGuest],
],
]);El código anterior crea un widget Menu e inicializa su propiedad activeItems en falsa. La propiedad items también se configura con elementos de menú que se muestran.
Tenga en cuenta que debido a que el nombre de la clase ya está dado, la matriz de configuración no deben tener la clave class.
Archivos de Configuración
Cuando una configuración es muy compleja, una práctica común es almacenarla en uno o múltiples archivos PHP, conocidos como archivos de configuración. Un archivo de configuración devuelve un array de PHP que representa la configuración. Por ejemplo, es posible mantener una configuración de la aplicación en un archivo llamado web.php, como el siguiente,
return [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'extensions' => require __DIR__ . '/../vendor/yiisoft/extensions.php',
'components' => require __DIR__ . '/components.php',
];Debido a que la configuración componentes es compleja también, se guarda en un archivo separado llamado components.php y "requerir" este archivo en web.php como se muestra arriba. El contenido de components.php es el siguiente,
return [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
],
'log' => [
'class' => 'yii\log\Dispatcher',
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
],
],
],
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=stay2',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
];Para obtener una configuración almacenada en un archivo de configuración, simplemente "requerir" este, como el siguiente:
$config = require 'path/to/web.php';
(new yii\web\Application($config))->run();Configuraciones por Defecto
El método [[Yii::createObject()]] es implementado en base a contenedor de inyección de dependencia. Le permite especificar un conjunto de los llamados configuraciones predeterminadas que se aplicarán a todos los casos de las clases especificadas cuando se crean utilizando [[Yii::createObject()]]. Las configuraciones por defecto se puede especificar llamando Yii::$container->set() en el código bootstrapping.
Por ejemplo, si desea personalizar [[yii\widgets\LinkPager]] para que TODO enlace de búsqueda muestre como máximo 5 botones de página (el valor por defecto es 10), puede utilizar el siguiente código para lograr este objetivo,
\Yii::$container->set('yii\widgets\LinkPager', [
'maxButtonCount' => 5,
]);Sin utilizar las configuraciones predeterminadas, usted tendría que configurar maxButtonCount en cada lugar en el que utiliza enlace paginador.
Constantes de Entorno
Las configuraciones a menudo varían de acuerdo al entorno en que se ejecuta una aplicación. Por ejemplo, en el entorno de desarrollo, es posible que desee utilizar una base de datos llamada mydb_dev, mientras que en servidor de producción es posible que desee utilizar la base de datos mydb_prod. Para facilitar la conmutación de entornos, Yii proporciona una constante llamado YII_ENV que se puede definir en el script de entrada de su aplicación. Por ejemplo,
defined('YII_ENV') or define('YII_ENV', 'dev');Usted puede definir YII_ENV como uno de los valores siguientes:
prod: entorno de producción. La constanteYII_ENV_PRODevaluará como verdadero.
Este es el valor por defecto deYII_ENVsi no esta definida.dev: entorno de desarrollo. La constanteYII_ENV_DEVevaluará como verdadero.test: entorno de pruebas. La constanteYII_ENV_TESTevaluará como verdadero.
Con estas constantes de entorno, puede especificar sus configuraciones condicionales basado en el entorno actual. Por ejemplo, la configuración de la aplicación puede contener el siguiente código para permitir que el depurador y barra de herramientas de depuración en el entorno de desarrollo.
$config = [...];
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = 'yii\debug\Module';
}
return $config;Guide Es Concept Di Container (`docs/guide-es/concept-di-container.md`)
Contenedor de Inyección de Dependencias
Un contenedor de Inyección de Dependencias (ID), es un objeto que sabe como instancias y configurar objetos y sus
objetos dependientes. El articulo de Martin contiene una buena
explicación de porque son útiles los contenedores de ID. A continuación explicaremos como usar el contenedor de ID que
proporciona Yii.
Inyección de Dependencias
Yii proporciona la función de contenedor de ID mediante la clase [[yii\di\Container]]. Soporta los siguientes tipos
de ID:
- Inyección de constructores;
- Inyección de setters y propiedades;
- Inyección de llamadas de retorno PHP;
Inyección de Constructores
El contenedor de ID soporta inyección de constructores con la ayuda de los indicios (hint) de tipo para los parámetros del
constructor. Los indicios de tipo le proporcionan información al contenedor para saber cuáles son las clases o
interfaces dependientes al usarse para crear un nuevo objeto. El contenedor intentara obtener las instancias de las
clases o interfaces dependientes y las inyectará dentro del nuevo objeto mediante el constructor. Por ejemplo,
class Foo
{
public function __construct(Bar $bar)
{
}
}
$foo = $container->get('Foo');
// que es equivalente a:
$bar = new Bar;
$foo = new Foo($bar);Inyección de Setters y Propiedades
La inyección de setters y propiedades se admite a través de configuraciones. Cuando se
registra una dependencia o se crea un nuevo objeto, se puede proporcionar una configuración que usará el contenedor
para inyectar las dependencias a través de sus correspondientes setters y propiedades. Por ejemplo,
use yii\base\BaseObject;
class Foo extends BaseObject
{
public $bar;
private $_qux;
public function getQux()
{
return $this->_qux;
}
public function setQux(Qux $qux)
{
$this->_qux = $qux;
}
}
$container->get('Foo', [], [
'bar' => $container->get('Bar'),
'qux' => $container->get('Qux'),
]);Inyección de Llamadas de retorno PHP
En este caso, el contenedor usará una llamada de retorno PHP registrada para construir una nueva instancia de una
clase. La llamada de retorno se responsabiliza de que dependencias debe inyectar al nuevo objeto creado. Por ejemplo,
$container->set('Foo', function ($container, $params, $config) {
return new Foo(new Bar);
});
$foo = $container->get('Foo');Registro de dependencias
Se puede usar [[yii\di\Container::set()]] para registrar dependencias. El registro requiere un nombre de dependencia
así como una definición de dependencia. Un nombre de dependencia puede ser un nombre de clase, un nombre de interfaz,
o un nombre de alias; y una definición de dependencia puede ser un nombre de clase, un array de configuración, o una
llamada de retorno PHP.
/* Detailed source-code truncated for AI context efficiency. */Tip: Si un nombre de dependencia es el mismo que la definición de dependencia, no es necesario registrarlo con
el contenedor de ID.
Una dependencia registrada mediante set() generará una instancia cada vez que se necesite la dependencia. Se puede
usar [[yii\di\Container::setSingleton()]] para registrar una dependencia que genere una única instancia:
$container->setSingleton('yii\db\Connection', [
'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);Resolución de Dependencias
Una ves se hayan registrado las dependencias, se puede usar el contenedor de ID para crear nuevos objetos, y el
contenedor resolverá automáticamente las dependencias instanciándolas e inyectándolas dentro de los nuevos objetos
creados. La resolución de dependencias es recursiva, esto significa que si una dependencia tiene otras dependencias,
estas dependencias también se resolverán automáticamente.
Se puede usar [[yii\di\Container::get()]] para crear nuevos objetos. El método obtiene el nombre de dependencia, que
puede ser un nombre de clase, un nombre de interfaz o un nombre de alias. El nombre de dependencia puede estar
registrado o no mediante set() o setSingleton(). Se puede proporcionar opcionalmente un listado de los parámetros
del constructor de clase y una configuración para configurar los nuevos objetos creados.
Por ejemplo,
// "db" ha sido registrado anteriormente como nombre de alias
$db = $container->get('db');
// equivalente a: $engine = new \app\components\SearchEngine($apiKey, ['type' => 1]);
$engine = $container->get('app\components\SearchEngine', [$apiKey], ['type' => 1]);Por detrás, el contenedor de ID efectúa mucho más trabajo la creación de un nuevo objeto. El contenedor primero
inspeccionará la clase constructora para encontrar los nombres de clase o interfaces dependientes y después
automáticamente resolverá estas dependencias recursivamente.
El siguiente código muestra un ejemplo más sofisticado. La clase UserLister depende del un objeto que implementa la
interfaz UserFinderInterface; la clase UserFinder implementa la interfaz y depende del objeto Connection. Todas
estas dependencias se declaran a través de insinuaciones (hinting) de los parámetros del constructor de clase. Con el
registro de dependencia de propiedades, el contenedor de ID puede resolver las dependencias automáticamente y crear
una nueva instancia de UserLister con una simple llamada a get('userLister').
namespace app\models;
use yii\base\BaseObject;
use yii\db\Connection;
use yii\di\Container;
interface UserFinderInterface
{
function findUser();
}
class UserFinder extends BaseObject implements UserFinderInterface
{
public $db;
public function __construct(Connection $db, $config = [])
{
$this->db = $db;
parent::__construct($config);
}
public function findUser()
{
}
}
class UserLister extends BaseObject
{
public $finder;
public function __construct(UserFinderInterface $finder, $config = [])
{
$this->finder = $finder;
parent::__construct($config);
}
}
$container = new Container;
$container->set('yii\db\Connection', [
'dsn' => '...',
]);
$container->set('app\models\UserFinderInterface', [
'class' => 'app\models\UserFinder',
]);
$container->set('userLister', 'app\models\UserLister');
$lister = $container->get('userLister');
// que es equivalente a:
$db = new \yii\db\Connection(['dsn' => '...']);
$finder = new UserFinder($db);
$lister = new UserLister($finder);Uso Practico
Yii crea un contenedor de ID cuando se incluye el archivo Yii.php en el
script de entrada de la aplicación. Cuando se llama a [[Yii::createObject()]] el método
realmente llama al contenedor del método [[yii\di\Container::get()|get()]] para crear un nuevo objeto. Como se ha
comentado anteriormente, el contenedor de ID resolverá automáticamente las dependencias (si las hay) y las inyectará
dentro del nuevo objeto creado. Debido a que Yii utiliza [[Yii::createObject()]] en la mayor parte del núcleo (core)
para crear nuevo objetos, podemos personalizar los objetos globalmente para que puedan tratar con [[Yii::$container]].
Por ejemplo, se puede personalizar globalmenete el numero predeterminado de números de botones de paginación de
[[yii\widgets\LinkPager]]:
\Yii::$container->set('yii\widgets\LinkPager', ['maxButtonCount' => 5]);Ahora si se usa el widget en una vista con el siguiente código, la propiedad maxButtonCount será inicializada con
valor 5 en lugar de 10 que es el valor predeterminado definido en la clase.
echo \yii\widgets\LinkPager::widget();Se puede sobrescribir el valor establecido mediante el contenedor de ID, como a continuación:
echo \yii\widgets\LinkPager::widget(['maxButtonCount' => 20]);Otro ejemplo es aprovechar la ventaja de la inyección automática de constructores de contenedores de ID. Asumiendo que
la clase controlador depende de otros objetos, tales como un servicio de reservas de hotel. Se puede declarar una
dependencia a través de un parámetro del constructor y permitir al contenedor de ID resolverla por nosotros.
namespace app\controllers;
use yii\web\Controller;
use app\components\BookingInterface;
class HotelController extends Controller
{
protected $bookingService;
public function __construct($id, $module, BookingInterface $bookingService, $config = [])
{
$this->bookingService = $bookingService;
parent::__construct($id, $module, $config);
}
}Si se accede al controlador desde el navegador, veremos un error advirtiendo que BookingInterface no puede ser
instanciada. Esto se debe a que necesitamos indicar al contenedor de ID como tratar con esta dependencia:
\Yii::$container->set('app\components\BookingInterface', 'app\components\BookingService');Ahora si se accede al contenedor nuevamente, se creará una instancia de app\components\BookingService y se inyectará
a como tercer parámetro al constructor del controlador.
Cuando Registrar Dependencias
El registro de dependencias debe hacerse lo antes posible debido a que las dependencias se necesitan cuando se crean
nuevos objetos. A continuación se listan practicas recomendadas:
- Siendo desarrolladores de una aplicación, podemos registrar dependencias en el
script de entrada o en un script incluido en el script de entrada. - Siendo desarrolladores de una extension redistribuible, podemos registrar dependencias en
la clase de boostraping de la extensión.
Resumen
Tanto la inyección de dependencias como el localizador de servicios son patrones de
diseño populares que permiten construir software con acoplamiento flexible y más fácil de testear. Se recomienda
encarecida la lectura del articulo de Martin para obtener una mejor
comprensión de la inyección de dependencias y de la localización de servicios.
Yii implementa su propio localizador de servicios por encima del contenedor de ID.
Cuando un localizador de servicios intenta crear una nueva instancia de objeto, se desviará la llamada al contenedor
de ID. Este último resolverá las dependencias automáticamente como se ha descrito anteriormente.
Guide Es Concept Events (`docs/guide-es/concept-events.md`)
Eventos
Los eventos permiten inyectar código dentro de otro código existente en ciertos puntos de ejecución. Se pueden adjuntar
código personalizado a un evento, cuando se lance (triggered), el código se ejecutará automáticamente. Por ejemplo, un
objeto mailer puede lanzar el evento messageSent cuando se envía un mensaje correctamente. Si se quiere rastrear
el correcto envío del mensaje, se puede, simplemente, añadir un código de seguimiento al evento messageSent.
Yii introduce una clase base [[yii\base\Component]] para soportar eventos. Si una clase necesita lanzar un evento,
este debe extender a [[yii\base\Component]] o a una clase hija.
Gestor de Eventos
Un gestor de eventos es una
llamada de retorno PHP (PHP callback) que se ejecuta cuando se
lanza el evento al que corresponde. Se puede usar cualquier llamada de retorno de las enumeradas a continuación:
- una función de PHP global especificada como una cadena de texto (sin paréntesis), ej.
'trim'; - un método de objeto especificado como un array de un objeto y un nombre de método como una cadena de texto
(sin paréntesis), ej.[$object, 'methodNAme']; - un método de clase estático especificado como un array de un nombre de clase y un método como una cadena de texto
(sin paréntesis), ej.[$class, 'methodName']; - una función anónima, ej.
function ($event) { ... }.
La firma de un gestor de eventos es:
function ($event) {
// $event es un objeto de yii\base\Event o de una clase hija
}Un gestor de eventos puede obtener la siguiente información acerca de un evento ya sucedido mediante el parámetro$event:
- [[yii\base\Event::name|nombre del evento]]
- [[yii\base\Event::sender|evento enviando]]: el objeto desde el que se ha ejecutado
trigger() - [[yii\base\Event::data|custom data]]: los datos que se proporcionan al adjuntar el gestor de eventos
(se explicará más adelante)
Añadir Gestores de Eventos
Se puede añadir un gestor a un evento llamando al método [[yii\base\Component::on()]]. Por ejemplo:
$foo = new Foo;
// este gestor es una función global
$foo->on(Foo::EVENT_HELLO, 'function_name');
// este gestor es un método de objeto
$foo->on(Foo::EVENT_HELLO, [$object, 'methodName']);
// este gestor es un método de clase estática
$foo->on(Foo::EVENT_HELLO, ['app\components\Bar', 'methodName']);
// este gestor es una función anónima
$foo->on(Foo::EVENT_HELLO, function ($event) {
// event handling logic
});También se pueden adjuntar gestores de eventos mediante configuraciones. Se pueden
encontrar más de talles en la sección Configuraciones.
Cuando se adjunta un gestor de eventos, se pueden proporcionar datos adicionales como tercer parámetro de
[[yii\base\Component::on()]]. El gestor podrá acceder a los datos cuando se lance el evento y se ejecute el gestor.
Por ejemplo:
// El siguiente código muestra "abc" cuando se lanza el evento
// ya que $event->data contiene los datos enviados en el tercer parámetro de "on"
$foo->on(Foo::EVENT_HELLO, 'function_name', 'abc');
function function_name($event) {
echo $event->data;
}Ordenación de Gestores de Eventos
Se puede adjuntar uno o más gestores a un único evento. Cuando se lanza un evento, se ejecutarán los gestores adjuntos
en el orden que se hayan añadido al evento. Si un gestor necesita parar la invocación de los gestores que le siguen,
se puede establecer la propiedad [[yii\base\Event::handled]] del parámetro $event para que sea true:
$foo->on(Foo::EVENT_HELLO, function ($event) {
$event->handled = true;
});De forma predeterminada, cada nuevo gestor añadido se pone a la cola de la lista de gestores del evento. Por lo tanto,
el gestor se ejecutará en el último lugar cuando se lance el evento. Para insertar un nuevo gestor al principio de la
cola de gestores para que sea ejecutado primero, se debe llamar a [[yii\base\Component::on()]], pasando al cuarto
parámetro $append el valor false:
$foo->on(Foo::EVENT_HELLO, function ($event) {
// ...
}, $data, false);Lanzamiento de Eventos
Los eventos se lanzan llamando al método [[yii\base\Component::trigger()]]. El método requiere un nombre de evento,
y de forma opcional un objeto de evento que describa los parámetros que se enviarán a los gestores de eventos. Por
ejemplo:
namespace app\components;
use yii\base\Component;
use yii\base\Event;
class Foo extends Component
{
const EVENT_HELLO = 'hello';
public function bar()
{
$this->trigger(self::EVENT_HELLO);
}
}Con el código anterior, cada llamada a bar() lanzará un evento llamado hello
Tip: Se recomienda usar las constantes de clase para representar nombres de eventos. En el anterior ejemplo, la
constanteEVENT_HELLOrepresenta el eventohello. Este enfoque proporciona tres beneficios. Primero, previene
errores tipográficos. Segundo, puede hacer que los IDEs reconozcan los eventos en las funciones de auto-completado.
Tercero, se puede ver que eventos soporta una clase simplemente revisando la declaración de constantes.
A veces cuando se lanza un evento se puede querer pasar información adicional al gestor de eventos. Por ejemplo, un
mailer puede querer enviar la información del mensaje para que los gestores del evento messageSent para que los
gestores puedan saber las particularidades del mensaje enviado. Para hacerlo, se puede proporcionar un objeto de tipo
evento como segundo parámetro al método [[yii\base\Component::trigger()]]. El objeto de tipo evento debe ser una
instancia de la clase [[yii\base\Event]] o de su clase hija. Por ejemplo:
namespace app\components;
use yii\base\Component;
use yii\base\Event;
class MessageEvent extends Event
{
public $message;
}
class Mailer extends Component
{
const EVENT_MESSAGE_SENT = 'messageSent';
public function send($message)
{
// ...enviando $message...
$event = new MessageEvent;
$event->message = $message;
$this->trigger(self::EVENT_MESSAGE_SENT, $event);
}
}Cuando se lanza el método [[yii\base\Component::trigger()]], se ejecutarán todos los gestores adjuntos al evento.
Desadjuntar Gestores de Evento
Para desadjuntar un gestor de un evento, se puede ejecutar el método [[yii\base\Component::off()]]. Por ejemplo:
// el gestor es una función global
$foo->off(Foo::EVENT_HELLO, 'function_name');
// el gestor es un método de objeto
$foo->off(Foo::EVENT_HELLO, [$object, 'methodName']);
// el gestor es un método estático de clase
$foo->off(Foo::EVENT_HELLO, ['app\components\Bar', 'methodName']);
// el gestor es una función anónima
$foo->off(Foo::EVENT_HELLO, $anonymousFunction);Tenga en cuenta que en general no se debe intentar desadjuntar las funciones anónimas a no ser que se almacene donde
se ha adjuntado al evento. En el anterior ejemplo, se asume que la función anónima se almacena como variable$anonymousFunction.
Para desadjuntar TODOS los gestores de un evento, se puede llamar [[yii\base\Component::off()]] sin el segundo
parámetro:
$foo->off(Foo::EVENT_HELLO);Nivel de Clase (Class-Level) Gestores de Eventos
En las subsecciones anteriores se ha descrito como adjuntar un gestor a un evento a nivel de instancia. A veces, se
puede querer que un gestor responda todos los eventos de todos las instancias de una clase en lugar de una instancia
especifica. En lugar de adjuntar un gestor de eventos a una instancia, se puede adjuntar un gestor a nivel de clase
llamando al método estático [[yii\base\Event::on()]].
Por ejemplo, un objeto de tipo Active Record lanzará un evento
[[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT|EVENT_AFTER_INSERT]] cada vez que inserte un nuevo registro en la base
de datos. Para poder registrar las inserciones efectuadas por todos los objetos
Active Record, se puede usar el siguiente código:
use Yii;
use yii\base\Event;
use yii\db\ActiveRecord;
Event::on(ActiveRecord::class, ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
Yii::debug(get_class($event->sender) . ' is inserted');
});Se invocará al gestor de eventos cada vez que una instancia de [[yii\db\ActiveRecord|ActiveRecord]], o de uno de sus
clases hijas, lance un evento de tipo [[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT|EVENT_AFTER_INSERT]]. Se puede
obtener el objeto que ha lanzado el evento mediante $event->sender en el gestor.
Cuando un objeto lanza un evento, primero llamará los gestores a nivel de instancia, y a continuación los gestores a
nivel de clase.
Se puede lanzar un evento de tipo nivel de clase llamando al método estático [[yii\base\Event::trigger()]]. Un
evento de nivel de clase no se asocia a un objeto en particular. Como resultado, esto provocará solamente la
invocación de los gestores de eventos a nivel de clase.
use yii\base\Event;
Event::on(Foo::class, Foo::EVENT_HELLO, function ($event) {
var_dump($event->sender); // displays "null"
});
Event::trigger(Foo::class, Foo::EVENT_HELLO);Tenga en cuenta que en este caso, el $event->sender hace referencia al nombre de la clase que lanza el evento en
lugar de a la instancia del objeto.
Note: Debido a que los gestores a nivel de clase responderán a los eventos lanzados por cualquier instancia de la
clase, o cualquier clase hija, se debe usar con cuidado, especialmente en las clases de bajo nivel (low-level), tales
como [[yii\base\BaseObject]].
Para desadjuntar un gestor de eventos a nivel de clase, se tiene que llamar a [[yii\base\Event::off()]]. Por ejemplo:
// desadjunta $handler
Event::off(Foo::class, Foo::EVENT_HELLO, $handler);
// desadjunta todos los gestores de Foo::EVENT_HELLO
Event::off(Foo::class, Foo::EVENT_HELLO);Eventos Globales
Yii soporta los llamados eventos globales, que en realidad es un truco basado en el gestor de eventos descrito
anteriormente. El evento global requiere un Singleton globalmente accesible, tal como la instancia de
aplicación en si misma.
Para crear un evento global, un evento remitente (event sender) llama al método trigger() del Singleton para lanzar
el evento, en lugar de llamar al propio método trigger() del remitente. De forma similar, los gestores de eventos se
adjuntan al evento del Singleton. Por ejemplo:
use Yii;
use yii\base\Event;
use app\components\Foo;
Yii::$app->on('bar', function ($event) {
echo get_class($event->sender); // muestra "app\components\Foo"
});
Yii::$app->trigger('bar', new Event(['sender' => new Foo]));Un beneficio de usar eventos globales es que no se necesita un objeto cuando se adjuntan gestores a un evento para que
sean lanzados por el objeto. En su lugar, los gestores adjuntos y el lanzamiento de eventos se efectúan en el
Singleton (ej. la instancia de la aplicación).
Sin embargo, debido a que los namespaces de los eventos globales son compartidos por todas partes, se les deben
asignar nombres bien pensados, como puede ser la introducción de algún namespace
(ej. "frontend.mail.sent", "backend.mail.sent").
Guide Es Concept Properties (`docs/guide-es/concept-properties.md`)
Propiedades
En PHP, las variables miembro de clases también llamadas propiedades, son parte de la definición de la clase, y se
usan para representar el estado de una instancia de la clase (ej. para diferenciar una instancia de clase de otra).
A la práctica, a menudo, se puede querer gestionar la lectura o escritura de las propiedades de algunos momentos. Por
ejemplo, se puede querer eliminar los espacios en blanco (trim) de una cadena de texto cada vez que esta se asigne a
una propiedad de tipo label. Se podría usar el siguiente código para realizar esta tarea:
$object->label = trim($label);La desventaja del código anterior es que se tendría que ejecutar trim() en todas las partes del código que pudieran
establecer la propiedad label. Si en el futuro, la propiedad label tiene que seguir otro funcionamiento, como por
ejemplo que la primera letra tiene que estar en mayúsculas, se tendrán que modificar todas las secciones de código que
asignen el valor a la propiedad label. La repetición de código conlleva a bugs, y es una practica que se tiene que
evitar en la medida de lo posible.
Para solventar este problema, Yii introduce la clase base llamada [[yii\base\BaseObject]] que da soporte a la definición
de propiedades basada en los métodos de clase getter y setter. Si una clase necesita más funcionalidad, debe
extender a la clase [[yii\base\BaseObject]] o a alguna de sus hijas.
Info: Casi todas las clases del núcleo (core) en el framework Yii extienden a [[yii\base\BaseObject]] o a una de
sus clases hijas. Esto significa que siempre que se encuentre un getter o un setter en una clase del núcleo, se
puede utilizar como una propiedad.
Un método getter es un método cuyo nombre empieza por la palabra get: un metodo setter empieza por set. El nombre
añadido detrás del prefijo get o set define el nombre de la propiedad. Por ejemplo, un getter getLabel() y/o un
setter setLabel() definen la propiedad label, como se muestra a continuación:
namespace app\components;
use yii\base\BaseObject;
class Foo extends BaseObject
{
private $_label;
public function getLabel()
{
return $this->_label;
}
public function setLabel($value)
{
$this->_label = trim($value);
}
}(Para ser claros, los métodos getter y setter crean la propiedad label, que en este caso hace una referencia interna
al nombre de atributo privado _label.)
Las propiedades definidas por los getter y los setters se pueden usar como variables de clase miembro. La principal
diferencia radica en que cuando esta propiedad se lea, se ejecutará su correspondiente método getter; cuando se asigne
un valor a la propiedad, se ejecutará el correspondiente método setter. Por ejemplo:
// equivalente a $label = $object->getLabel();
$label = $object->label;
// equivalente a $object->setLabel('abc');
$object->label = 'abc';Una propiedad definida por un getter sin un setter es de tipo sólo lectura. Si se intenta asignar un valor a esta
propiedad se producirá una excepción de tipo [[yii\base\InvalidCallException|InvalidCallException]]. Del mismo modo
que una propiedad definida con un setter pero sin getter será de tipo sólo escritura, cualquier intento de lectura
de esta propiedad producirá una excepción. No es común tener variables de tipo sólo escritura.
Hay varias reglas especiales y limitaciones en las propiedades definidas mediante getters y setters:
- Los nombres de estas propiedades son case-insensitive. Por ejemplo,
$object->labely$object->Labelson la
misma. Esto se debe a que los nombres de los métodos en PHP son case-insensitive. - Si el nombre de una propiedad de este tipo es igual al de una variable miembro de la clase, la segunda tendrá
prioridad. Por ejemplo, si la anterior claseFootiene la variable miembrolabel, entonces la asignación$object->label = 'abc'afectará a la variable miembro 'label'; no se ejecutará el método settersetLabel(). - Estas variables no soportan la visibilidad. No hay diferencia en definir los métodos getter o setter en una
propiedad public, protected, o private. - Las propiedades sólo se pueden definir por getters y setters no estáticos. Los métodos estáticos no se tratarán de
la misma manera.
Volviendo de nuevo al problema descrito al principio de la guía, en lugar de ejecutar trim() cada vez que se asigne
un valor a label, ahora trim() sólo necesita ser invocado dentro del setter setLabel(). I si se tiene que añadir
un nuevo requerimiento, para que label empiece con una letra mayúscula, se puede modificar rápidamente el método setLabel() sin tener que modificar más secciones de código. El cambio afectará a cada asignación de label.
Guide Es Concept Service Locator (`docs/guide-es/concept-service-locator.md`)
Localizador de Servicios
Un localizador de servicios es un objeto que sabe cómo proporcionar todo tipo de servicios (o componentes) que puede necesitar una aplicación. Dentro de un localizador de servicios, existe en cada componente como una única instancia, únicamente identificado por un ID. Se utiliza el ID para recuperar un componente desde el localizador de servicios.
En Yii, un localizador de servicio es simplemente una instancia de [[yii\di\ServiceLocator]], o de una clase hija.
El localizador de servicio más utilizado en Yii es el objeto aplicación, que se puede acceder a través de \Yii::$app. Los servicios que prestá son llamadas componentes de la aplicación, como los componentes request, response, and urlManager. Usted puede configurar estos componentes, o incluso cambiarlos por sus propias implementaciones fácilmente a través de la funcionalidad proporcionada por el localizador de servicios.
Además del objeto de aplicación, cada objeto módulo es también un localizador de servicios.
Para utilizar un localizador de servicios, el primer paso es registrar los componentes de la misma. Un componente se puede registrar a través de [[yii\di\ServiceLocator::set()]]. El código siguiente muestra diferentes maneras de registrarse componentes:
use yii\di\ServiceLocator;
use yii\caching\FileCache;
$locator = new ServiceLocator;
// register "cache" using a class name that can be used to create a component
$locator->set('cache', 'yii\caching\ApcCache');
// register "db" using a configuration array that can be used to create a component
$locator->set('db', [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=demo',
'username' => 'root',
'password' => '',
]);
// register "search" using an anonymous function that builds a component
$locator->set('search', function () {
return new app\components\SolrService;
});
// register "pageCache" using a component
$locator->set('pageCache', new FileCache);Una vez que el componente se ha registrado, usted puede acceder a él utilizando su ID, en una de las dos formas siguientes:
$cache = $locator->get('cache');
// or alternatively
$cache = $locator->cache;Como puede observarse, [[yii\di\ServiceLocator]] le permite acceder a un componente como una propiedad utilizando el ID de componente. Cuando acceda a un componente, por primera vez, [[yii\di\ServiceLocator]] utilizará la información de registro de componente para crear una nueva instancia del componente y devolverlo. Más tarde, si se accede de nuevo al componente, el localizador de servicio devolverá la misma instancia.
Usted puede utilizar [[yii\di\ServiceLocator::has()]] para comprobar si un ID de componente ya ha sido registrada.
Si llama [[yii\di\ServiceLocator::get()]] con una identificación válida, se produce una excepción.
Debido a que los localizadores de servicios a menudo se crean con configuraciones, se proporciona una propiedad que puede escribir el nombre [[yii\di\ServiceLocator::setComponents()|components]]. Esto le permite configurar y registrar varios componentes a la vez. El siguiente código muestra un arreglo de configuración que se puede utilizar para configurar una aplicación, al mismo tiempo que el registro de la "db", "cache" y "buscar" componentes:
return [
// ...
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=demo',
'username' => 'root',
'password' => '',
],
'cache' => 'yii\caching\ApcCache',
'search' => function () {
return new app\components\SolrService;
},
],
];Guide Es Db Dao (`docs/guide-es/db-dao.md`)
Objetos de Acceso a Bases de Datos
Construido sobre PDO, Yii DAO (Objetos de Acceso a Bases de Datos) proporciona una
API orientada a objetos para el acceso a bases de datos relacionales. Es el fundamento para otros métodos de acceso a bases de datos
más avanzados, incluyendo el constructor de consultas y active record.
Al utilizar Yii DAO, principalmente vas a tratar con SQLs planos y arrays PHP. Como resultado, esta es la manera más eficiente
de acceder a las bases de datos. Sin embargo, como la sintaxis puede variar para las diferentes bases de datos, utilizando
Yii DAO también significa que tienes que tienes que tomar un esfuerzo adicional para crear una aplicación de database-agnostic.
Yii DAO soporta las siguientes bases de datos:
- MySQL
- MariaDB
- SQLite
- PostgreSQL: versión 8.4 o superior.
- CUBRID: versión 9.3 o superior.
- Oracle
- MSSQL: versión 2008 o superior.
Creando Conexiones DB
Para acceder a una base de datos, primero necesitas conectarte a tu bases de datos mediante la creación
de una instancia de [[yii\db\Connection]]:
$db = new yii\db\Connection([
'dsn' => 'mysql:host=localhost;dbname=example',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);Debido a una conexión DB a menudo necesita ser accedido en diferentes lugares, una práctica común es
configurarlo en términos de un componente de aplicación como
se muestra a continuación:
return [
// ...
'components' => [
// ...
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=example',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
],
// ...
];Puedes acceder a la conexión DB mediante la expresión Yii::$app->db.
Tip: Puedes configurar múltiples componentes de aplicación DB si tu aplicación necesita acceder a múltiples bases de datos.
Cuando configuras una conexión DB, deberías siempre especificar el Nombre de Origen de Datos (DSN) mediante la
propiedad [[yii\db\Connection::dsn|dsn]]. El formato del DSN varia para cada diferente base de datos. Por favor consulte el
manual de PHP para más detalles. Abajo están algunos ejemplos:
- MySQL, MariaDB:
mysql:host=localhost;dbname=mydatabase - SQLite:
sqlite:/path/to/database/file - PostgreSQL:
pgsql:host=localhost;port=5432;dbname=mydatabase - CUBRID:
cubrid:dbname=demodb;host=localhost;port=33000 - MS SQL Server (mediante sqlsrv driver):
sqlsrv:Server=localhost;Database=mydatabase - MS SQL Server (mediante dblib driver):
dblib:host=localhost;dbname=mydatabase - MS SQL Server (mediante mssql driver):
mssql:host=localhost;dbname=mydatabase - Oracle:
oci:dbname=//localhost:1521/mydatabase
Nota que si estás conectándote con una base de datos mediante ODBC, deberías configurar la propiedad [[yii\db\Connection::driverName]]
para que Yii pueda conocer el tipo de base de datos actual. Por ejemplo,
'db' => [
'class' => 'yii\db\Connection',
'driverName' => 'mysql',
'dsn' => 'odbc:Driver={MySQL};Server=localhost;Database=test',
'username' => 'root',
'password' => '',
],Además de la propiedad [[yii\db\Connection::dsn|dsn]], a menudo es necesario configurar el [[yii\db\Connection::username|username]]
y [[yii\db\Connection::password|password]]. Por favor consulta [[yii\db\Connection]] para ver la lista completa de propiedades configurables.
Info: Cuando se crea una instancia de conexión DB, la conexión actual a la base de datos no se establece hasta que
ejecutes el primer SQL o llames explícitamente al método [[yii\db\Connection::open()|open()]].
Ejecutando Consultas SQL
Una vez tienes instanciada una conexión a la base de datos, se pueden ejecutar consultas SQL tomando
los siguientes pasos:
- Crea un [[yii\db\Command]] con SQL plano;
- Vincula parámetros (opcional);
- Llama a uno de los métodos de ejecución SQL con [[yii\db\Command]].
El siguiente ejemplo muestra varias maneras de obtener datos de una base de datos:
$db = new yii\db\Connection(...);
// retorna un conjunto de filas. Cada fila es un array asociativo de columnas de nombres y valores.
// un array vacío es retornado si no hay resultados
$posts = $db->createCommand('SELECT * FROM post')
->queryAll();
// retorna una sola fila (la primera fila)
// `false` es retornado si no hay resultados
$post = $db->createCommand('SELECT * FROM post WHERE id=1')
->queryOne();
// retorna una sola columna (la primera columna)
// un array vacío es retornado si no hay resultados
$titles = $db->createCommand('SELECT title FROM post')
->queryColumn();
// retorna un escalar
// `false` es retornado si no hay resultados
$count = $db->createCommand('SELECT COUNT(*) FROM post')
->queryScalar();Note: Para preservar la precisión, los datos obtenidos de las bases de datos son todos representados como cadenas, incluso si el tipo de columna correspondiente
a la base de datos es numérico.
Tip: Si necesitas ejecutar una consulta SQL inmediatamente después de establecer una conexión (ej., para establecer una zona horaria o un conjunto de caracteres),
puedes hacerlo con el evento [[yii\db\Connection::EVENT_AFTER_OPEN]]. Por ejemplo,
return [
// ...
'components' => [
// ...
'db' => [
'class' => 'yii\db\Connection',
// ...
'on afterOpen' => function($event) {
// $event->sender se refiere a la conexión DB
$event->sender->createCommand("SET time_zone = 'UTC'")->execute();
}
],
],
// ...
];Parámetros Vinculados (Binding Parameters)
Cuando creamos un comando DB para un SQL con parámetros, nosotros deberíamos casi siempre aprovechar el uso de los parámetros vinculados
para prevenir los ataques de inyección de SQL. Por ejemplo,
$post = $db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status')
->bindValue(':id', $_GET['id'])
->bindValue(':status', 1)
->queryOne();En la sentencia SQL, puedes incrustar uno o múltiples parámetros placeholders (ej. :id en el ejemplo anterior). Un parámetro
placeholder debería ser una cadena que empiece con dos puntos. A continuación puedes llamar a uno de los siguientes métodos para
unir los valores de los parámetros vinculados:
- [[yii\db\Command::bindValue()|bindValue()]]: une un solo parámetro
- [[yii\db\Command::bindValues()|bindValues()]]: une múltiples parámetros en una sola llamada
- [[yii\db\Command::bindParam()|bindParam()]]: similar a [[yii\db\Command::bindValue()|bindValue()]] pero también
soporta las referencias de parámetros vinculados.
El siguiente ejemplo muestra formas alternativas de vincular parámetros:
$params = [':id' => $_GET['id'], ':status' => 1];
$post = $db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status')
->bindValues($params)
->queryOne();
$post = $db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status', $params)
->queryOne();La vinculación parámetros es implementada mediante sentencias preparadas (prepared statements).
Además de prevenir ataques de inyección de SQL, también puede mejorar el rendimiento preparando una sola vez una sentencia SQL y ejecutándola múltiples veces con diferentes
parámetros. Por ejemplo,
$command = $db->createCommand('SELECT * FROM post WHERE id=:id');
$post1 = $command->bindValue(':id', 1)->queryOne();
$post2 = $command->bindValue(':id', 2)->queryOne();Porque [[yii\db\Command::bindParam()|bindParam()]] soporta parámetros vinculados por referencias, el código de arriba también
puede ser escrito como lo siguiente:
$command = $db->createCommand('SELECT * FROM post WHERE id=:id')
->bindParam(':id', $id);
$id = 1;
$post1 = $command->queryOne();
$id = 2;
$post2 = $command->queryOne();Observe que vincula el placeholder a la variable $id antes de la ejecución, y entonces cambia el valor de esa variable
antes de cada subsiguiente ejecución (esto se hace a menudo con bucles). Ejecutando consultas de esta manera puede ser
bastante más eficiente que ejecutar una nueva consulta para cada valor diferente del parámetro.
Ejecutando Consultas Non-SELECT
El método queryXyz() introducidos en las secciones previas todos tratan con consultas SELECT los cuales recogen los
datos de la base de datos. Para las consultas que no devuelven datos, deberías llamar a el método [[yii\db\Command::execute()]]
en su lugar. Por ejemplo,
$db->createCommand('UPDATE post SET status=1 WHERE id=1')
->execute();El método [[yii\db\Command::execute()]] retorna el número de filas afectadas por la ejecución SQL.
Para consultas INSERT, UPDATE y DELETE, en vez de escribir SQLs planos, puedes llamar a [[yii\db\Command::insert()|insert()]],
[[yii\db\Command::update()|update()]], [[yii\db\Command::delete()|delete()]], respectivamente, construyen los correspondientes
SQLs. Estos métodos entrecomillan adecuadamente las tablas y los nombres de columnas y los valores de los parámetros vinculados.
Por ejemplo,
// INSERT (table name, column values)
$db->createCommand()->insert('user', [
'name' => 'Sam',
'age' => 30,
])->execute();
// UPDATE (table name, column values, condition)
$db->createCommand()->update('user', ['status' => 1], 'age > 30')->execute();
// DELETE (table name, condition)
$db->createCommand()->delete('user', 'status = 0')->execute();Puedes también llamar a [[yii\db\Command::batchInsert()|batchInsert()]] para insertar múltiples filas de una sola vez,
que es mucho más eficiente que insertar una fila de cada vez:
// table name, column names, column values
$db->createCommand()->batchInsert('user', ['name', 'age'], [
['Tom', 30],
['Jane', 20],
['Linda', 25],
])->execute();Entrecomillado de Tablas y Nombres de Columna
Al escribir código de database-agnostic, entrecomillar correctamente los nombres de las tablas y las columnas es a menudo
un dolor de cabeza porque las diferentes bases de datos tienen diferentes reglas para entrecomillar los nombres. Para
solventar este problema, puedes usar la siguiente sintaxis de entrecomillado introducido por Yii:
[[column name]]: encierra con dobles corchetes el nombre de una columna que debe ser entrecomillado;{{table name}}: encierra con dobles llaves el nombre de una tabla que debe ser entrecomillado.
Yii DAO automáticamente convertirá tales construcciones en un SQL con los correspondientes entrecomillados de los nombres de las columnas o tablas.
Por ejemplo,
// ejecuta esta SQL para MySQL: SELECT COUNT(`id`) FROM `employee`
$count = $db->createCommand("SELECT COUNT([[id]]) FROM {{employee}}")
->queryScalar();Usando Prefijos de Tabla
Si la mayoría de tus tablas de BD utilizan algún prefijo común en sus tablas, puedes usar la función de prefijo de tabla soportado
por Yii DAO.
Primero, especifica el prefijo de tabla mediante la propiedad [[yii\db\Connection::tablePrefix]]:
return [
// ...
'components' => [
// ...
'db' => [
// ...
'tablePrefix' => 'tbl_',
],
],
];Luego en tu código, siempre que lo necesites para hacer referencia a una tabla cuyo nombre tiene un prefijo, utiliza la sintaxis{{%table name}}. El carácter porcentaje se sustituye con el prefijo de la tabla que has especificado en la configuración de
la conexión DB. Por ejemplo,
// ejecuta esta SQL para MySQL: SELECT COUNT(`id`) FROM `tbl_employee`
$count = $db->createCommand("SELECT COUNT([[id]]) FROM {{%employee}}")
->queryScalar();Realización de Transacciones
Cuando se ejecutan múltiples consultas relacionadas en una secuencia, puede que se tengan que envolver en una
transacción para asegurar la integridad de los datos y la consistencia de tu base de datos. Si cualquiera de las consultas
falla, la base de datos debe ser revertida al estado anterior como si ninguna de estas consultas se haya ejecutado.
El siguiente código muestra una manera típica de usar transacciones:
$db->transaction(function($db) {
$db->createCommand($sql1)->execute();
$db->createCommand($sql2)->execute();
// ... ejecutando otras sentencias SQL
});El código de arriba es equivalente a lo siguiente:
$transaction = $db->beginTransaction();
try {
$db->createCommand($sql1)->execute();
$db->createCommand($sql2)->execute();
// ... ejecutando otras sentencias SQL
$transaction->commit();
} catch(\Exception $e) {
$transaction->rollBack();
throw $e;
}Al llamar al método [[yii\db\Connection::beginTransaction()|beginTransaction()]], se inicia una nueva transacción.
La transacción se representa como un objeto [[yii\db\Transaction]] almacenado en la variable $transaction. Luego,
las consultas que se ejecutan están encerrados en un bloque try...catch.... Si todas las consultas son ejecutadas satisfactoriamente,
el método [[yii\db\Transaction::commit()|commit()]] es llamado para confirmar la transacción. De lo contrario, una excepción
se disparará y se capturará, y el método [[yii\db\Transaction::rollBack()|rollBack()]] es llamado para revertir
los cambios hechos por las consultas antes de que fallara la consulta en la transacción.
Especificando los Niveles de Aislamiento
Yii también soporta la configuración de [niveles de aislamiento] para tus transacciones. Por defecto, cuando comienza una nueva transacción,
utilizará el nivel de aislamiento definido por tu sistema de base de datos. Se puede sobrescribir el nivel de aislamiento por defecto de la
siguiente manera,
$isolationLevel = \yii\db\Transaction::REPEATABLE_READ;
$db->transaction(function ($db) {
....
}, $isolationLevel);
// or alternatively
$transaction = $db->beginTransaction($isolationLevel);Yii proporciona cuatro constantes para los niveles de aislamiento más comunes:
- [[\yii\db\Transaction::READ_UNCOMMITTED]] - el nivel más bajo, pueden ocurrir lecturas Dirty, lecturas
Non-repeatable y Phantoms. - [[\yii\db\Transaction::READ_COMMITTED]] - evita lecturas Dirty.
- [[\yii\db\Transaction::REPEATABLE_READ]] - evita lecturas Dirty y lecturas Non-repeatable.
- [[\yii\db\Transaction::SERIALIZABLE]] - el nivel más fuerte, evita todos los problemas nombrados anteriormente.
Además de usar las constantes de arriba para especificar los niveles de aislamiento, puedes también usar cadenas con
una sintaxis valida soportada por el DBMS que estés usando. Por ejemplo, en PostgreSQL, puedes utilizar SERIALIZABLE READ ONLY DEFERRABLE.
Tenga en cuenta que algunos DBMS permiten configuraciones de niveles de aislamiento solo a nivel de conexión. Las transacciones subsiguientes
recibirá el mismo nivel de aislamiento , incluso si no se especifica ninguna. Al utilizar esta característica
es posible que necesites ajustar el nivel de aislamiento para todas las transacciones de forma explícitamente para evitar conflictos
en las configuraciones.
En el momento de escribir esto, solo MSSQL y SQLite serán afectadas.
Note: SQLite solo soporta dos niveles de aislamiento, por lo que solo se puede usar
READ UNCOMMITTEDySERIALIZABLE. El uso de otros niveles causará el lanzamiento de una excepción.
Note: PostgreSQL no permite configurar el nivel de aislamiento antes que la transacción empiece por lo que no se
puede especificar el nivel de aislamiento directamente cuando empieza la transacción. Se tiene que llamar a
[[yii\db\Transaction::setIsolationLevel()]] después de que la transacción haya empezado.
Transacciones Anidadas
Si tu DBMS soporta Savepoint, puedes anidar múltiples transacciones como a continuación:
$db->transaction(function ($db) {
// outer transaction
$db->transaction(function ($db) {
// inner transaction
});
});O alternativamente,
$outerTransaction = $db->beginTransaction();
try {
$db->createCommand($sql1)->execute();
$innerTransaction = $db->beginTransaction();
try {
$db->createCommand($sql2)->execute();
$innerTransaction->commit();
} catch (Exception $e) {
$innerTransaction->rollBack();
}
$outerTransaction->commit();
} catch (Exception $e) {
$outerTransaction->rollBack();
}Replicación y División Lectura-Escritura
Muchos DBMS soportan replicación de bases de datos para tener
una mejor disponibilidad de la base de datos y un mejor tiempo de respuesta del servidor. Con la replicación de bases
de datos, los datos están replicados en los llamados servidores maestros (master servers) y servidores esclavos
(slave servers). Todas las escrituras y actualizaciones deben hacerse en el servidor maestro, mientras que las lecturas
se efectuarán en los servidores esclavos.
Para aprovechar las ventajas de la replicación de la base de datos y lograr una división de lecuta-escritura, se puede configurar
el componente [[yii\db\Connection]] como se muestra a continuación:
[
'class' => 'yii\db\Connection',
// configuración para el maestro
'dsn' => 'dsn for master server',
'username' => 'master',
'password' => '',
// configuración para los esclavos
'slaveConfig' => [
'username' => 'slave',
'password' => '',
'attributes' => [
// utiliza un tiempo de espera de conexión más pequeña
PDO::ATTR_TIMEOUT => 10,
],
],
// listado de configuraciones de esclavos
'slaves' => [
['dsn' => 'dsn for slave server 1'],
['dsn' => 'dsn for slave server 2'],
['dsn' => 'dsn for slave server 3'],
['dsn' => 'dsn for slave server 4'],
],
]La configuración anterior especifica una configuración con un único maestro y múltiples esclavos. Uno de los esclavos
se conectará y se usará para ejecutar consultas de lectura, mientras que el maestro se usará para realizar consultas de
escritura. De este modo la división de lectura-escritura se logra automáticamente con esta configuración, Por ejemplo,
// crea una instancia de Connection usando la configuración anterior
$db = Yii::createObject($config);
// consulta contra uno de los esclavos
$rows = $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();
// consulta contra el maestro
$db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute();Info: Las consultas realizadas llamando a [[yii\db\Command::execute()]] se consideran consultas de escritura,
mientras que todas las demás se ejecutan mediante alguno de los métodos "query" de [[yii\db\Command]] son consultas
de lectura. Se puede obtener la conexión de esclavo activa mediante$db->slave.
El componente Connection soporta el balanceo de carga y la conmutación de errores entre esclavos. Cuando se realiza
una consulta de lectura por primera vez, el componente Connection elegirá un esclavo aleatorio e intentará realizar
una conexión a este. Si el esclavo se encuentra "muerto", se intentará con otro. Si no está disponible ningún esclavo, se conectará al maestro. Configurando una [[yii\db\Connection::serverStatusCache|server status cache]], se recordarán los servidores
"muertos" por lo que no se intentará volver a conectar a ellos durante
[[yii\db\Connection::serverRetryInterval|certain period of time]].
Info: En la configuración anterior, se especifica un tiempo de espera (timeout) de conexión de 10 segundos
para cada esclavo. Esto significa que si no se puede conectar a un esclavo en 10 segundos, este será considerado
como "muerto". Se puede ajustar el parámetro basado en el entorno actual.
También se pueden configurar múltiples maestros con múltiples esclavos. Por ejemplo,
[
'class' => 'yii\db\Connection',
// configuracion habitual para los maestros
'masterConfig' => [
'username' => 'master',
'password' => '',
'attributes' => [
// utilizar un tiempo de espera de conexión más pequeña
PDO::ATTR_TIMEOUT => 10,
],
],
// listado de configuraciones de maestros
'masters' => [
['dsn' => 'dsn for master server 1'],
['dsn' => 'dsn for master server 2'],
],
// configuración habitual para esclavos
'slaveConfig' => [
'username' => 'slave',
'password' => '',
'attributes' => [
// utilizar un tiempo de espera de conexión más pequeña
PDO::ATTR_TIMEOUT => 10,
],
],
// listado de configuración de esclavos
'slaves' => [
['dsn' => 'dsn for slave server 1'],
['dsn' => 'dsn for slave server 2'],
['dsn' => 'dsn for slave server 3'],
['dsn' => 'dsn for slave server 4'],
],
]La configuración anterior especifica dos maestros y cuatro esclavos. El componente Connection también da soporte al
balanceo de carga y la conmutación de errores entre maestros igual que hace con los esclavos. La diferencia es que
cuando no se encuentra ningún maestro disponible se lanza una excepción.
Note: cuando se usa la propiedad [[yii\db\Connection::masters|masters]] para configurar uno o múltiples maestros, se
ignorarán todas las otras propiedades que especifiquen una conexión de base de datos
(ej.dsn,username,password), junto con el mismo objetoConnection.
Por defecto. las transacciones usan la conexión del maestro. Y dentro de una transacción, todas las operaciones de DB usarán
la conexión del maestro. Por ejemplo,
// la transacción empieza con la conexión al maestro
$transaction = $db->beginTransaction();
try {
// las dos consultas se ejecutan contra el maestro
$rows = $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();
$db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute();
$transaction->commit();
} catch(\Exception $e) {
$transaction->rollBack();
throw $e;
}Si se quiere empezar la transacción con una conexión a un esclavo, se debe hacer explícitamente como se muestra a
continuación:
$transaction = $db->slave->beginTransaction();A veces, se puede querer forzar el uso de una conexión maestra para realizar una consulta de lectura. Se puede lograr
usando el método useMaster():
$rows = $db->useMaster(function ($db) {
return $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();
});También se puede utilizar directamente estableciendo $db->enableSlaves a false para que se redirijan todas las
consultas a la conexión del maestro.
Trabajando con Esquemas de Bases de Datos
Yii DAO proporciona todo un conjunto de métodos que permites manipular el esquema de tu base de datos, tal como
crear nuevas tablas, borrar una columna de una tabla, etc. Estos métodos son listados a continuación:
- [[yii\db\Command::createTable()|createTable()]]: crea una tabla
- [[yii\db\Command::renameTable()|renameTable()]]: renombra una tabla
- [[yii\db\Command::dropTable()|dropTable()]]: remueve una tabla
- [[yii\db\Command::truncateTable()|truncateTable()]]: remueve todas las filas de una tabla
- [[yii\db\Command::addColumn()|addColumn()]]: añade una columna
- [[yii\db\Command::renameColumn()|renameColumn()]]: renombra una columna
- [[yii\db\Command::dropColumn()|dropColumn()]]: remueve una columna
- [[yii\db\Command::alterColumn()|alterColumn()]]: altera una columna
- [[yii\db\Command::addPrimaryKey()|addPrimaryKey()]]: añade una clave primaria
- [[yii\db\Command::dropPrimaryKey()|dropPrimaryKey()]]: remueve una clave primaria
- [[yii\db\Command::addForeignKey()|addForeignKey()]]: añade una clave ajena
- [[yii\db\Command::dropForeignKey()|dropForeignKey()]]: remueve una clave ajena
- [[yii\db\Command::createIndex()|createIndex()]]: crea un indice
- [[yii\db\Command::dropIndex()|dropIndex()]]: remueve un indice
Estos métodos puedes ser usados como se muestra a continuación:
// CREATE TABLE
$db->createCommand()->createTable('post', [
'id' => 'pk',
'title' => 'string',
'text' => 'text',
]);También puedes recuperar la información de definición de una tabla a través
del método [[yii\db\Connection::getTableSchema()|getTableSchema()]] de una conexión DB. Por ejemplo,
$table = $db->getTableSchema('post');El método retorna un objeto [[yii\db\TableSchema]] que contiene la información sobre las columnas de las tablas,
claves primarias, claves ajenas, etc. Toda esta información principalmente es utilizada por el
constructor de consultas y active record para ayudar a
escribir código database-agnostic.
Guide Es Db Migrations (`docs/guide-es/db-migrations.md`)
Migración de Base de Datos
Durante el curso de desarrollo y mantenimiento de una aplicación con base de datos, la estructura de dicha base de datos
evoluciona tanto como el código fuente. Por ejemplo, durante el desarrollo de una aplicación,
una nueva tabla podría ser necesaria; una vez que la aplicación se encuentra en producción, podría descrubrirse
que debería crearse un índice para mejorar el tiempo de ejecución de una consulta; y así sucesivamente. Debido a los cambios en la estructura de la base de datos
a menudo se requieren cambios en el código, Yii soporta la característica llamada migración de base de datos, la cual permite
tener un seguimiento de esos cambios en término de migración de base de datos, cuyo versionado es controlado
junto al del código fuente.
Los siguientes pasos muestran cómo una migración puede ser utilizada por un equipo durante el desarrollo:
- Tim crea una nueva migración (por ej. crea una nueva table, cambia la definición de una columna, etc.).
- Tim hace un commit con la nueva migración al sistema de control de versiones (por ej. Git, Mercurial).
- Doug actualiza su repositorio desde el sistema de control de versiones y recibe la nueva migración.
- Doug aplica dicha migración a su base de datos local de desarrollo, de ese modo sincronizando su base de datos
y reflejando los cambios que hizo Tim.
Los siguientes pasos muestran cómo hacer una puesta en producción con una migración de base de datos:
- Scott crea un tag de lanzamiento en el repositorio del proyecto que contiene algunas migraciones de base de datos.
- Scott actualiza el código fuente en el servidor de producción con el tag de lanzamiento.
- Scott aplica cualquier migración de base de datos acumulada a la base de datos de producción.
Yii provee un grupo de herramientas de línea de comandos que te permite:
- crear nuevas migraciones;
- aplicar migraciones;
- revertir migraciones;
- re-aplicar migraciones;
- mostrar el historial y estado de migraciones.
Todas esas herramientas son accesibles a través del comando yii migrate. En esta sección describiremos en detalle
cómo lograr varias tareas utilizando dichas herramientas. Puedes a su vez ver el uso de cada herramienta a través del comando
de ayuda yii help migrate.
Tip: las migraciones pueden no sólo afectar un esquema de base de datos sino también ajustar datos existentes para que encajen en el nuevo esquema, crear herencia RBAC
o también limpiar el cache.
Creando Migraciones
Para crear una nueva migración, ejecuta el siguiente comando:
yii migrate/create <name>El argumento requerido name da una pequeña descripción de la nueva migración. Por ejemplo, si
la migración se trata acerca de crear una nueva tabla llamada news, podrías utilizar el nombre create_news_table
y ejecutar el siguiente comando:
yii migrate/create create_news_tableNote: Debido a que el argumento
nameserá utilizado como parte del nombre de clase de la migración generada,
sólo debería contener letras, dígitos, y/o guines bajos.
El comando anterior un nuevo archivo de clase PHP llamado m150101_185401_create_news_table.php
en el directorio @app/migrations. El archivo contendrá el siguiente código, que principalmente declara
una clase de tipo migración m150101_185401_create_news_table con el siguiente esqueleto de código:
<?php
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
public function up()
{
}
public function down()
{
echo "m101129_185401_create_news_table cannot be reverted.\n";
return false;
}
/*
// Use safeUp/safeDown to run migration code within a transaction
public function safeUp()
{
}
public function safeDown()
{
}
*/
}Cada migración de base de datos es definida como una clase PHP que extiende de [[yii\db\Migration]]. La nombre de clase
de la migración es generado automáticamente en el formato m<YYMMDD_HHMMSS>_<Name>, donde
<YYMMDD_HHMMSS>se refiere a la marca de tiempo UTC en la cual el comando de migración fue ejecutado.<Name>es el mismo valor del argumentonameprovisto al ejecutar el comando.
En la clase de la migración, se espera que tu escribas código en el método up(), que realiza los cambios en la base de datos.
Podrías también querer introducir código en el método down(), que debería revertir los cambios realizados por up(). El método up() es llamado
cuando actualizas la base de datos con esta migración, mientras que el método down() es llamado cuando reviertes dicha migración.
El siguiente código muestra cómo podrías implementar la clase de migración para crear la tabla news:
<?php
use yii\db\Schema;
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
public function up()
{
$this->createTable('news', [
'id' => Schema::TYPE_PK,
'title' => Schema::TYPE_STRING . ' NOT NULL',
'content' => Schema::TYPE_TEXT,
]);
}
public function down()
{
$this->dropTable('news');
}
}Info: No todas las migraciones son reversibles. Por ejemplo, si el método
up()elimina un registro en una tabla, podrías
no ser capáz de recuperarla en el métododown(). A veces, podrías ser simplemente demasiado perezoso para implementar
el métododown(), debido a que no es muy común revertir migraciones de base de datos. En este caso, deberías devolver
falseen el métododown()para indicar que dicha migración no es reversible.
La clase de migración de base de datos [[yii\db\Migration]] expone una conexión a la base de datos mediante la propiedad [[yii\db\Migration::db|db]].
Puedes utilizar esto para manipular el esquema de la base de datos utilizando métodos como se describen en
Trabajando con Esquemas de Base de Datos.
En vez de utilizar tipos físicos, al crear tablas o columnas deberías utilizar los tipos abstractos
así las migraciones son independientes de algún DBMS específico. La clase [[yii\db\Schema]] define
un grupo de constantes que representan los tipos abstractos soportados. Dichas constantes son llamadas utilizando el formato
de TYPE_<Name>. Por ejemplo, TYPE_PK se refiere al tipo clave primaria auto-incremental; TYPE_STRING
se refiere al tipo string. Cuando se aplica una migración a una base de datos en particular, los tipos abstractos
serán traducidos a los tipos físicos correspondientes. En el caso de MySQL, TYPE_PK será transformado
en int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, mientras TYPE_STRING se vuelve varchar(255).
Puedes agregar restricciones adicionales al utilizar tipos abstractos. En el ejemplo anterior, NOT NULL es agregado
a Schema::TYPE_STRING para especificar que la columna no puede ser null.
Info: El mapeo entre tipos abstractos y tipos físicos es especificado en
la propiedad [[yii\db\QueryBuilder::$typeMap|$typeMap]] en cada clase concretaQueryBuilder.
Desde la versión 2.0.6, puedes hacer uso del recientemente introducido generador de esquemas, el cual provee una forma más conveniente de definir las columnas.
De esta manera, la migración anterior podría ser escrita así:
<?php
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
public function up()
{
$this->createTable('news', [
'id' => $this->primaryKey(),
'title' => $this->string()->notNull(),
'content' => $this->text(),
]);
}
public function down()
{
$this->dropTable('news');
}
}Existe una lista de todos los métodos disponibles para la definición de tipos de columna en la API de la documentación de [[yii\db\SchemaBuilderTrait]].
Generar Migraciones
Desde la versión 2.0.7 la consola provee una manera muy conveniente de generar migraciones.
Si el nombre de la migración tiene una forma especial, por ejemplo create_xxx_table o drop_xxx_table entonces el archivo de la migración generada
contendrá código extra, en este caso para crear/eliminar tablas.
A continuación se describen todas estas variantes.
Crear Tabla
yii migrate/create create_post_tableesto genera
/**
* Handles the creation for table `post`.
*/
class m150811_220037_create_post_table extends Migration
{
/**
* {@inheritdoc}
*/
public function up()
{
$this->createTable('post', [
'id' => $this->primaryKey()
]);
}
/**
* {@inheritdoc}
*/
public function down()
{
$this->dropTable('post');
}
}Para crear las columnas en ese momento, las puedes especificar vía la opción --fields.
yii migrate/create create_post_table --fields="title:string,body:text"genera
/**
* Handles the creation for table `post`.
*/
class m150811_220037_create_post_table extends Migration
{
/**
* {@inheritdoc}
*/
public function up()
{
$this->createTable('post', [
'id' => $this->primaryKey(),
'title' => $this->string(),
'body' => $this->text(),
]);
}
/**
* {@inheritdoc}
*/
public function down()
{
$this->dropTable('post');
}
}Puedes especificar más parámetros para las columnas.
yii migrate/create create_post_table --fields="title:string(12):notNull:unique,body:text"genera
/**
* Handles the creation for table `post`.
*/
class m150811_220037_create_post_table extends Migration
{
/**
* {@inheritdoc}
*/
public function up()
{
$this->createTable('post', [
'id' => $this->primaryKey(),
'title' => $this->string(12)->notNull()->unique(),
'body' => $this->text()
]);
}
/**
* {@inheritdoc}
*/
public function down()
{
$this->dropTable('post');
}
}Note: la clave primaria es automáticamente agragada y llamada
idpor defecto. Si quieres utilizar otro nombre puedes
especificarlo así--fields="name:primaryKey".
Claves Foráneas
Desde 2.0.8 el generador soporta claves foráneas utilizando la palabra clave foreignKey.
yii migrate/create create_post_table --fields="author_id:integer:notNull:foreignKey(user),category_id:integer:defaultValue(1):foreignKey,title:string,body:text"genera
/* Detailed source-code truncated for AI context efficiency. */La posición de la palabra clave foreignKey en la descripción de la columna
no cambia el código generado. Esto significa:
author_id:integer:notNull:foreignKey(user)author_id:integer:foreignKey(user):notNullauthor_id:foreignKey(user):integer:notNull
Todas generan el mismo código.
La palabra clave foreignKey puede tomar un parámetro entre paréntesis el cual
será el nombre de la tabla relacionada por la clave foránea generada. Si no se pasa ningún parámetro
el nombre de la tabla será deducido en base al nombre de la columna.
En el ejemplo anterior author_id:integer:notNull:foreignKey(user) generará
una columna llamada author_id con una clave foránea a la tabla user mientrascategory_id:integer:defaultValue(1):foreignKey generarácategory_id con una clave foránea a la tabla category.
Eliminar Tabla
yii migrate/create drop_post_table --fields="title:string(12):notNull:unique,body:text"genera
class m150811_220037_drop_post_table extends Migration
{
public function up()
{
$this->dropTable('post');
}
public function down()
{
$this->createTable('post', [
'id' => $this->primaryKey(),
'title' => $this->string(12)->notNull()->unique(),
'body' => $this->text()
]);
}
}Agregar Columna
Si el nombre de la migración está en la forma add_xxx_column_to_yyy_table entonces el archivo generado contendrá
las declaraciones addColumn y dropColumn necesarias.
Para agregar una columna:
yii migrate/create add_position_column_to_post_table --fields="position:integer"genera
class m150811_220037_add_position_column_to_post_table extends Migration
{
public function up()
{
$this->addColumn('post', 'position', $this->integer());
}
public function down()
{
$this->dropColumn('post', 'position');
}
}Eliminar Columna
Si el nombre de la migración está en la forma drop_xxx_column_from_yyy_table entonces el archivo generado contendrá
las declaraciones addColumn y dropColumn necesarias.
yii migrate/create drop_position_column_from_post_table --fields="position:integer"genera
class m150811_220037_drop_position_column_from_post_table extends Migration
{
public function up()
{
$this->dropColumn('post', 'position');
}
public function down()
{
$this->addColumn('post', 'position', $this->integer());
}
}Agregar Tabla de Unión
Si el nombre de la migración está en la forma create_junction_table_for_xxx_and_yyy_tables entonces se generará el código necesario
para una tabla de unión.
yii migrate/create create_junction_table_for_post_and_tag_tables --fields="created_at:dateTime"genera
/* Detailed source-code truncated for AI context efficiency. */Migraciones Transaccionales
Al ejecutar migraciones complejas de BD, es importante asegurarse que todas las migraciones funcionen o fallen como una unidad
así la base de datos puede mantener integridad y consistencia. Para alcanzar este objetivo, se recomienda que
encierres las operación de la BD de cada migración en una transacción.
Una manera simple de implementar migraciones transaccionales es poniendo el código de las migraciones en los métodos safeUp() y safeDown().
Estos métodos se diferencias con up() y down() en que son encerrados implícitamente en una transacción.
Como resultado, si alguna de las operaciones dentro de estos métodos falla, todas las operaciones previas son automáticamente revertidas.
En el siguiente ejemplo, además de crear la tabla news también insertamos un registro inicial dentro de la dicha tabla.
<?php
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
public function safeUp()
{
$this->createTable('news', [
'id' => $this->primaryKey(),
'title' => $this->string()->notNull(),
'content' => $this->text(),
]);
$this->insert('news', [
'title' => 'test 1',
'content' => 'content 1',
]);
}
public function safeDown()
{
$this->delete('news', ['id' => 1]);
$this->dropTable('news');
}
}Ten en cuenta que usualmente cuando ejecutas múltiples operaciones en la BD en safeUp(), deberías revertir su orden de ejecución
en safeDown(). En el ejemplo anterior primero creamos la tabla y luego insertamos la finla en safeUp(); mientras
que en safeDown() primero eliminamos el registro y posteriormente eliminamos la tabla.
Note: No todos los DBMS soportan transacciones. Y algunas consultas a la BD no pueden ser puestas en transacciones. Para algunos ejemplos,
por favor lee acerca de commits implícitos. En estos casos,
deberías igualmente implementarup()ydown().
Métodos de Acceso a la Base de Datos
La clase base [[yii\db\Migration]] provee un grupo de métodos que te permiten acceder y manipular bases de datos.
Podrías encontrar que estos métodos son nombrados de forma similar a los métodos DAO provistos por la clase [[yii\db\Command]].
Por ejemplo, el método [[yii\db\Migration::createTable()]] te permite crear una nueva tabla,
tal como lo hace [[yii\db\Command::createTable()]].
El beneficio de utilizar lo métodos provistos por [[yii\db\Migration]] es que no necesitas explícitamente
crear instancias de [[yii\db\Command]], y la ejecución de cada método mostrará automáticamente mensajes útiles
diciéndote qué operaciones de la base de datos se realizaron y cuánto tiempo tomaron.
Debajo hay una lista de todos los métodos de acceso a la base de datos:
- [[yii\db\Migration::execute()|execute()]]: ejecuta una declaración SQL
- [[yii\db\Migration::insert()|insert()]]: inserta un único registro
- [[yii\db\Migration::batchInsert()|batchInsert()]]: inserta múltiples registros
- [[yii\db\Migration::update()|update()]]: actualiza registros
- [[yii\db\Migration::delete()|delete()]]: elimina registros
- [[yii\db\Migration::createTable()|createTable()]]: crea una nueva tabla
- [[yii\db\Migration::renameTable()|renameTable()]]: renombra una tabla
- [[yii\db\Migration::dropTable()|dropTable()]]: elimina una tabla
- [[yii\db\Migration::truncateTable()|truncateTable()]]: elimina todos los registros de una tabla
- [[yii\db\Migration::addColumn()|addColumn()]]: agrega una columna
- [[yii\db\Migration::renameColumn()|renameColumn()]]: renombra una columna
- [[yii\db\Migration::dropColumn()|dropColumn()]]: elimina una columna
- [[yii\db\Migration::alterColumn()|alterColumn()]]: modifica una columna
- [[yii\db\Migration::addPrimaryKey()|addPrimaryKey()]]: agrega una clave primaria
- [[yii\db\Migration::dropPrimaryKey()|dropPrimaryKey()]]: elimina una clave primaria
- [[yii\db\Migration::addForeignKey()|addForeignKey()]]: agrega una clave foránea
- [[yii\db\Migration::dropForeignKey()|dropForeignKey()]]: elimina una clave foránea
- [[yii\db\Migration::createIndex()|createIndex()]]: crea un índice
- [[yii\db\Migration::dropIndex()|dropIndex()]]: elimina un índice
- [[yii\db\Migration::addCommentOnColumn()|addCommentOnColumn()]]: agrega un comentario a una columna
- [[yii\db\Migration::dropCommentFromColumn()|dropCommentFromColumn()]]: elimina un comentario de una columna
- [[yii\db\Migration::addCommentOnTable()|addCommentOnTable()]]: agrega un comentario a una tabla
- [[yii\db\Migration::dropCommentFromTable()|dropCommentFromTable()]]: elimina un comentario de una tabla
Info: [[yii\db\Migration]] no provee un método de consulta a la base de datos. Esto es porque normalmente no necesitas
mostrar mensajes detallados al traer datos de una base de datos. También se debe a que puedes utilizar el poderoso
Query Builder para generar y ejecutar consultas complejas.
Note: Al manipular datos utilizando una migración podrías encontrar que utilizando tus clases Active Record
para esto podría ser útil ya que algo de la lógica ya está implementada ahí. Ten en cuenta de todos modos, que en contraste con
el código escrito en las migraciones, cuya naturaleza es permanecer constante por siempre, la lógica de la aplicación está sujeta a cambios.
Entonces al utilizar Active Record en migraciones, los cambios en la lógica en la capa Active Record podrían accidentalmente romper
migraciones existentes. Por esta razón, el código de las migraciones debería permanecer independiente de determinada lógica de la aplicación
tal como clases Active Record.
Aplicar Migraciones
To upgrade a database to its latest structure, you should apply all available new migrations using the following command:
Para actualizar una base de datos a su última estructura, deberías aplicar todas las nuevas migraciones utilizando el siguiente comando:
yii migrateEste comando listará todas las migraciones que no han sido aplicadas hasta el momento. Si confirmas que quieres aplicar
dichas migraciones, se correrá el método up() o safeUp() en cada clase de migración nueva, una tras otra,
en el orden de su valor de marca temporal. Si alguna de las migraciones falla, el comando terminará su ejecución sin aplicar
el resto de las migraciones.
Tip: En caso de no disponer de la línea de comandos en el servidor, podrías intentar utilizar
la extensión web shell.
Por cada migración aplicada correctamente, el comando insertará un registro en la base de datos, en la tabla llamadamigration para registrar la correcta aplicación de la migración. Esto permitirá a la herramienta de migración identificar
cuáles migraciones han sido aplicadas y cuáles no.
Info: La herramienta de migración creará automáticamente la tabla
migrationen la base de datos especificada
en la opción [[yii\console\controllers\MigrateController::db|db]] del comando. Por defecto, la base de datos
es especificada en el componente de aplicacióndb.
A veces, podrías sólo querer aplicar una o algunas pocas migraciones, en vez de todas las migraciones disponibles.
Puedes hacer esto el número de migraciones que quieres aplicar al ejecutar el comando.
Por ejemplo, el siguiente comando intentará aplicar las tres siguientes migraciones disponibles:
yii migrate 3Puedes además explícitamente especificar una migración en particular a la cual la base de datos debería migrar
utilizando el comando migrate/to de acuerdo a uno de los siguientes formatos:
yii migrate/to 150101_185401 # utiliza la marca temporal para especificar la migración
yii migrate/to "2015-01-01 18:54:01" # utiliza un string que puede ser analizado por strtotime()
yii migrate/to m150101_185401_create_news_table # utiliza el nombre completo
yii migrate/to 1392853618 # utiliza el tiempo UNIXSi hubiera migraciones previas a la especificada sin aplicar, estas serán aplicadas antes de que la migración especificada
sea aplicada.
Si la migración especificada ha sido aplicada previamente, cualquier migración aplicada posteriormente será revertida.
Revertir Migraciones
Para revertir (deshacer) una o varias migraciones ya aplicadas, puedes ejecutar el siguiente comando:
yii migrate/down # revierte la más reciente migración aplicada
yii migrate/down 3 # revierte las 3 últimas migraciones aplicadasNote: No todas las migraciones son reversibles. Intentar revertir tales migraciones producirá un error y detendrá
completamente el proceso de reversión.
Rehacer Migraciones
Rehacer (re-ejecutar) migraciones significa primero revertir las migraciones especificadas y luego aplicarlas nuevamente. Esto puede hacerse
de esta manera:
yii migrate/redo # rehace la más reciente migración aplicada
yii migrate/redo 3 # rehace las 3 últimas migraciones aplicadasNote: Si una migración no es reversible, no tendrás posibilidades de rehacerla.
Listar Migraciones
Para listar cuáles migraciones han sido aplicadas y cuáles no, puedes utilizar los siguientes comandos:
yii migrate/history # muestra las últimas 10 migraciones aplicadas
yii migrate/history 5 # muestra las últimas 5 migraciones aplicadas
yii migrate/history all # muestra todas las migraciones aplicadas
yii migrate/new # muestra las primeras 10 nuevas migraciones
yii migrate/new 5 # muestra las primeras 5 nuevas migraciones
yii migrate/new all # muestra todas las nuevas migracionesModificar el Historial de Migraciones
En vez de aplicar o revertir migraciones, a veces simplemente quieres marcar que tu base de datos
ha sido actualizada a una migración en particular. Esto sucede normalmente cuando cambias manualmente la base de datos
a un estado particular y no quieres que la/s migración/es de ese cambio sean re-aplicadas posteriormente. Puedes alcanzar este objetivo
con el siguiente comando:
yii migrate/mark 150101_185401 # utiliza la marca temporal para especificar la migración
yii migrate/mark "2015-01-01 18:54:01" # utiliza un string que puede ser analizado por strtotime()
yii migrate/mark m150101_185401_create_news_table # utiliza el nombre completo
yii migrate/mark 1392853618 # utiliza el tiempo UNIXEl comando modificará la tabla migration agregando o eliminado ciertos registros para indicar que en la base de datos
han sido aplicadas las migraciones hasta la especificada. Ninguna migración será aplicada ni revertida por este comando.
Personalizar Migraciones
Hay varias maneras de personalizar el comando de migración.
Utilizar Opciones de la Línea de Comandos
El comando de migración trae algunas opciones de línea de comandos que pueden ser utilizadas para personalizar su comportamiento:
interactive: boolean (por defectotrue), especificar si se debe ejecutar la migración en modo interactivo.
Cuando se indicatrue, se le pedirá confirmación al usuario antes de ejecutar ciertas acciones.
Puedes querer definirlo comofalsesi el comando está siendo utilizado como un proceso de fondo.migrationPath: string (por defecto@app/migrations), especifica el directorio que contiene todos los archivos
de clase de las migraciones. Este puede ser especificado tanto como una ruta a un directorio un alias de ruta.
Ten en cuenta que el directorio debe existir, o el comando disparará un error.migrationTable: string (por defectomigration), especifica el nombre de la tabla de la base de datos que almacena
información del historial de migraciones. Dicha tabla será creada por el comando en caso de que no exista.
Puedes también crearla manualmente utilizando la estructuraversion varchar(255) primary key, apply_time integer.db: string (por defectodb), especifica el ID del componente de aplicación de la base de datos.
Esto representa la base de datos que será migrada en este comando.templateFile: string (por defecto@yii/views/migration.php), especifica la ruta al template
utilizado para generar el esqueleto de los archivos de clases de migración. Puede ser especificado tanto como una ruta a un archivo
como una alias de una ruta. El template es un archivo PHP en el cual puedes utilizar una variable predefinida
llamada$classNamepara obtener el nombre de clase de la migración.generatorTemplateFiles: array (por defecto[ 'create_table' => '@yii/views/createTableMigration.php', 'drop_table' => '@yii/views/dropTableMigration.php', 'add_column' => '@yii/views/addColumnMigration.php', 'drop_column' => '@yii/views/dropColumnMigration.php', 'create_junction' => '@yii/views/createTableMigration.php' ]), especifica los templates utilizados para generar las migraciones. Ver "Generar Migraciones"
para más detalles.fields: array de strings de definiciones de columna utilizado por el código de migración. Por defecto[]. El formato de cada
definición esCOLUMN_NAME:COLUMN_TYPE:COLUMN_DECORATOR. Por ejemplo,--fields=name:string(12):notNullproduce
una columna string de tamaño 12 que es notnull.
El siguiente ejemplo muestra cómo se pueden utilizar estas opciones.
Por ejemplo, si queremos migrar un módulo forum cuyos arhivos de migración
están ubicados dentro del directorio migrations del módulo, podemos utilizar el siguientedocs/guide-es/db-migrations.md
comando:
# realiza las migraciones de un módulo forum sin interacción del usuario
yii migrate --migrationPath=@app/modules/forum/migrations --interactive=0Configurar el Comando Globalmente
En vez de introducir los valores de las opciones cada vez que ejecutas un comandod e migración, podrías configurarlos
de una vez por todas en la configuración de la aplicación como se muestra a continuación:
return [
'controllerMap' => [
'migrate' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationTable' => 'backend_migration',
],
],
];Con esta configuración, cada vez que ejecutes un comando de migración, la tabla backend_migration
será utilizada para registrar el historial de migraciones. No necesitarás volver a especificarla con la opción migrationTable
de la línea de comandos.
Migrar Múltiples Bases de Datos
Por defecto, las migraciones son aplicadas en la misma base de datos especificada en el componente de aplicación db.
Si quieres que sean aplicadas en una base de datos diferente, puedes especificar la opción db como se muestra a continuación,
yii migrate --db=db2El comando anterior aplicará las migraciones en la base de datos db2.
A veces puede suceder que quieras aplicar algunas de las migraciones a una base de datos, mientras algunas otras
a una base de datos distinta. Para lograr esto, al implementar una clase de migración debes especificar explícitamente el ID del componente DB
que la migración debe utilizar, como a continuación:
<?php
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
public function init()
{
$this->db = 'db2';
parent::init();
}
}La migración anterior se aplicará a db2, incluso si especificas una base de datos diferente en la opción db de la
línea de comandos. Ten en cuenta que el historial aún será registrado in la base de datos especificada en la opción db de la línea de comandos.
Si tienes múltiples migraciones que utilizan la misma base de datos, es recomandable que crees una clase base de migración
con el código init() mostrado. Entonces cada clase de migración puede extender de esa clase base.
Tip: Aparte de definir la propiedad [[yii\db\Migration::db|db]], puedes también operar en diferentes bases de datos
creando nuevas conexiones de base de datos en tus clases de migración. También puedes utilizar métodos DAO
con esas conexiones para manipular diferentes bases de datos.
Another strategy that you can take to migrate multiple databases is to keep migrations for different databases in
different migration paths. Then you can migrate these databases in separate commands like the following:
Otra estrategia que puedes seguir para migrar múltiples bases de datos es mantener las migraciones para diferentes bases de datos en
distintas rutas de migración. Entonces podrías migrar esas bases de datos en comandos separados como a continuación:
yii migrate --migrationPath=@app/migrations/db1 --db=db1
yii migrate --migrationPath=@app/migrations/db2 --db=db2
...El primer comando aplicará las migraciones que se encuentran en @app/migrations/db1 en la base de datos db1, el segundo comando
aplicará las migraciones que se encuentran en @app/migrations/db2 en db2, y así sucesivamente.
Guide Es Db Query Builder (`docs/guide-es/db-query-builder.md`)
Constructor de Consultas
Note: Esta sección está en desarrollo.
Yii proporciona una capa de acceso básico a bases de datos como se describe en la sección
Objetos de Acceso a Bases de Datos. La capa de acceso a bases de datos proporciona un método de bajo
nivel (low-level) para interaccionar con la base de datos. Aunque a veces puede ser útil la escritura de sentencias
SQLs puras, en otras situaciones puede ser pesado y propenso a errores. Otra manera de tratar con bases de datos puede
ser el uso de Constructores de Consultas (Query Builder). El Constructor de Consultas proporciona un medio orientado a
objetos para generar las consultas que se ejecutarán.
Un uso típico de Constructor de Consultas puede ser el siguiente:
$rows = (new \yii\db\Query())
->select('id, name')
->from('user')
->limit(10)
->all();
// que es equivalente al siguiente código:
$query = (new \yii\db\Query())
->select('id, name')
->from('user')
->limit(10);
// Crear un comando. Se puede obtener la consulta SQL actual utilizando $command->sql
$command = $query->createCommand();
// Ejecutar el comando:
$rows = $command->queryAll();Métodos de Consulta
Como se puede observar, primero se debe tratar con [[yii\db\Query]]. En realidad, Query sólo se encarga de
representar diversa información de la consulta. La lógica para generar la consulta se efectúa mediante
[[yii\db\QueryBuilder]] cuando se llama al método createCommand(), y la ejecución de la consulta la efectúa
[[yii\db\Command]].
Se ha establecido, por convenio, que [[yii\db\Query]] proporcione un conjunto de métodos de consulta comunes que
construirán la consulta, la ejecutarán, y devolverán el resultado. Por ejemplo:
- [[yii\db\Query::all()|all()]]: construye la consulta, la ejecuta y devuelve todos los resultados en formato de array.
- [[yii\db\Query::one()|one()]]: devuelve la primera fila del resultado.
- [[yii\db\Query::column()|column()]]: devuelve la primera columna del resultado.
- [[yii\db\Query::scalar()|scalar()]]: devuelve la primera columna en la primera fila del resultado.
- [[yii\db\Query::exists()|exists()]]: devuelve un valor indicando si la el resultado devuelve algo.
- [[yii\db\Query::count()|count()]]: devuelve el resultado de la consulta
COUNT. Otros métodos similares incluidos
sonsum($q),average($q),max($q),min($q), que soportan las llamadas funciones de agregación. El parámetro$qes obligatorio en estos métodos y puede ser el nombre de la columna o expresión.
Construcción de Consultas
A continuación se explicará como construir una sentencia SQL que incluya varias clausulas. Para simplificarlo, usamos$query para representar el objeto [[yii\db\Query]]:
`SELECT`
Para formar una consulta SELECT básica, se necesita especificar que columnas y de que tablas se seleccionarán:
$query->select('id, name')
->from('user');Las opciones de select se pueden especificar como una cadena de texto (string) separada por comas o como un array. La
sintaxis del array es especialmente útil cuando se forma la selección dinámicamente.
$query->select(['id', 'name'])
->from('user');Info: Se debe usar siempre el formato array si la clausula
SELECTcontiene expresiones SQL. Esto se debe a
que una expresión SQL comoCONCAT(first_name, last_name) AS full_namepuede contener comas. Si se junta con otra
cadena de texto de otra columna, puede ser que la expresión se divida en varias partes por comas, esto puede
conllevar a errores.
Cuando se especifican columnas, se pueden incluir los prefijos de las tablas o alias de columnas, ej. user.id,user.id AS user_id. Si se usa un array para especificar las columnas, también se pueden usar las claves del array
para especificar los alias de columna, ej. ['user_id' => 'user.id', 'user_name' => 'user.name'].
A partir de la versión 2.0.1, también se pueden seleccionar subconsultas como columnas. Por ejemplo:
$subQuery = (new Query)->select('COUNT(*)')->from('user');
$query = (new Query)->select(['id', 'count' => $subQuery])->from('post');
// $query representa la siguiente sentencia SQL:
// SELECT `id`, (SELECT COUNT(*) FROM `user`) AS `count` FROM `post`Para seleccionar filas distintas, se puede llamar a distinct(), como se muestra a continuación:
$query->select('user_id')->distinct()->from('post');`FROM`
Para especificar de que tabla(s) se quieren seleccionar los datos, se llama a from():
$query->select('*')->from('user');Se pueden especificar múltiples tablas usando una cadena de texto separado por comas o un array. Los nombres de tablas
pueden contener prefijos de esquema (ej. 'public.user') y/o alias de tablas (ej. `'user u'). El método
entrecomillara automáticamente los nombres de tablas a menos que contengan algún paréntesis (que significa que se
proporciona la tabla como una subconsulta o una expresión de BD). Por ejemplo:
$query->select('u.*, p.*')->from(['user u', 'post p']);Cuando se especifican las tablas como un array, también se pueden usar las claves de los arrays como alias de tablas
(si una tabla no necesita alias, no se usa una clave en formato texto). Por ejemplo:
$query->select('u.*, p.*')->from(['u' => 'user', 'p' => 'post']);Se puede especificar una subconsulta usando un objeto Query. En este caso, la clave del array correspondiente se
usará como alias para la subconsulta.
$subQuery = (new Query())->select('id')->from('user')->where('status=1');
$query->select('*')->from(['u' => $subQuery]);`WHERE`
Habitualmente se seleccionan los datos basándose en ciertos criterios. El Constructor de Consultas tiene algunos
métodos útiles para especificarlos, el más poderoso de estos es where, y se puede usar de múltiples formas.
La manera más simple para aplicar una condición es usar una cadena de texto:
$query->where('status=:status', [':status' => $status]);Cuando se usan cadenas de texto, hay que asegurarse que se unen los parámetros de la consulta, no crear una consulta
mediante concatenación de cadenas de texto. El enfoque anterior es seguro, el que se muestra a continuación, no lo es:
$query->where("status=$status"); // Peligroso!En lugar de enlazar los valores de estado inmediatamente, se puede hacer usando params o addParams:
$query->where('status=:status');
$query->addParams([':status' => $status]);Se pueden establecer múltiples condiciones en where usando el formato hash.
$query->where([
'status' => 10,
'type' => 2,
'id' => [4, 8, 15, 16, 23, 42],
]);El código generará la el siguiente SQL:
WHERE (`status` = 10) AND (`type` = 2) AND (`id` IN (4, 8, 15, 16, 23, 42))El valor NULO es un valor especial en las bases de datos, y el Constructor de Consultas lo gestiona inteligentemente.
Este código:
$query->where(['status' => null]);da como resultado la siguiente cláusula WHERE:
WHERE (`status` IS NULL)También se pueden crear subconsultas con objetos de tipo Query como en el siguiente ejemplo:
$userQuery = (new Query)->select('id')->from('user');
$query->where(['id' => $userQuery]);que generará el siguiente código SQL:
WHERE `id` IN (SELECT `id` FROM `user`)Otra manera de usar el método es el formato de operando que es [operator, operand1, operand2, ...].
El operando puede ser uno de los siguientes (ver también [[yii\db\QueryInterface::where()]]):
and: los operandos deben concatenerase usandoAND. por ejemplo,['and', 'id=1', 'id=2']generaráid=1 AND id=2. Si el operando es un array, se convertirá en una cadena de texto usando las reglas aquí descritas.
Por ejemplo,['and', 'type=1', ['or', 'id=1', 'id=2']]generarátype=1 AND (id=1 OR id=2). El método no
ejecutará ningún filtrado ni entrecomillado.or: similar al operandoandexceptuando que los operando son concatenados usandoOR.between: el operando 1 debe ser el nombre de columna, y los operandos 2 y 3 deben ser los valores iniciales y
finales del rango en el que se encuentra la columna. Por ejemplo,['between', 'id', 1, 10]generaráid BETWEEN 1 AND 10.not between: similar abetweenexceptuando queBETWEENse reemplaza porNOT BETWEENen la condición
generada.in: el operando 1 debe ser una columna o una expresión de BD. El operando 2 puede ser un array o un objeto de tipoQuery. Generará una condiciónIN. Si el operando 2 es un array, representará el rango de valores que puede
albergar la columna o la expresión de BD; Si el operando 2 es un objeto de tipoQuery, se generará una subconsulta
y se usará como rango de la columna o de la expresión de BD. Por ejemplo,['in', 'id', [1, 2, 3]]generaráid IN (1, 2, 3). El método entrecomillará adecuadamente el nombre de columna y filtrará los valores del rango. El
operandointambién soporta columnas compuestas. En este caso, el operando 1 debe se un array de columnas,
mientras que el operando 2 debe ser un array de arrays o un objeto de tipoQueryque represente el rango de las
columnas.not in: similar que el operandoinexceptuando queINse reemplaza porNOT INen la condición generada.like: el operando 1 debe ser una columna o una expresión de BD, y el operando 2 debe ser una cadena de texto o un
array que represente los valores a los que tienen que asemejarse la columna o la expresión de BD.Por ejemplo,['like', 'name', 'tester']generaráname LIKE '%tester%'. Cuando se da el valor rango como un array, se
generarán múltiples predicadosLIKEy se concatenaran usandoAND. Por ejemplo,['like', 'name', ['test', 'sample']]generaráname LIKE '%test%' AND name LIKE '%sample%'. También se puede
proporcionar un tercer operando opcional para especificar como deben filtrarse los caracteres especiales en los
valores. El operando debe se un array que mapeen los caracteres especiales a sus caracteres filtrados asociados. Si
no se proporciona este operando, se aplicará el mapeo de filtrado predeterminado. Se puede usarfalseo un array
vacío para indicar que los valores ya están filtrados y no se necesita aplicar ningún filtro. Hay que tener en
cuenta que cuando se usa un el mapeo de filtrado (o no se especifica el tercer operando), los valores se encerraran
automáticamente entre un par de caracteres de porcentaje.
Note: Cuando se usa PostgreSQL también se puede usar
ilikeen lugar delikepara
filtrar resultados insensibles a mayúsculas (case-insensitive).
or like: similar al operandolikeexceptuando que se usaORpara concatenar los predicadosLIKEcuando haya
un segundo operando en un array.not like: similar al operandolikeexceptuando que se usaLIKEen lugar deNOT LIKEen las condiciones
generadas.or not like: similar al operandonot likeexceptuando que se usaORpara concatenar los predicadosNOT LIKE.exists: requiere un operando que debe ser una instancia de [[yii\db\Query]] que represente la subconsulta. Esto
generará una expresiónEXISTS (sub-query).not exists: similar al operandoexistsy genera una expresiónNOT EXISTS (sub-query).
Adicionalmente se puede especificar cualquier cosa como operando:
$query->select('id')
->from('user')
->where(['>=', 'id', 10]);Cuyo resultado será:
SELECT id FROM user WHERE id >= 10;Si se construyen partes de una condición dinámicamente, es muy convenientes usar andWhere() y orWhere():
$status = 10;
$search = 'yii';
$query->where(['status' => $status]);
if (!empty($search)) {
$query->andWhere(['like', 'title', $search]);
}En el caso que $search no este vacío, se generará el siguiente código SQL:
WHERE (`status` = 10) AND (`title` LIKE '%yii%')Construcción de Condiciones de Filtro
Cuando se generan condiciones de filtro basadas en datos recibidos de usuarios (inputs), a menudo se quieren gestionar
de forma especial las "datos vacíos" para ignorarlos en los filtros. Por ejemplo, teniendo un formulario HTML que
obtiene el nombre de usuario y la dirección de correo electrónico. Si el usuario solo rellena el campo de nombre de
usuario, se puede querer generar una consulta para saber si el nombre de usuario recibido es valido. Se puede usarfilterWhere() para conseguirlo:
// $username y $email son campos de formulario rellenados por usuarios
$query->filterWhere([
'username' => $username,
'email' => $email,
]);El método filterWhere() es muy similar al método where(). La principal diferencia es que el filterWhere()
eliminará los valores vacíos de las condiciones proporcionadas. Por lo tanto si $email es "vació", la consulta
resultante será ...WHERE username=:username; y si tanto $username como $email son "vacías", la consulta no
tendrá WHERE.
Decimos que un valor es vacío si es nulo, una cadena de texto vacía, una cadena de texto que consista en espacios en
blanco o un array vacío.
También se pueden usar andFilterWhere() y orFilterWhere() para añadir más condiciones de filtro.
`ORDER BY`
Se pueden usar orderBy y addOrderBy para ordenar resultados:
$query->orderBy([
'id' => SORT_ASC,
'name' => SORT_DESC,
]);Aquí estamos ordenando por id ascendente y después por name descendente.
`GROUP BY` and `HAVING`
Para añadir GROUP BY al SQL generado se puede usar el siguiente código:
$query->groupBy('id, status');Si se quieren añadir otro campo después de usar groupBy:
$query->addGroupBy(['created_at', 'updated_at']);Para añadir la condición HAVING se pueden usar los métodos having y andHaving y orHaving. Los parámetros para
ellos son similares a los del grupo de métodos where:
$query->having(['status' => $status]);`LIMIT` and `OFFSET`
Para limitar el resultado a 10 filas se puede usar limit:
$query->limit(10);Para saltarse las 100 primeras filas, se puede usar:
$query->offset(100);`JOIN`
Las clausulas JOIN se generan en el Constructor de Consultas usando el método join aplicable:
innerJoin()leftJoin()rightJoin()
Este left join selecciona los datos desde dos tablas relacionadas en una consulta:
$query->select(['user.name AS author', 'post.title as title'])
->from('user')
->leftJoin('post', 'post.user_id = user.id');En el código, el primer parámetro del método leftjoin especifica la tabla a la que aplicar el join. El segundo
parámetro, define la condición del join.
Si la aplicación de bases de datos soporta otros tipos de joins, se pueden usar mediante el método join genérico:
$query->join('FULL OUTER JOIN', 'post', 'post.user_id = user.id');El primer argumento es el tipo de join a realizar. El segundo es la tabla a la que aplicar el join, y el tercero es la condición:
Como en FROM, también se pueden efectuar joins con subconsultas. Para hacerlo, se debe especificar la subconsulta
como un array que tiene que contener un elemento. El valor del array tiene que ser un objeto de tipo Query que
represente la subconsulta, mientras que la clave del array es el alias de la subconsulta. Por ejemplo:
$query->leftJoin(['u' => $subQuery], 'u.id=author_id');`UNION`
En SQL UNION agrega resultados de una consulta a otra consulta. Las columnas devueltas por ambas consultas deben
coincidir. En Yii para construirla, primero se pueden formar dos objetos de tipo query y después usar el métodounion:
$query = new Query();
$query->select("id, category_id as type, name")->from('post')->limit(10);
$anotherQuery = new Query();
$anotherQuery->select('id, type, name')->from('user')->limit(10);
$query->union($anotherQuery);Consulta por Lotes
Cuando se trabaja con grandes cantidades de datos, los métodos como [[yii\db\Query::all()]] no son adecuados ya que
requieren la carga de todos los datos en memoria. Para mantener los requerimientos de memoria reducidos, Yii
proporciona soporte a las llamadas consultas por lotes (batch query). Una consulta por lotes usa un cursor de datos y
recupera los datos en bloques.
Las consultas por lotes se pueden usar del siguiente modo:
use yii\db\Query;
$query = (new Query())
->from('user')
->orderBy('id');
foreach ($query->batch() as $users) {
// $users is an array of 100 or fewer rows from the user table
}
// o si se quieren iterar las filas una a una
foreach ($query->each() as $user) {
// $user representa uno fila de datos de la tabla user
}Los métodos [[yii\db\Query::batch()]] y [[yii\db\Query::each()]] devuelven un objeto [[yii\db\BatchQueryResult]] que
implementa una interfaz Iterator y así se puede usar en el constructor foreach. Durante la primera iteración, se
efectúa una consulta SQL a la base de datos. Desde entonces, los datos se recuperan por lotes en las iteraciones. El
tamaño predeterminado de los lotes es 100, que significa que se recuperan 100 filas de datos en cada lote. Se puede
modificar el tamaño de los lotes pasando pasando un primer parámetro a los métodos batch() o each().
En comparación con [[yii\db\Query::all()]], las consultas por lotes sólo cargan 100 filas de datos en memoria cada
vez. Si el procesan los datos y después se descartan inmediatamente, las consultas por lotes, pueden ayudar a mantener
el uso de memora bajo un limite.
Si se especifica que el resultado de la consulta tiene que ser indexado por alguna columna mediante
[[yii\db\Query::indexBy()]], las consultas por lotes seguirán manteniendo el indice adecuado. Por ejemplo,
use yii\db\Query;
$query = (new Query())
->from('user')
->indexBy('username');
foreach ($query->batch() as $users) {
// $users esta indexado en la columna "username"
}
foreach ($query->each() as $username => $user) {
}Guide Es Glossary (`docs/guide-es/glossary.md`)
A
alias
Alias es un string utilizado por Yii para referirse a una clase o directorio tal como @app/vendor.
aplicación
La aplicación es el objeto central durante la solicitud HTTP. Contiene un número de componentes con los que toma información de la solicitud y la envía al controlador apropiado para posterior procesamiento.
El objeto de la aplicación es instanciado como un singleton por el script de entrada. El singleton de la aplicación puede ser accedido desde cualquier lugar a través de \Yii::$app.
assets
Asset se refiere a un archivo de recurso. Típicamente contiene JavaScript o CSS pero puede ser cualquier otra cosa que sea accesible vía HTTP.
atributo
Un atributo es una propiedad de un modelo (una variable miembro de clase o una propiedad mágica definida vía __get()/__set()) que almacena datos de negocio.
B
bundle
Bundle, conocido como paquete en Yii 1.1, se refiere a un número de recursos y un archivo de configuración que describe dependencias y lista recursos.
C
configuración
Configuración puede referirse tanto al proceso de establecer propiedades de un objeto como a un archivo de configuración que almacena la definición de propiedades para un objeto o clase de objetos.
E
extensión
Extensión es un grupo de clases, paquete de recursos y configuraciones que agrega más características a la aplicación.
I
instalación
Instalación es el proceso de preparar algo para trabajar, desde seguir un archivo léame hasta ejecutar un script preparado especialmente para tal fin. En el caso de Yii, define permisos y chequea los requerimientos para el funcionamiento del software.
M
módulo
Módulo es una sub-aplicación que contiene elementos MVC en sí mismo, como modelos, vistas, controladores, etc. y puede ser utilizado dentro de la aplicación principal. Típicamente remitiendo las solicitudes al módulo en vez de manejándolo desde controladores.
N
namespace
Namespace (espacio de nombres) se refiere a una característica de PHP activamente utilizada en Yii 2.
P
paquete
V
vendor
Vendor (proveedor) es una organización o un desarrollador individual que provee código en forma de extensiones, módulos o librerías.
Guide Es Helper Array (`docs/guide-es/helper-array.md`)
ArrayHelper
Adicionalmente al rico conjunto de funciones para arrays de PHP, el array helper de Yii proporciona
métodos estáticos adicionales permitiendo trabajar con arrays de manera más eficiente.
Devolviendo Valores
Recuperar valores de un array, un objeto o una estructura compleja usando PHP estándar es bastante
repetitivo. Tienes que comprobar primero si una clave existe con isset, después devolver el valor si existe, si no,
devolver un valor por defecto:
class User
{
public $name = 'Alex';
}
$array = [
'foo' => [
'bar' => new User(),
]
];
$value = isset($array['foo']['bar']->name) ? $array['foo']['bar']->name : null;Yii proviene de un método muy conveniente para hacerlo:
$value = ArrayHelper::getValue($array, 'foo.bar.name');El primer argumento del método es de donde vamos a obtener el valor. El segundo argumento especifica como devolver el dato. Puede ser
de la siguiente manera:
- Nombre de la clave del array o de la propiedad del objeto para recuperar el valor.
- Conjunto de puntos separados por las claves del array o los nombres de las propiedades del objeto. Esto se ha usado en el ejemplo anterior.
- Un callback que devuelve un valor.
El callback se debería usar de la siguiente manera:
$fullName = ArrayHelper::getValue($user, function ($user, $defaultValue) {
return $user->firstName . ' ' . $user->lastName;
});El tercer argumento opcional es el valor por defecto el cual es null si no se especifica. Podría ser utilizado de la siguiente manera:
$username = ArrayHelper::getValue($comment, 'user.username', 'Unknown');En caso de que quieras coger un valor y luego removerlo inmediatamente del array puedes usar el método remove:
$array = ['type' => 'A', 'options' => [1, 2]];
$type = ArrayHelper::remove($array, 'type');Después de ejecutar el código el $array contendrá ['options' => [1, 2]] y $type debe ser A. Tenga en cuenta que a diferencia del métodogetValue, remove solo soporta nombres clave simples.
Comprobando la Existencia de Claves
ArrayHelper::keyExists funciona de la misma manera que array_key_exists
excepto que también soporta case-insensitive para la comparación de claves. Por ejemplo,
$data1 = [
'userName' => 'Alex',
];
$data2 = [
'username' => 'Carsten',
];
if (!ArrayHelper::keyExists('username', $data1, false) || !ArrayHelper::keyExists('username', $data2, false)) {
echo "Please provide username.";
}Recuperando Columnas
A menudo necesitas obtener unos valores de una columna de las filas de datos u objetos de un array. Un ejemplo común es obtener una lista de IDs.
$data = [
['id' => '123', 'data' => 'abc'],
['id' => '345', 'data' => 'def'],
];
$ids = ArrayHelper::getColumn($array, 'id');El resultado será ['123', '345'].
Si se requieren transformaciones adicionales o la manera de obtener el valor es complejo, se podría especificar como segundo argumento
una función anónima :
$result = ArrayHelper::getColumn($array, function ($element) {
return $element['id'];
});Re-indexar Arrays
Con el fin de indexar un array según una clave especificada, se puede usar el método index. La entrada debería ser
un array multidimensional o un array de objetos. $key puede ser tanto una clave del sub-array, un nombre de una propiedad
del objeto, o una función anónima que debe devolver el valor que será utilizado como clave.
El atributo $groups es un array de claves, que será utilizado para agrupar el array de entrada en uno o más sub-arrays
basado en la clave especificada.
Si el atributo $key o su valor por el elemento en particular es null y $groups no está definido, dicho elemento del array
será descartado. De otro modo, si $groups es especificado, el elemento del array será agregado al array resultante
sin una clave.
Por ejemplo:
$array = [
['id' => '123', 'data' => 'abc', 'device' => 'laptop'],
['id' => '345', 'data' => 'def', 'device' => 'tablet'],
['id' => '345', 'data' => 'hgi', 'device' => 'smartphone'],
];
$result = ArrayHelper::index($array, 'id');');El resultado será un array asociativo, donde la clave es el valor del atributo id
[
'123' => ['id' => '123', 'data' => 'abc', 'device' => 'laptop'],
'345' => ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone']
// El segundo elemento del array original es sobrescrito por el último elemento debido a que tiene el mismo id
]Pasando una función anónima en $key, da el mismo resultado.
$result = ArrayHelper::index($array, function ($element) {
return $element['id'];
});Pasando id como tercer argumento, agrupará $array mediante id:
$result = ArrayHelper::index($array, null, 'id');El resultado será un array multidimensional agrupado por id en su primer nivel y no indexado en su segundo nivel:
[
'123' => [
['id' => '123', 'data' => 'abc', 'device' => 'laptop']
],
'345' => [ // todos los elementos con este índice están presentes en el array resultante
['id' => '345', 'data' => 'def', 'device' => 'tablet'],
['id' => '345', 'data' => 'hgi', 'device' => 'smartphone'],
]
]Una función anónima puede ser usada también en el array agrupador:
$resu