├── .gitignore ├── CONTRIBUTING.md ├── Gemfile ├── Gemfile.lock ├── Gruntfile.js ├── LICENSE ├── README.md ├── _config.yml ├── _includes └── welcome.md ├── _layouts ├── default.html └── page.html ├── _posts ├── 01-01-01-Getting-Started.md ├── 01-02-01-Use-the-Current-Stable-Version.md ├── 01-03-01-Built-in-Web-Server.md ├── 01-04-01-Mac-Setup.md ├── 01-05-01-Windows-Setup.md ├── 02-01-01-Code-Style-Guide.md ├── 03-01-01-Language-Highlights.md ├── 03-02-01-Programming-Paradigms.md ├── 03-03-01-Namespaces.md ├── 03-04-01-Standard-PHP-Library.md ├── 03-05-01-Command-Line-Interface.md ├── 03-06-01-XDebug.md ├── 04-01-01-Dependency-Management.md ├── 04-02-01-Composer-and-Packagist.md ├── 04-03-01-PEAR.md ├── 05-01-01-Coding-Practices.md ├── 05-02-01-The-Basics.md ├── 05-03-01-Date-and-Time.md ├── 05-04-01-Design-Patterns.md ├── 05-05-01-PHP-and-UTF8.md ├── 05-06-01-Internationalization-and-Localization.md ├── 06-01-01-Dependency-Injection.md ├── 06-02-01-Basic-Concept.md ├── 06-03-01-Complex-Problem.md ├── 06-04-01-Containers.md ├── 06-05-01-Further-Reading.md ├── 07-01-01-Databases.md ├── 07-02-01-Databases_MySQL.md ├── 07-03-01-Databases_PDO.md ├── 07-04-01-Interacting-via-Code.md ├── 07-05-01-Abstraction-Layers.md ├── 08-01-01-Templating.md ├── 08-02-01-Benefits.md ├── 08-03-01-Plain-PHP-Templates.md ├── 08-04-01-Compiled-Templates.md ├── 08-05-01-Further-Reading.md ├── 09-01-01-Errors-and-Exceptions.md ├── 09-02-01-Errors.md ├── 09-03-01-Exceptions.md ├── 10-01-01-Security.md ├── 10-02-01-Web-Application-Security.md ├── 10-03-01-Password-Hashing.md ├── 10-04-01-Data-Filtering.md ├── 10-05-01-Configuration-Files.md ├── 10-06-01-Register-Globals.md ├── 10-07-01-Error-Reporting.md ├── 11-01-01-Testing.md ├── 11-02-01-Test-Driven-Development.md ├── 11-03-01-Behavior-Driven-Development.md ├── 11-04-01-Complementary-Testing-Tools.md ├── 12-01-01-Servers-and-Deployment.md ├── 12-02-01-Platform-as-a-Service.md ├── 12-03-01-Virtual-or-Dedicated-Servers.md ├── 12-04-01-Shared-Servers.md ├── 12-05-01-Building-your-Application.md ├── 13-01-01-Virtualization.md ├── 13-02-01-Vagrant.md ├── 13-03-01-Docker.md ├── 14-01-01-Caching.md ├── 14-02-01-Opcode-Cache.md ├── 14-03-01-Object-Caching.md ├── 15-01-01-Documenting.md ├── 15-02-01-PHPDoc.md ├── 16-01-01-Resources.md ├── 16-02-01-From-the-Source.md ├── 16-03-01-People-to-Follow.md ├── 16-04-01-Mentoring.md ├── 16-05-01-PHP-PaaS-Providers.md ├── 16-06-01-Frameworks.md ├── 16-07-01-Components.md ├── 16-08-01-Sites.md ├── 16-09-01-Videos.md ├── 16-10-01-Books.md ├── 17-01-01-Community.md ├── 17-02-01-User-Groups.md ├── 17-03-01-Conferences.md └── 17-04-01-Elephpants.md ├── banners.md ├── css └── all.css ├── images ├── banners │ ├── btn1-120x90.png │ ├── btn2-120x60.png │ ├── leaderboard-728x90.png │ ├── lg-rect-386x280.png │ ├── med-rect-300x250.png │ ├── rect-180x150.png │ ├── sq-btn-125x125.png │ └── vert-rect-240x400.png ├── favicon.png ├── nmc-logo.gif ├── og-image.png └── og-logo.png ├── index.html ├── less └── all.less ├── package.json ├── pages ├── Design-Patterns.md ├── Functional-Programming.md ├── The-Basics.md └── example.md ├── scripts ├── fastclick.js └── setup.js └── styles ├── all.css ├── all.less ├── base ├── all.less ├── bars-buttons.less ├── buttons.less ├── grid.less ├── idioms.less ├── prefixer.less ├── reset.less ├── spacing.less ├── typography.less └── variables.less ├── print.css ├── site ├── site-content.less ├── site-footer.less ├── site-header.less ├── site-navigation.less └── variables.less └── syntax.css /.gitignore: -------------------------------------------------------------------------------- 1 | /_site/ 2 | *.DS_Store 3 | node_modules 4 | vendor 5 | .bundle 6 | .idea 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to PHP The Right Way 2 | 3 | Enjoy [PHP The Right Way](http://phptherightway.com) and want to get 4 | involved? Great! There are plenty of ways you can help out. 5 | 6 | Please take a moment to review this document in order to make the contribution 7 | process easy and effective for everyone involved. 8 | 9 | Following these guidelines helps to communicate that you respect the time of 10 | the developers managing and developing this open source project. In return, 11 | they should reciprocate that respect in addressing your issue or assessing 12 | patches and features. 13 | 14 | 15 | ## Using the issue tracker 16 | 17 | The [issue tracker](https://github.com/codeguy/php-the-right-way/issues) is 18 | the preferred channel for changes: spelling mistakes, wording changes, new 19 | content and generally [submitting pull requests](#pull-requests), but please 20 | respect the following restrictions: 21 | 22 | * Please **do not** use the issue tracker for personal support requests (use 23 | [Stack Overflow](http://stackoverflow.com/questions/tagged/php) or IRC). 24 | 25 | * Please **do not** derail or troll issues. Keep the discussion on topic and 26 | respect the opinions of others. 27 | 28 | 29 | 30 | ## Pull Requests 31 | 32 | Pull requests are a great way to add new content to PHP The Right Way, as well 33 | as updating any browser issues or other style changes. Pretty much any sort of 34 | change is accepted if seen as constructive. 35 | 36 | Adhering to the following this process is the best way to get your work 37 | included in the project: 38 | 39 | 1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, 40 | and configure the remotes: 41 | 42 | ```bash 43 | # Clone your fork of the repo into the current directory 44 | git clone https://github.com//php-the-right-way.git 45 | # Navigate to the newly cloned directory 46 | cd php-the-right-way 47 | # Assign the original repo to a remote called "upstream" 48 | git remote add upstream https://github.com/codeguy/php-the-right-way.git 49 | ``` 50 | 51 | 2. If you cloned a while ago, get the latest changes from upstream: 52 | 53 | ```bash 54 | git checkout gh-pages 55 | git pull upstream gh-pages 56 | ``` 57 | 58 | 3. Create a new topic branch (off the main project development branch) to 59 | contain your change or fix: 60 | 61 | ```bash 62 | git checkout -b 63 | ``` 64 | 65 | 4. Install the [Jekyll](https://github.com/jekyll/jekyll/) gem and dependencies to preview locally: 66 | 67 | ```bash 68 | # Install the needed gems through Bundler 69 | bundle install --path vendor/bundle 70 | # Run the local server 71 | bundle exec jekyll serve 72 | ``` 73 | 74 | 5. Commit your changes in logical chunks. Please adhere to these [git commit 75 | message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) 76 | or your content is unlikely be merged into the main project. Use Git's 77 | [interactive rebase](https://help.github.com/articles/interactive-rebase) 78 | feature to tidy up your commits before making them public. 79 | 80 | 6. Locally merge (or rebase) the upstream development branch into your topic branch: 81 | 82 | ```bash 83 | git pull [--rebase] upstream gh-pages 84 | ``` 85 | 86 | 7. Push your topic branch up to your fork: 87 | 88 | ```bash 89 | git push origin 90 | ``` 91 | 92 | 8. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) 93 | with a clear title and description. 94 | 95 | 96 | ## Contribution Agreement and Usage 97 | 98 | By submitting a pull request to this repository, you agree to allow the project 99 | owners to license your work under the the terms of the [Creative Commons Attribution-NonCommercial-ShareAlike 100 | 3.0 Unported License](http://creativecommons.org/licenses/by-nc-sa/3.0/). 101 | 102 | The same content and license will be used for all PHP The Right Way publications, 103 | including - but not limited to: 104 | 105 | * [phptherightway.com](http://phptherightway.com) 106 | * Translations of phptherightway.com 107 | * [LeanPub: PHP The Right Way](https://leanpub.com/phptherightway/) 108 | * Translations of "LeanPub: PHP The Right Way" 109 | 110 | All content is completely free now, and always will be. 111 | 112 | ## Contributor Style Guide 113 | 114 | 1. Use American English spelling (*primary English repo only*) 115 | 2. Use four (4) spaces to indent text; do not use tabs 116 | 3. Wrap all text to 120 characters 117 | 4. Code samples should adhere to PSR-1 or higher 118 | 5. Use [GitHub Flavored Markdown](http://github.github.com/github-flavored-markdown/) for all content 119 | 6. Use language agnostic urls when referring to external websites such as the [php.net](http://php.net/urlhowto.php) manual 120 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'github-pages' 3 | gem 'rouge' 4 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | RedCloth (4.2.9) 5 | activesupport (5.0.0.1) 6 | concurrent-ruby (~> 1.0, >= 1.0.2) 7 | i18n (~> 0.7) 8 | minitest (~> 5.1) 9 | tzinfo (~> 1.1) 10 | addressable (2.4.0) 11 | blankslate (2.1.2.4) 12 | classifier-reborn (2.0.4) 13 | fast-stemmer (~> 1.0) 14 | coffee-script (2.4.1) 15 | coffee-script-source 16 | execjs 17 | coffee-script-source (1.10.0) 18 | colorator (0.1) 19 | concurrent-ruby (1.0.2) 20 | ethon (0.9.1) 21 | ffi (>= 1.3.0) 22 | execjs (2.7.0) 23 | faraday (0.10.0) 24 | multipart-post (>= 1.2, < 3) 25 | fast-stemmer (1.0.2) 26 | ffi (1.9.14) 27 | ffi (1.9.14-x64-mingw32) 28 | gemoji (2.1.0) 29 | github-pages (39) 30 | RedCloth (= 4.2.9) 31 | github-pages-health-check (~> 0.2) 32 | jekyll (= 2.4.0) 33 | jekyll-coffeescript (= 1.0.1) 34 | jekyll-feed (= 0.3.1) 35 | jekyll-mentions (= 0.2.1) 36 | jekyll-redirect-from (= 0.8.0) 37 | jekyll-sass-converter (= 1.3.0) 38 | jekyll-sitemap (= 0.8.1) 39 | jemoji (= 0.5.0) 40 | kramdown (= 1.5.0) 41 | liquid (= 2.6.2) 42 | maruku (= 0.7.0) 43 | mercenary (~> 0.3) 44 | pygments.rb (= 0.6.3) 45 | rdiscount (= 2.1.7) 46 | redcarpet (= 3.3.2) 47 | terminal-table (~> 1.4) 48 | github-pages-health-check (0.3.2) 49 | net-dns (~> 0.6) 50 | public_suffix (~> 1.4) 51 | typhoeus (~> 0.7) 52 | html-pipeline (1.9.0) 53 | activesupport (>= 2) 54 | nokogiri (~> 1.4) 55 | i18n (0.7.0) 56 | jekyll (2.4.0) 57 | classifier-reborn (~> 2.0) 58 | colorator (~> 0.1) 59 | jekyll-coffeescript (~> 1.0) 60 | jekyll-gist (~> 1.0) 61 | jekyll-paginate (~> 1.0) 62 | jekyll-sass-converter (~> 1.0) 63 | jekyll-watch (~> 1.1) 64 | kramdown (~> 1.3) 65 | liquid (~> 2.6.1) 66 | mercenary (~> 0.3.3) 67 | pygments.rb (~> 0.6.0) 68 | redcarpet (~> 3.1) 69 | safe_yaml (~> 1.0) 70 | toml (~> 0.1.0) 71 | jekyll-coffeescript (1.0.1) 72 | coffee-script (~> 2.2) 73 | jekyll-feed (0.3.1) 74 | jekyll-gist (1.4.0) 75 | octokit (~> 4.2) 76 | jekyll-mentions (0.2.1) 77 | html-pipeline (~> 1.9.0) 78 | jekyll (~> 2.0) 79 | jekyll-paginate (1.1.0) 80 | jekyll-redirect-from (0.8.0) 81 | jekyll (>= 2.0) 82 | jekyll-sass-converter (1.3.0) 83 | sass (~> 3.2) 84 | jekyll-sitemap (0.8.1) 85 | jekyll-watch (1.5.0) 86 | listen (~> 3.0, < 3.1) 87 | jemoji (0.5.0) 88 | gemoji (~> 2.0) 89 | html-pipeline (~> 1.9) 90 | jekyll (>= 2.0) 91 | kramdown (1.5.0) 92 | liquid (2.6.2) 93 | listen (3.0.8) 94 | rb-fsevent (~> 0.9, >= 0.9.4) 95 | rb-inotify (~> 0.9, >= 0.9.7) 96 | maruku (0.7.0) 97 | mercenary (0.3.6) 98 | mini_portile2 (2.1.0) 99 | minitest (5.9.1) 100 | multipart-post (2.0.0) 101 | net-dns (0.8.0) 102 | nokogiri (1.6.8.1) 103 | mini_portile2 (~> 2.1.0) 104 | nokogiri (1.6.8.1-x64-mingw32) 105 | mini_portile2 (~> 2.1.0) 106 | octokit (4.6.1) 107 | sawyer (~> 0.8.0, >= 0.5.3) 108 | parslet (1.5.0) 109 | blankslate (~> 2.0) 110 | posix-spawn (0.3.12) 111 | public_suffix (1.5.3) 112 | pygments.rb (0.6.3) 113 | posix-spawn (~> 0.3.6) 114 | yajl-ruby (~> 1.2.0) 115 | rb-fsevent (0.9.8) 116 | rb-inotify (0.9.7) 117 | ffi (>= 0.5.0) 118 | rdiscount (2.1.7) 119 | redcarpet (3.3.2) 120 | rouge (2.0.7) 121 | safe_yaml (1.0.4) 122 | sass (3.4.22) 123 | sawyer (0.8.1) 124 | addressable (>= 2.3.5, < 2.6) 125 | faraday (~> 0.8, < 1.0) 126 | terminal-table (1.7.3) 127 | unicode-display_width (~> 1.1.1) 128 | thread_safe (0.3.5) 129 | toml (0.1.2) 130 | parslet (~> 1.5.0) 131 | typhoeus (0.8.0) 132 | ethon (>= 0.8.0) 133 | tzinfo (1.2.2) 134 | thread_safe (~> 0.1) 135 | unicode-display_width (1.1.1) 136 | yajl-ruby (1.2.1) 137 | 138 | PLATFORMS 139 | ruby 140 | x64-mingw32 141 | 142 | DEPENDENCIES 143 | github-pages 144 | rouge 145 | 146 | BUNDLED WITH 147 | 1.13.6 148 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | // Project configuration 3 | grunt.initConfig({ 4 | pkg: grunt.file.readJSON('package.json'), 5 | less: { 6 | dist: { 7 | options: { 8 | cleancss: true, 9 | compress: true, 10 | ieCompat: true 11 | }, 12 | files: { 13 | "css/all.css": "less/all.less" 14 | } 15 | } 16 | }, 17 | postcss: { 18 | options: { 19 | map: true, 20 | processors: [ 21 | require('autoprefixer')({ 22 | browsers: ['last 2 versions', 'ie 9'] 23 | }) 24 | ] 25 | }, 26 | dist: { 27 | src: 'css/all.css' 28 | } 29 | }, 30 | watch: { 31 | less: { 32 | files: ['less/**/*.less'], 33 | tasks: ['less:dist', 'postcss:dist'], 34 | options: { 35 | spawn: false 36 | } 37 | } 38 | } 39 | }); 40 | 41 | // Load plugins 42 | grunt.loadNpmTasks('grunt-contrib-less'); 43 | grunt.loadNpmTasks('grunt-contrib-watch'); 44 | grunt.loadNpmTasks('grunt-postcss'); 45 | 46 | // Default task(s) 47 | grunt.registerTask('default', ['less', 'postcss:dist']); 48 | }; 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Josh Lockhart 2 | 3 | http://creativecommons.org/licenses/by-nc-sa/3.0/ 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHP: The Right Way 2 | 3 | ## Overview 4 | 5 | This is the GitHub Pages repository for the _PHP: The Right Way_ project. 6 | 7 | * This website is a Jekyll project. 8 | * Each section and sub-section are a Markdown file in `_posts/`. 9 | * Sub-sections have `isChild: true` in their front matter. 10 | * The navigation and page structure are automatically generated. 11 | 12 | ## Spread the Word! 13 | 14 | _PHP: The Right Way_ has web banner images you can use on your website. Show your support, and let new PHP 15 | developers know where to find good information! 16 | 17 | [See Banner Images](http://www.phptherightway.com/banners.html) 18 | 19 | ## How to Contribute 20 | 21 | You should read the `CONTRIBUTING.md` file for precise instructions and tips. But, if you prefer a TL;DR: 22 | 23 | 1. Fork and edit 24 | 2. Optionally install [Ruby](https://rvm.io/rvm/install/) with [Jekyll](https://github.com/mojombo/jekyll/) gem to preview locally 25 | 3. Submit pull request for consideration 26 | 27 | ### Contributor Style Guide 28 | 29 | 1. Use American English spelling (*primary English repo only*) 30 | 2. Use four (4) spaces to indent text; do not use tabs. 31 | 3. Wrap all text to 120 characters. 32 | 4. Code samples should adhere to PSR-1 or higher. 33 | 34 | ## Where 35 | 36 | 37 | 38 | * [English](http://www.phptherightway.com) 39 | * [Deutsch](http://rwetzlmayr.github.io/php-the-right-way) 40 | * [Español](http://phpdevenezuela.github.io/php-the-right-way) 41 | * [Français](http://eilgin.github.io/php-the-right-way/) 42 | * [Indonesia](http://id.phptherightway.com) 43 | * [Italiano](http://it.phptherightway.com) 44 | * [Polski](http://pl.phptherightway.com) 45 | * [Português do Brasil](http://br.phptherightway.com) 46 | * [Română](https://bgui.github.io/php-the-right-way/) 47 | * [Slovenščina](http://sl.phptherightway.com) 48 | * [Srpski](http://phpsrbija.github.io/php-the-right-way/) 49 | * [Türkçe](http://hkulekci.github.io/php-the-right-way/) 50 | * [български](http://bg.phptherightway.com) 51 | * [Русский язык](http://getjump.github.io/ru-php-the-right-way) 52 | * [Українська](http://iflista.github.com/php-the-right-way) 53 | * [العربية](https://adaroobi.github.io/php-the-right-way/) 54 | * [فارسى](http://novid.github.io/php-the-right-way/) 55 | * [ภาษาไทย](https://apzentral.github.io/php-the-right-way/) 56 | * [한국어판](http://modernpug.github.io/php-the-right-way) 57 | * [日本語](http://ja.phptherightway.com) 58 | * [简体中文](http://laravel-china.github.io/php-the-right-way/) 59 | * [繁體中文](http://laravel-taiwan.github.io/php-the-right-way) 60 | 61 | ### Translations 62 | 63 | If you are interested in translating _PHP: The Right Way_, fork this repo on GitHub and publish your localized fork to your own GitHub Pages account. We'll link to your translation from the primary document. 64 | 65 | To avoid fragmentation and reader confusion, please choose one of these options: 66 | 67 | 1. We link to your GitHub Pages fork with `[username].github.io/php-the-right-way` 68 | 2. We link to your GitHub Pages fork with a subdomain (e.g. "ru.phptherightway.com") 69 | 70 | If you use a subdomain, enter the subdomain into the `CNAME` file, and ask us to setup DNS for you. If you do not use a subdomain, remove the `CNAME` file entirely else your fork will not build when pushed. 71 | 72 | Add information about your translation in the [wiki page](https://github.com/codeguy/php-the-right-way/wiki/Translations). 73 | 74 | When your translation is ready, open an issue on the Issue Tracker to let us know. 75 | 76 | ## Why 77 | 78 | There's been a lot of discussion lately about how the PHP community lacks sufficient, credible information for programmers new to PHP. This repository aims to solve this problem. 79 | 80 | ## Who 81 | 82 | My name is [Josh Lockhart](http://twitter.com/codeguy). I'm the author of the [Slim Framework](http://www.slimframework.com/), and I work for [New Media Campaigns](http://www.newmediacampaigns.com/). 83 | 84 | ### Collaborators 85 | 86 | * [Kris Jordan](http://krisjordan.com/) 87 | * [Phil Sturgeon](http://philsturgeon.co.uk/) 88 | 89 | ## License 90 | 91 | [Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-nc-sa/3.0/) 92 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | baseurl: /php-the-right-way/ 2 | highlighter: rouge 3 | markdown: kramdown 4 | permalink: date 5 | maruku: 6 | use_tex: false 7 | use_divs: false 8 | png_engine: blahtex 9 | png_dir: images/latex 10 | png_url: /images/latex 11 | 12 | gems: 13 | - jekyll-sitemap 14 | 15 | defaults: 16 | - 17 | scope: 18 | path: "" 19 | values: 20 | sitemap: false 21 | 22 | exclude: ['CNAME', 'CONTRIBUTING.md', 'LICENSE', 'README.md', 'pages/example.md', 'vendor'] 23 | 24 | future: true 25 | -------------------------------------------------------------------------------- /_includes/welcome.md: -------------------------------------------------------------------------------- 1 | # الترحيب 2 | 3 | هنالك العديد من المصادر القديمة على شبكة الإنترنت لتعلم لغة PHP التي تؤثر سلباً على المطورين الجدد، 4 | بحيث تقدم لهم عدة مفاهيم وأسس قد انتهى عصرها وصارت قديمة، بالإضافة لشيفرات برمجية غير آمنة. 5 | _PHP: بالطريقة الصحيحة_ هو دليل سريع وسهل للطرق القياسية لبرمجة وتطوير PHP الأكثر شهرة، 6 | وروابط لدروس ودلائل موثوقة على شبكة الإنترنت وكل ما يعتبره المساهمون كمعايير قياسية 7 | حتى هذه اللحظة. 8 | 9 | _لا يوجد قاعدة موحدة للبرمجة باستخدام PHP_. هذا الموقع يهدف إلى تعريف مطوري PHP الجدد إلى بعض 10 | المواضيع التي قد لا يعرفها أو يتطرق لها إلا بعد فوات الأوان، ويهدف أيضاً لتوضيح وتنقيح إيجابيات 11 | المواضيع التي قد تم التطرق إليها واستخدامها منذ عدة سنين من دون إعادة النظر إليها. 12 | لن يدلك هذا الموقع لاستخدام أدوات أو أساليب محددة، ولكن يوفر لك مقتراحات لأكثر من خيار، 13 | مع توضيح الفرق ما بينها إن أمكن ذلك مع أمثلة وطرق استخدام. 14 | 15 | هذا الموقع حي ومحدث وسوف يتم تحديثه باستمرار بمعلومات وأمثلة مفيدة جديدة حين توافرها. 16 | 17 | ## الترجمات {#translations} 18 | 19 | _PHP: بالطريقة الصحيحة_ متوفر بعدة لغات اخرى: 20 | 21 | * [English](http://www.phptherightway.com) 22 | * [Deutsch](http://rwetzlmayr.github.io/php-the-right-way) 23 | * [Español](http://phpdevenezuela.github.io/php-the-right-way) 24 | * [Français](http://eilgin.github.io/php-the-right-way/) 25 | * [Indonesia](http://id.phptherightway.com) 26 | * [Italiano](http://it.phptherightway.com) 27 | * [Polski](http://pl.phptherightway.com) 28 | * [Português do Brasil](http://br.phptherightway.com) 29 | * [Română](https://bgui.github.io/php-the-right-way/) 30 | * [Slovenščina](http://sl.phptherightway.com) 31 | * [Srpski](http://phpsrbija.github.io/php-the-right-way/) 32 | * [Türkçe](http://hkulekci.github.io/php-the-right-way/) 33 | * [български](http://bg.phptherightway.com) 34 | * [Русский язык](http://getjump.github.io/ru-php-the-right-way) 35 | * [Українська](http://iflista.github.com/php-the-right-way) 36 | * [العربية](https://adaroobi.github.io/php-the-right-way/) 37 | * [فارسى](http://novid.github.io/php-the-right-way/) 38 | * [ภาษาไทย](https://apzentral.github.io/php-the-right-way/) 39 | * [한국어판](http://modernpug.github.io/php-the-right-way) 40 | * [日本語](http://ja.phptherightway.com) 41 | * [简体中文](http://laravel-china.github.io/php-the-right-way/) 42 | * [繁體中文](http://laravel-taiwan.github.io/php-the-right-way) 43 | 44 | ## كتاب 45 | يمكن الحصول على أحدث نسخة من _PHP بالطريقة الصحيحة_ في صيغة PDF ، EPUB ، MOBI. [من Leanpub][1] 46 | 47 | ## كيفية المساهمة {#how-to-contribute} 48 | 49 | قم بالمساعدة لجعل هذا الموقع أفضل مصدر لمبرمجي PHP الجدد [قم بالمساهمة في تطوير المحتوى العربي على GitHub][2] 50 | أو [المحتوى الأصلي باللغة الإنجليزية على GitHub][3]. 51 | 52 | __ملاحظة:__ يتم التحديث وإضافة المحتوى وفقاً للمحتوى باللغة الإنجليزية، إذا كان هنالك أي إضافة تود إدراجها فضلاً قم بزيارة 53 | المحتوى [المحتوى الأصلي باللغة الإنجليزية على GitHub][3]. 54 | 55 | ## قم بالنشر! {#spread-the-word} 56 | 57 | _PHP: بالطريقة الصحيحة_ لديه عدة بانرات صور يمكنك أن تضعها في موقعك. قم بالدعم ودع المطورين الجدد يعرفون المصدر 58 | لمعرفة معلومات مفيدة! 59 | 60 | [صور البانرات][4] 61 | 62 | [1]: https://leanpub.com/phptherightway 63 | [2]: https://github.com/adaroobi/php-the-right-way/tree/gh-pages 64 | [3]: https://github.com/codeguy/php-the-right-way/tree/gh-pages 65 | [4]: /banners.html 66 | -------------------------------------------------------------------------------- /_posts/01-01-01-Getting-Started.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: قم بالبدء 3 | isChild: false 4 | anchor: getting_started 5 | --- 6 | 7 | # لنبدأ {#getting_started_title} 8 | 9 | -------------------------------------------------------------------------------- /_posts/01-02-01-Use-the-Current-Stable-Version.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: قم باستخدام آخر نسخة مستقرة (7.1) 3 | isChild: true 4 | anchor: use_the_current_stable_version 5 | --- 6 | 7 | ## قم باستخدام آخر نسخة مستقرة (7.1) {#use_the_current_stable_version_title} 8 | 9 | إذا كنت تريد البدء بالتطوير بلغة PHP، إذاً قم باستخدام آخر نسخة مستقرة من [PHP 7.1][php-release]. 10 | PHP 7.1 هي نسخة جديدة، تم إضافة العديد من المميزات [المميزات الجديدة](#language_highlights) مقارنة بالنسخ القديمة 5.×. 11 | قد تم إعادة بناء محرك اللغة من جديد، فالآن PHP أصبحت أسرع من سبيقاتها. 12 | 13 | في الغالب حتى الآن سوف تجد أن PHP 5.× ما تزال مستخدمة مع العلم أن آخر نسخة من PHP 5.× هي PHP 5.6. وهذه النسخة لا تعتبر خياراً سيئًـا ولكن يتوجب عليك التحديث إلى آخر نسخة مستقرة في أقرب فرصة. 14 | [سيتوقف الدعم وضخ التحديثات الأمنية على النسخة PHP 5.6 بعد العام 2018](http://php.net/supported-versions.php). 15 | عملية التحديث هي عملية سهلة للغاية، ربما قد تواجه بضع ماشكل توافقية مع الأعمال المكتوبة بالإصدارات السابقة ولكن يمكنك الاطلاع على صفحة [التوافقية مع الإصدارات السابقة][php71-bc]. 16 | إذا كنت غير متأكد من وجود دالة أو ميزة في أي إصدار، يمكنك التأكد عبر زيارة موقع دليل توثيق PHP [php.net][php-docs]. 17 | 18 | [php-release]: http://php.net/downloads.php 19 | [php-docs]: http://php.net/manual/ 20 | [php71-bc]: http://php.net/manual/migration71.incompatible.php 21 | -------------------------------------------------------------------------------- /_posts/01-03-01-Built-in-Web-Server.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: خادم ويب مدمج 3 | isChild: true 4 | anchor: builtin_web_server 5 | --- 6 | 7 | ## خادم ويب مدمج {#builtin_web_server_title} 8 | 9 | منذ إصدار PHP 5.4 بإمكانك تعلم PHP بدون تنصيب أي إضافات أو تخصيصات، مع التمتع بكل خصائص خادم الويب المعتاد. 10 | لتشغيل الخادم قم بتنفيذ هذا الأمر من نافذة الأوامر من مجلد مشروعك الرئيس: 11 | 12 | {% highlight console %} 13 | > php -S localhost:8000 14 | {% endhighlight %} 15 | 16 | * [لمعرفة المزيد عن أوامر أخرى لخادم الويب المدمج][cli-server] 17 | 18 | 19 | [cli-server]: http://php.net/features.commandline.webserver 20 | -------------------------------------------------------------------------------- /_posts/01-04-01-Mac-Setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: التنصيب على نظام تشغيل Mac 3 | isChild: true 4 | anchor: mac_setup 5 | --- 6 | 7 | ## التنصيب على نظام تشغيل Mac {#mac_setup_title} 8 | 9 | يحتوي نظام التشغيل OS X على إصدار PHP ولكنها عادة ما تكون غير حديثة. 10 | فالنسخة OS X Mavericks تحتوي على الإصدار 5.4.17، والنسخة OS X Yosemite تحتوي على الإصدار 5.5.9، 11 | والنسخة OS X El Capitan تحتوي على الإصدار 5.5.29 وSierra 5.6.24. لكن مع انطلاق إصدار PHP 7.1 لم تعد هذه الإصدارات جيدة للاستخدام. 12 | 13 | هنالك عدة طرق لتنصيب PHP على نظام تشغيل Mac OS X. 14 | 15 | ### التنصيب بواسطة Homebrew 16 | 17 | [Homebrew] هو عبارة عن مدير تطبيقات لنظام تشغيل Mac OS x، يساعدك على تنصيب PHP وملحقاتها بكل سهولة. 18 | [Homebrew PHP] هو المستودع الذي يحتوي كل ما يتعلق بـ PHP لمدير التطبيقات Homebrew، ويمكنك من تنصيب PHP بكل سهولة. 19 | 20 | حتى هذه اللحظة يمكنك تنصيب كل من `php53`، `php54`، `php55`، `php56` ،`php71`، `php70` باستخدام الأمر `brew install`، ويمكنك التحويل 21 | فيما بينهم بتعديل متغير `PATH`. أو يمكنك استخدام [brew-php-switcher][brew-php-switcher] للتحويل التلقائي. 22 | 23 | ### التنصيب بواسطة Macports 24 | 25 | مشروع [MacPorts] هو مشروع مفتوح المصدر يهدف لتصميم نظام سهل الاستخدام لتجميع وتنصيب وتحديث 26 | البرامج المفتوحة المصدر لكل من برامج سطور الأوامر X11، Aqua على نظام تشغيل Mac OS X. 27 | 28 | يدعم MacPorts الملفات بلغة الآلة المبنية مسبقاً (Pre-Compiled Binaries) لكيلا تقوم بإعادة بناء كل حزمة من متطلبات 29 | النظام من الملفات المصدرية (tarball files)، فهي توفر لك سهولة تنصيب الحزم خصوصاً عندما لا يحتوي نظامك على إحداها. 30 | 31 | حتى هذه اللحظة يمكنك تنصيب كل من `php54`، `php55`، `php56`، `php70`، `php71` باستخدام الأمر `port install` مثلاً: 32 | 33 | sudo port install php56 34 | sudo port install php71 35 | 36 | ويمكنك تشغيل الأمر `select` لتَّحويل بين الإصدارات المتوفرة. 37 | 38 | sudo port select --set php php71 39 | 40 | ### التنصيب بواسطة phpbrew 41 | 42 | [phpbrew] هي إداة لتنصيب وإدارة أكثر من إصدار PHP. فهي أداة مفيدة جداً عندما يتطلب مشروعان إصدارات مختلفة من PHP 43 | وتريد تشغيلهما بدون الحاجة لنظام تشغيل افتراضي. 44 | 45 | ### التنصيب بواسطة Liip's binary installer 46 | 47 | وسيلة أخرى متاحة وهي [php-osx.liip.ch] فهي توفر وسيلة تنصيب لنسخة واحدة لكل من الإصدارات ابتداء من 5.3 حتى 7.1. 48 | تتميز بأنها لا تستبدل ملفات حزمة PHP binaries المدمجة مع نظام Apple، ولكنها تعمل على التنصيب في مكان آخر (/usr/local/php5). 49 | 50 | ### البناء من المصدر Compile from Source 51 | 52 | وسيلة أخرى تمكنك من التحكم بإصدارات PHP وتنصيبها، وذلك عن طريق [بنائها بنفسك][mac-compile]. 53 | في هذه الحالة تَأَكَّد من تنصيب [Xcode][xcode-gcc-substitution]، أو["Command Line Tools for XCode"] التابعة 54 | لـ Apple ويمكن تحميلها ["Command Line Tools for XCode"] من قسم Mac للمطورين (Mac Developer Center). 55 | 56 | ### تنصيب حلول متكاملة مجمعة «الكل في واحد» 57 | 58 | كل الحلول السابق ذكرها تتلخص بأنك تطبق عملية تنصيب PHP بنفسك، وهي لا تشمل تنصيب برامج مثل Apache, Nginx أو حتى خادم SQL. 59 | «الكل في واحد» هي حلول متكاملة مثل [MAMP][mamp-downloads] و [XAMPP][xampp] فهي تقوم بتنصيب كل تلك البرامج وضبطهم معاً، ولكن رغم سهولة التنصيب فإن مثل هذه الحلول تفتقر للمرونة. 60 | 61 | 62 | [Homebrew]: http://brew.sh/ 63 | [Homebrew PHP]: https://github.com/Homebrew/homebrew-php#installation 64 | [MacPorts]: https://www.macports.org/install.php 65 | [phpbrew]: https://github.com/phpbrew/phpbrew 66 | [php-osx.liip.ch]: http://php-osx.liip.ch/ 67 | [mac-compile]: http://php.net/install.macosx.compile 68 | [xcode-gcc-substitution]: https://github.com/kennethreitz/osx-gcc-installer 69 | ["Command Line Tools for XCode"]: https://developer.apple.com/downloads 70 | [mamp-downloads]: http://www.mamp.info/en/downloads/ 71 | [xampp]: http://www.apachefriends.org/en/xampp.html 72 | [brew-php-switcher]: https://github.com/philcook/brew-php-switcher 73 | -------------------------------------------------------------------------------- /_posts/01-05-01-Windows-Setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: التنصيب على نظام تشغيل Windows 3 | isChild: true 4 | anchor: windows_setup 5 | --- 6 | 7 | ## التنصيب على نظام تشغيل Windows {#windows_setup_title} 8 | 9 | يمكنك تحميل الملفات التنفيذية من [windows.php.net/download][php-downloads]. 10 | بعد تنصيب PHP يفضل إضافة وضبط مسار التنصيب (المسار الذي يحتوي على ملف php.exe داخله) إلى المتغير العام [PATH][windows-path] حتى تتمكن من تشغيل PHP من أي مكان في النظام. 11 | 12 | لأغراض التعلم والتطوير المحلي يمكنك استخدام الخادم المُدْمج مع PHP 5.4 أو أعلى، حتى لا تحتاج عملية الضبط مع برامج أخرى للخادم. 13 | إذا كنت تفضل «الكل في واحد» وهي برامج تحتوي على كل الحزم التي قد تحتاجها من خادم ويب وخادم قاعدة بيانات بالإضافة لـ PHP، إذاً 14 | فبرامج مثل [Web Platform Installer][wpi]، [XAMPP][xampp]، [EasyPHP][easyphp]، [OpenServer][openserver] ، [WAMP][wamp] 15 | ستساعدك عند تنصيب بيئة تطوير متكاملة بسرعة على نظام تشغيل Windows. الجدير بالذكر أنَّ هذه الأدوات تختلف قليلاً مما هي عليه على خوادم مرحلة التنفيذ النهائية، فيجب عليك توخي الحيطة والحذر ومراعاة الإختلافات ما بين البيئتين. مثلا تقوم بالتطوير على بيئة عمل Windows ويتم التنفيذ في بيئة نهائية Linux. 16 | 17 | إذا كنت تريد تشغيل بيئتك النهائية على نظام تشغيل Windows حينها IIS7 سوف يُوَفِّر لك أداءً عالٍ ومستقرا. 18 | يمكنك استخدام [phpmanager][phpmanager] (إضافة واجهة عمل رسومية لـ IIS7) لإدارة وضبط PHP بكل سهولة. 19 | IIS7 يكون معه FastCGI مدمج وجاهز للاستخدام، كل ما عليك هو ضبط PHP كمعالج (Handler). 20 | للدعم ومصادر أخرى هناك [صفحة مخصصة على iis.net][php-iis] خصيصاً لـPHP. 21 | 22 | بشكل عام تشغيل برامجك على بيئات متعددة في مرحلة التطوير والتنفيذ قد يؤدي لظهور أخطاء ومشاكل مختلفة وغريبة.. 23 | لذلك عندما تقوم بتنصيب بيئة تطوير على Windows ثم تقوم بتنصيبها على بيئة عمل نهائية Linux (أو أي نظام تشغيل آخر) يجب أخذ استخدام [بيئة تشغيل افتراضية](/#virtualization_title) بعين الاعتبار. 24 | 25 | كريس تانكرسلي لديه مقالة ممتازة على مدونته الشخصية للأدوات التي يستخدمها عندما [يقوم بتطوير البرامج على بيئة Windows][windows-tools]. 26 | 27 | [easyphp]: http://www.easyphp.org/ 28 | [phpmanager]: http://phpmanager.codeplex.com/ 29 | [openserver]: http://open-server.ru/ 30 | [wamp]: http://www.wampserver.com/en/ 31 | [php-downloads]: http://windows.php.net/download/ 32 | [php-iis]: http://php.iis.net/ 33 | [windows-path]: http://www.windows-commandline.com/set-path-command-line/ 34 | [windows-tools]: http://ctankersley.com/2015/07/01/developing-on-windows/ 35 | [wpi]: http://www.microsoft.com/web/downloads/platform.aspx 36 | [xampp]: http://www.apachefriends.org/en/xampp.html 37 | -------------------------------------------------------------------------------- /_posts/02-01-01-Code-Style-Guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: دليل أسلوب كتابة الشفرة البرمجية 3 | isChild: false 4 | anchor: code_style_guide 5 | --- 6 | 7 | # دليل أسلوب كتابة الشفرة البرمجية {#code_style_guide_title} 8 | 9 | مجتمع لغة PHP هو مجتمع ضخم ومتنوع، يتألف من عدد لا يعد ولا يحصى من المكتبات، وأطر عمل، و مكونات وعناصر أخرى. 10 | من الشائع أن يختار المطورون عدة خيارات منها ودمجها في مشروع واحد. من المهم أن يتم تقييد الشفرة البرمجية للغة PHP 11 | (قدر الإمكان) بأسلوب برمجي معين لكي يَسْهُل على المطورين التعامل المشترك وفهم محتوى الشفرة البرمجية في مكتبات مشاريعهم. 12 | 13 | قامت [Framework Interop Group][fig] بتقديم وإجازة سلسلة من الأساليب المُوصَى بها. 14 | ليس كل هذه التوصيات هي توصيات تتعلق بأسلوب كتابة الشفرة البرمجية، ولكن تحديداً ما يتعلق منها بأسلوب الكتابة هم: 15 | [PSR-0][psr0]، [PSR-1][psr1]، [PSR-2][psr2]، [PSR-4][psr4]. 16 | هذه التوصيات هي عبارة عن مجموعة من القواعد التي تستعملها مشاريع وتطبيقات كبرى مثل Drupal، Zend، Symfony، Laravel، CakePHP، phpBB، AWS SDK، 17 | FuelPHP، Lithium.. وغيرها. 18 | يمكنك استخدام هذه الأساليب والتوصيات في مشروعك الخاص أو الإستمرار في استخدام أسلوبك الخاص في الكتابة. 19 | 20 | من الأمثل أن تقوم بكتابة شفرة برمجية تتماشى مع مجموعة قواعد قياسية متعارف عليها. ويتم تطبيق هذه القواعد عن طريق دمج الأساليب سابقة الذِّكر PSR أو أساليب أخرى تم اعتمادها من قبل PEAR أو Zend. هذا يعني أنه يمكن لأي مطور آخر أن يقرأ ويفهم عملك نظراً لأن محتواه يخضع لطريقة كتابة معتمدة وتستخدمها كثير من التطبيقات والتطبيقات الفرعية الأخرى التي قد تستخدمها مع مشروعك. 21 | 22 | * [قراءة المزيد عن PSR-0][psr0] 23 | * [قراءة المزيد عن PSR-1][psr1] 24 | * [قراءة المزيد عن PSR-2][psr2] 25 | * [قراءة المزيد عن PSR-4][psr4] 26 | * [قراءة المزيد عن الاسلوب القياسي لـ PEAR][pear-cs] 27 | * [قراءة المزيد عن أسلوب كتابة الشفرة البرمجية في Symfony][symfony-cs] 28 | 29 | يمكنك استخدام أدوات فحص الشفرة البرمجية ومعرفة ما إذا كانت تخضع لأي من التوصيات مثل [PHP_CodeSniffer][phpcs]، وهنالك إضافات 30 | يمكن تنصيبها على محرر النصوص مثل [Sublime Text][st-cs] وتتميز بأنها تتفاعل معك في أثناء الكتابة مباشرة. 31 | 32 | يمكنك إصلاح الشفرة البرمجية وإخضاعها لأحد الأساليب القياسية باستخدام أي من هذه الأدوات: 33 | 34 | - الأول هو [PHP Coding Standards Fixer][phpcsfixer] وهو جيد جداً وتم تجربته ونتائجه ممتازة. 35 | - والآخر هو [PHP Code Beautifier and Fixer][phpcbf] وهي أداة مدمجة مع PHP_CodeSniffer ويمكن استخدامها لتصحيح أسلوب الكتابة من وقت إلى آخر. 36 | 37 | ويمكنك أيضاً تشغيل `phpcs` يدوياً من سطر الأوامر: 38 | 39 | phpcs -sw --standard=PSR2 file.php 40 | 41 | بعد التنفيذ سوف تظهر أخطاء ووصفٌ لكيفية إصلاحها. 42 | أيضاً يمكن الإستفادة من هذا الأمر عبر إضافته كـ git hook بحيث تتحقق من أن جميع الشفرة البرمجية تتبع الأسلوب القياسي وإصلاح الأخطاء حتى يكون بالإمكان إعتمادها في المستودع (Repository). 43 | 44 | إذا كنت تمتلك PHP_CodeSniffer عندها يمكنك تصحيح أسلوب الشفرة البرمجية تلقائياً باستخدام 45 | [PHP Code Beautifier and Fixer][phpcbf]. 46 | 47 | phpcbf -w --standard=PSR2 file.php 48 | 49 | أو عن طريق خيار آخر وهو استخدام [PHP Coding Standards Fixer][phpcsfixer]. 50 | باستخدام هذا الأخير سيقوم بإظهار نوع الأخطاء قبل إصلاحها. 51 | 52 | php-cs-fixer fix -v --level=psr2 file.php 53 | 54 | اللغة الإنجليزية هي المفضلة لكل التسميات والرموز والعلامات وجميع بنية الشفرة البرمجية. 55 | يمكن كتابة الملاحظات بأي لغة يمكن قراءتها من قبل المطورين الحاليين أو المحتملين. 56 | 57 | 58 | [fig]: http://www.php-fig.org/ 59 | [psr0]: http://www.php-fig.org/psr/psr-0/ 60 | [psr1]: http://www.php-fig.org/psr/psr-1/ 61 | [psr2]: http://www.php-fig.org/psr/psr-2/ 62 | [psr4]: http://www.php-fig.org/psr/psr-4/ 63 | [pear-cs]: http://pear.php.net/manual/en/standards.php 64 | [symfony-cs]: http://symfony.com/doc/current/contributing/code/standards.html 65 | [phpcs]: http://pear.php.net/package/PHP_CodeSniffer/ 66 | [phpcbf]: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Fixing-Errors-Automatically 67 | [st-cs]: https://github.com/benmatselby/sublime-phpcs 68 | [phpcsfixer]: http://cs.sensiolabs.org/ 69 | -------------------------------------------------------------------------------- /_posts/03-01-01-Language-Highlights.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: تسليط الضوء على اللغة 3 | isChild: false 4 | anchor: language_highlights 5 | --- 6 | 7 | # تسليط الضوء على اللغة {#language_highlights_title} 8 | -------------------------------------------------------------------------------- /_posts/03-02-01-Programming-Paradigms.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: النماذج البرمجية 3 | isChild: true 4 | anchor: programming_paradigms 5 | --- 6 | 7 | ## النماذج البرمجية {#programming_paradigms_title} 8 | 9 | PHP هي لغة مرنة ومتغيرة حيث أنها تدعم عدة أساليب برمجية. فقد تطورت بشكل ملحوظ خلال السنين الماضية وأضافت البرمجة كائنية 10 | التوجه (Object Oriented) في إصدار PHP 5.0 (سنة 2004) وأضافت الدَّوال المجهولة (anonymous functions) ونطاق التسميات (namespaces) في الإصدار PHP 5.3 (سنة 2009) وأضافت السِّمَات (traits) في إصدار PHP 5.4 (سنة 2012). 11 | 12 | ### البرمجة كائنية التوجه (الشيئية) OOP 13 | 14 | تحتوي PHP على خَوَاصِ البرمجة الكائنية بشكل كامل وذلك يشمل الأصناف (class) والأصناف المجردة (abstract class) والمنافذ (interface) والوراثة (inheritance) والبنائيات (constructor) والاستنساخ (clone) والاستثناء (exception) والمزيد ... 15 | 16 | * [قراءة المزيد عن البرمجة الشيئية OOP PHP][oop] 17 | * [قراءة المزيد عن السِّأمَات Traits][traits] 18 | 19 | ### البرمجة الوظيفية 20 | 21 | تدعم PHP دوال «المستوى الأول»، بمعنى أنه يمكن إسناد دالة إلى متغير. كل من «دوال المستخدم» والدوال المدمجة مع اللغة يمكن إحالتها باستخدام متغيرات ومناداتها بصورة حيوية. يمكن تمرير الدوال كقيم إلى دوال أخرى (خاصية تسمى _الدوال العليا_ _higher-order Functions_) والدوال نفسها بإمكانها إرجاع دوال أخرى! 22 | 23 | الإستدعاء (recursion) الذاتي، وهي خاصية تتيح للدَّالة أن تنادي نفسها، وهي مدعومة من قبل اللغة ولكن معظم الشفرة بلغة PHP تعتمد على التكرار. 24 | 25 | الدوال المجهولة (anonymous functions) خاصية موجودة منذ الإصدار PHP 5.3 (سنة 2009، مع دعم «الإغلاق» closures). 26 | 27 | أضافت PHP 5.4 إمكانية إسناد دوال مجهولة وكائنات مغلقة لنطاق الكائن وقد تم التطوير للإستدعاءات حتى يمكن استخدامها مع كل الدوال في أي حال. 28 | 29 | * أكمل القراءة عن [البرمجة الوظيفية في PHP Functional Programming in PHP](pages/Functional-Programming.html) 30 | * [قراءة المزيد عن الدوال المجهولة Anonymous Functions][anonymous-functions] 31 | * [قراءة المزيد عن الأصناف اللااسمية Closure class][closure-class] 32 | * [قراءة المزيد عن الدوال والكائنات المغلقة أو اللااسمية Closures RFC][closures-rfc] 33 | * [قراءة المزيد عن الدوال القابلة للاستدعاء Callables][callables] 34 | * [قراءة المزيد عن استدعاء الدوال بصورة مجهولة باستخدام الدالة `call_user_func_array()`][call-user-func-array] 35 | 36 | ### البرمجة التحويلية 37 | 38 | تدعم PHP أيضاً عدة أشكال من البرمجة التحويلية (Meta programming) عبر عدة وسائل مثل واجهة برمجة تطبيقات الإنعكاس (reflection API) 39 | والدوال السحرية (Magic Methods). هناك عدة دوال سحرية مثل `__get()`، `__set()`، `__clone()`، `__toString()`، `__invoke()` 40 | وغيرها والتي تتيح للمُطَوِّر ربطها بتصرفات الكائنات. يقول مطورو لغة Ruby أن لغة PHP تفتقر إلى الدالة `method_missing`، ولكنها موجودة 41 | وتتمثل في كل من `__call()` و `__callStatic()`. 42 | 43 | * [قراءة المزيد عن الدوال السحرية Magic Methods][magic-methods] 44 | * [قراءة المزيد عن دوال الإنعكاس Reflection][reflection] 45 | * [قراءة المزيد عن التحميل الإضافي Overloading][overloading] 46 | 47 | 48 | [oop]: http://php.net/language.oop5 49 | [traits]: http://php.net/language.oop5.traits 50 | [anonymous-functions]: http://php.net/functions.anonymous 51 | [closure-class]: http://php.net/class.closure 52 | [closures-rfc]: https://wiki.php.net/rfc/closures 53 | [callables]: http://php.net/language.types.callable 54 | [call-user-func-array]: http://php.net/function.call-user-func-array 55 | [magic-methods]: http://php.net/language.oop5.magic 56 | [reflection]: http://php.net/intro.reflection 57 | [overloading]: http://php.net/language.oop5.overloading 58 | 59 | -------------------------------------------------------------------------------- /_posts/03-03-01-Namespaces.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: فضاءات الاسماء Namespaces 3 | isChild: true 4 | anchor: namespaces 5 | --- 6 | 7 | ## فضاءات الاسماء Namespaces {#namespaces_title} 8 | 9 | قد سبق ذِكْرُ أنَّ مجتمع PHP يحتوي على عدد كبير من المطورين الذين يقومون بتطوير أعداداً ضخمة من البرمجيات. وهذا يعني أنَّ مكتبة واحدة 10 | من برمجية مطورة بلغة PHP قد تستخدم أسماءَ لكائنات مستعملة في مكتبة أخرى، أي قد يحدث تضارب في التَّسْميات. عندما تُستخدم عدة مكاتب في نفس فضاء الاسم (namespace) قد يسبب ذلك (التضارب في التسميات) بعض المشاكل. 11 | 12 | فضاءات الأسماء _Namespaces_ تحل هذه المشكلة. كما هو مُوضحٌ في مرجع لغة PHP، أسماء الفضاءات يمكن تشبيهها بمجلدات النظام حيث يمكن لملفين يحملان نفس الاسم أن يوجدا في مُجلدين مختلفين. كذلك بالنسبة لكائنات PHP فيمكن لكائنين حمل نفس الاسم ولكن يجب لأن يكونا في فضاءين مختلفين. 13 | 14 | فمن المهم أن تستخدم هذه الفضاءات في عملك، بالتحديد إذا كنت تنوي مشاركة هذا العمل مع مطورين آخرين. 15 | فهذا يمنع حدوث التضارب فيما بين المكتبات المتعددة. 16 | 17 | هنالك طريقة موصى بها لاستخدام فضاءات الاسماء وهي مدرجة [PSR-4][psr4]، وتهدف إلى تحديد نمط قياسي لكل ملف وكائن و فضاء اسم لسهولة الاستخدام وإمكانية الإدراج والبدء بالاستخدام المباشر للمكتبات. 18 | 19 | في أكتوبر 20014 PHP-FIG قامت بإهمال وإيقاف العمل بطريقة الإدراج التلقائي القياسية بالرمز [PSR-0][psr0]. كلا الإصدارين [PSR-0][psr0] 20 | و [PSR-4][psr4] ما يزالان صالحين للاستخدام. ولكن الثاني يتطلب إصدار PHP 5.3 لذا العديد من المشاريع المبرمجة على إصدار PHP 5.2 تستخدم PSR-0. 21 | 22 | إذا كنت تنوي استخدام الإستدعاء التلقائي في تطبيقك أو حزمتك، حينها يجب أن تلقي نظرة على التوصية القياسية PSR-4. 23 | 24 | * [قراءة المزيد عن فضاءات الأسماء Namespaces][namespaces] 25 | * [قراءة المزيد عن التوصية القياسية PSR-0][psr0] 26 | * [قراءة المزيد عن التوصية القياسية PSR-4][psr4] 27 | 28 | 29 | [namespaces]: http://php.net/language.namespaces 30 | [psr0]: http://www.php-fig.org/psr/psr-0/ 31 | [psr4]: http://www.php-fig.org/psr/psr-4/ 32 | -------------------------------------------------------------------------------- /_posts/03-04-01-Standard-PHP-Library.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: مكتبة PHP القياسية 3 | isChild: true 4 | anchor: standard_php_library 5 | --- 6 | 7 | ## مكتبة PHP القياسية {#standard_php_library_title} 8 | 9 | مكتبة PHP القياسية (Standard PHP Library إختصارا SPL) هي مكتبة مدمجة مع PHP، توفر مجموعة من الكائنات (classes) والواجهات (interfaces). 10 | صُمِّمت هذه المكتبة لتلبي الإحتياجات الأساسية من كائنات هيكلة البيانات (المكدسات، الصفوف، الأكوام وغيرها)، ودوال تكرار تختصر عمل هيكلة البيانات في كائناتك التي تطبق واجهات المكتبة القياسية. 11 | 12 | * [قراءة المزيد عن المكتبة SPL][spl] 13 | * [دروس فيديو عن مكتبة SPL Lynda.com(مدفوعة)][spllynda] 14 | 15 | 16 | [spl]: http://php.net/book.spl 17 | [spllynda]: http://www.lynda.com/PHP-tutorials/Up-Running-Standard-PHP-Library/175038-2.html 18 | -------------------------------------------------------------------------------- /_posts/03-05-01-Command-Line-Interface.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: واجهة سطور الأوامر 3 | isChild: true 4 | anchor: command_line_interface 5 | --- 6 | 7 | ## واجهة سطور الأوامر {#command_line_interface_title} 8 | 9 | صُمِّمَت لغة PHP لكتابة تطبيقات الويب، ولكن من المفيد أيضاً التعامل مع برامج واجهة سطور الأوامر (CLI). 10 | برامج PHP المبنية للعمل على سطور الأوامر تساعد على أداء مهام معتادة مثل تجربة ونشر وإدارة البرامج بصورة تلقائية. 11 | 12 | تطبيقات PHP التي تعمل على واجهة سطور الأوامر هي برامج قوية لأنها تستخدم مصدر البرنامج مباشرة دون الحاجة لتطوير واجهة ويب مرئية ومَحْمِيَّة. ولكن تأكد من **عدم** وضع تطبيقك الذي يعمل بواجهة سطور الأوامر في مجلد موقعك (حيث يمكن للجميع رؤيته)! 13 | 14 | جرب تشغيل أمر PHP هذا من واجهة سطور الأوامر: 15 | 16 | {% highlight console %} 17 | > php -i 18 | {% endhighlight %} 19 | 20 | يدل خيار `-i` على طباعة بيانات ضبط PHP كما تنفذه دالة [`phpinfo()`][phpinfo] تماماً. 21 | 22 | أيضاً خيار `-a` يوفر أوامر تفاعلية مماثلة لشبيهاتها عند ruby IRB و python interactive shell. هنالك عدد من الأوامر والخيارات المفيدة 23 | التي يمكنك الاطلاع عليها أيضاً [command line options][cli-options]. 24 | 25 | لنقم بتجربة كتابة برنامج ترحيبي سهل بطريقة واجهة سطور الأوامر، قم بإنشاء ملف باسم `hello.php` ثم قم بكتابة الآتي: 26 | 27 | {% highlight php %} 28 | php hello.php 48 | Usage: php hello.php [name] 49 | > php hello.php world 50 | Hello, world 51 | {% endhighlight %} 52 | 53 | 54 | * [لمعرفة المزيد عن تشغيل PHP من واجهة سطور الأوامر][php-cli] 55 | * [تعرف على كيفية ضبط نظام التشغيل Windows لتشغيل PHP من نافذة سطور الأوامر][php-cli-windows] 56 | 57 | 58 | [phpinfo]: http://php.net/function.phpinfo 59 | [cli-options]: http://php.net/features.commandline.options 60 | [argc]: http://php.net/reserved.variables.argc 61 | [argv]: http://php.net/reserved.variables.argv 62 | [exit-codes]: http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits 63 | [php-cli]: http://php.net/features.commandline 64 | [php-cli-windows]: http://php.net/install.windows.commandline 65 | -------------------------------------------------------------------------------- /_posts/03-06-01-XDebug.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: المُصَحِّح Xdebug 3 | isChild: true 4 | anchor: xdebug 5 | --- 6 | 7 | ## المُصَحِّح Xdebug {#xdebug_title} 8 | 9 | أحد أهم أدوات التطوير هو: مَصَحح فعال! فهو يتيح لك تعقب تنفيذ المصدر البرمجي ومراقبة محتواه وتدفق عمليته. 10 | Xdebug هو مُصَحح لغة PHP، يمكن استعماله من خلال بيئة التطوير المتكاملة (IDE) لتوفير نقاط توقف وتعقب التدفق. 11 | أيضاً يتيح لأدوات مثل PHPUnit و KCacheGrind عمل تغطية شاملة على المصدر البرمجي لفحصه وتحليله. 12 | 13 | إذا كنت تلجأ لاستخدام `var_dump()` أو `print_r()`، لكنهما لم تفيان بالغرض، إذا عليك أن تستخدم مُصَححا حينها! 14 | 15 | [تنصيب Xdebug][xdebug-install] قد يكون معَقَّدا بعض الشيء، ولكن واحدة من أهم مميزاته هو التصحيح عن بعد (Remote Debugging)، فإذا كنت تقوم بتطوير برنامجك في بيئة محلية ثم تقوم بتجربته داخل نظام افتراضي أو في خادم آخر عندها التصحيح عن بعد هو الخيار الذي يسهل عليك المتابعة والتصحيح بالطريقة الصحيحة. 16 | 17 | يمكنك تعديل Apache VHost أو ملف .htaccess وإعطاؤه القيم الآتية: 18 | 19 | {% highlight ini %} 20 | php_value xdebug.remote_host 192.168.?.? 21 | php_value xdebug.remote_port 9000 22 | {% endhighlight %} 23 | 24 | كل من "remote host" و"remote port" يعبران عن بيانات جهازك الخاص والمنفذ الذي تتعامل به بيئة التطوير المتكاملة (IDE) للاستماع إليه. 25 | الآن كل ما عليك فعله هو أن تضع برنامج بيئة التطوير IDE لديك على وضعية استماع الإتصالات (Listen for connections Mode) ثم عرض الصفحة باستخدام URL: 26 | 27 | http://your-website.example.com/index.php?XDEBUG_SESSION_START=1 28 | 29 | سوف يعترض برنامج التطوير لديك الحالة الحالية لتنفيذ المصدر، مما يتيح لك أن تضع نقاط توقف والاطلاع ومتابعة القيم في الذاكرة. 30 | 31 | أدوات التصحيح المرئية تسهل استخدامها مع الشفرة، والتحقق من المتغيرات، وتنفيذ الشفرة مباشرة. 32 | العديد من برامج بيئة التطوير IDE لديها إضافة مدمجة تدعم أدوات التصحيح المرئية ومتوافقة مع xDebug. 33 | MacDGBp هو أداة مجانية ومفتوحة المصدر قائمة بذاتها تعمل على نظام التشغيل Mac. 34 | 35 | * [تَعَرَّف على المزيد عن Xdebug][xdebug-docs] 36 | * [تَعَرَّف على المزيد عن MacGDBp][macgdbp-install] 37 | 38 | 39 | [xdebug-install]: http://xdebug.org/docs/install 40 | [xdebug-docs]: http://xdebug.org/docs/ 41 | [macgdbp-install]: http://www.bluestatic.org/software/macgdbp/ 42 | -------------------------------------------------------------------------------- /_posts/04-01-01-Dependency-Management.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: إدارة التوابع 3 | isChild: false 4 | anchor: dependency_management 5 | --- 6 | 7 | # إدارة التوابع {#dependency_management_title} 8 | 9 | لغة البرمجة PHP لديها العديد من المكتبات وأطر العمل والمحتويات التي تستطيع اختيار أحدها. ربما قد تستخدم بعضا منها في عملك أو مشروعك، تلك الإضافات تُسَمَّى توابع المشروع. منذ عهد قريب لم تكن لغة البرمجة PHP تملك طريقة مثلى لإدارة تلك التوابع. حتى إن قمت بإدارتها يدويا، مازلت تحتاج ان تعير انتباهاً لتحميلها آليا (autoloaders). ولكن هذا الأمر لم يعد يشكل مشكلة. 10 | 11 | حتى الآن رائدي أنظمَة إدارة التوابع في لغة البرمجة PHP هما [Composer] و [PEAR]. Composer حالياً هو الأكثر شهرة، لكن لفترة طويلة من الزمن كان PEAR هو النظام الأساسي لإدارة التوابع في PHP. 12 | من الجيد معرفة تفاصيل تاريخ PEAR، لأنه يمكن الرجوع إليها ولو لم تستخدمها.. 13 | 14 | [Composer]: /#composer_and_packagist 15 | [PEAR]: /#pear 16 | -------------------------------------------------------------------------------- /_posts/04-02-01-Composer-and-Packagist.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Composer و Packagist 3 | isChild: false 4 | isChild: true 5 | anchor: composer_and_packagist 6 | --- 7 | 8 | ## Composer و Packagist {#composer_and_packagist_title} 9 | 10 | يعتبر Composer أداة **ممتازة** لإدارة توابع لغة PHP. كل ما عليك هو أن تضع قائمة بالتوابع في ملف `composer.json` وببعض أوامر 11 | سهلة سيقوم Composer بتنزيل كل توابع مشروعك بالإضافة لتنصيب وضبط ملف إدراج تلقائي autoload. 12 | يعتبر Composer مماثل لـ NPM المستخدم في node.js، أو Bundler المستخدم في Ruby. 13 | 14 | يوجد الكثير من مكتبات لغة PHP متوافقة مع Composer وجاهزة للاستخدام مع مشروعك. هذه المكتبات أو «الحزم» مدرجة في [Packagist]، المستودع الحصري لكل مكتبات لغة PHP المتوافقة مع Composer. 15 | 16 | ### كيفية تنصيب Composer 17 | 18 | الطريقة الآمنة لتحميل Composer هي عن طريق [التعليمات الرسمية](https://getcomposer.org/download/). 19 | سيتم التحقق من ملفات التنصيب كونها سليمة ولم يتم التلاعب بها. 20 | يقوم ملف التنصيب بتنصيب Composer *محلياً* في مجلد العمل الحالي. 21 | 22 | ننصح بتنصيبه *للإتاحة العامة* (مثلا نسخة واحدة في `/usr/local/bin`)، للقيام بذلك قم بتنفيذ: 23 | 24 | {% highlight console %} 25 | mv composer.phar /usr/local/bin/composer 26 | {% endhighlight %} 27 | 28 | **ملاحظة:** إذا فشل الأمر السابق بسبب صلاحيات قم بتشغيل الأمر `mv` مرة أخرى بكتابة الأمر `sudo` قبله. 29 | 30 | لتشغيل Composer الذي تم تنصيبه محلياً قم باستخدام `php composer.phar` وعامةً قم باستخدام `composer` فقط. 31 | 32 | #### التنصيب على نظام تشغيل Windows 33 | 34 | بالنسبة لمستخدمي نظام التشغيل Windows الطريقة الأسهل هي استخدام ملف تنصيب [ComposerSetup]، حيث يقوم بتنصيبه بشكل عام على النظام، ويقوم بضبط متغيرات `$PATH` حتى تتمكن من استدعاء الأمر `composer` فقط من شاشة سطور الأوامر من أي مجلد في النظام. 35 | 36 | ### كيفية تنصيب Composer (يدوياً) 37 | 38 | تنصيب Composer يدوياً هو عملية متقدمة، لذلك هناك العديد من الأسباب تجعل المُطَوِّر يقوم باستخدام هذه الطريقة بدلاً عن الطريقة التلقائية التقليدية. فالطريقة التقليدية التلقائية تقوم بفحص إصدار PHP الحالي لتقوم بالتَّأكد من الآتي: 39 | 40 | - توافق إصدار PHP المنصب حالياً. 41 | - هل يمكن تشغيل وتنفيذ ملفات `.phar` بصورة صحيحة. 42 | - التأكد من الصلاحيات على المجلدات. 43 | - التأكد من الملحقات إذا فشل إدراجها. 44 | - التأكد من ملف الضبط `php.ini`. 45 | 46 | في المقابل الطريقة التقليدية لا تقوم بأي من العمليات المذكورة آنفاً، يتوجب عليك أن تقوم ببعض أو كل العمليات يدوياً، لتنصيب Composer يدويا قم بالآتي: 47 | 48 | {% highlight console %} 49 | curl -s https://getcomposer.org/composer.phar -o $HOME/local/bin/composer 50 | chmod +x $HOME/local/bin/composer 51 | {% endhighlight %} 52 | 53 | المجلد `$HOME/local/bin` (أو المجلد الذي تختاره) يجب أن يكون مُدْرَجًا في متغيرات `$PATH`. وهكذا يمكن الوصول إلى الأمر `composer` من أي مكان (في نظام التشغيل). 54 | 55 | عند استخدام طريقة اليدوية ستتغير طريقة الاستخدام التي قد تجدها في بعض المراجع `php composer.phar install` ليكتب بدلاً منها الآتي: 56 | 57 | {% highlight console %} 58 | composer install 59 | {% endhighlight %} 60 | 61 | في القسم التالي سوف نفترض أنك قمت بتنصيب Composer بشكل عام في النظام. 62 | 63 | ### كيفية تحديد وإدراج التوابع 64 | 65 | يقوم Composer بتتبع وإدارة توابع مشروعك عن طريق ملف يسمى `composer.json`. يمكنك إدارة هذا الملف يدوياً باستخدام أي محرر نصوص، أو استخدام Composer لإنجاز هذه العملية. يقوم الأمر `composer require` بإضافة تابع إلى مشروعك، فإذا لم يكن ملف `composer.json` موجوداً سيقوم تلقائياً بإنشائه. 66 | مثال لإدراج مكتبة [Twig] كتابع لمشروعك. 67 | 68 | {% highlight console %} 69 | composer require twig/twig:~1.8 70 | {% endhighlight %} 71 | 72 | عوضاً عن ذلك يمكنك تنفيذ الأمر `composer init` الذي سيساعدك لإنشاء ملف `composer.json` بالكامل ليتناسب مع مشروعك. ويمكنك أيضاً بعد إنشاء ملف `composer.json` أن تُخْبِر Composer بأن يقوم بتحميل وتنصيب التوابع في مجلد `vendor/`. وهذا ينطبق أيضاً على المشاريع والمكتبات التي تقوم بتنزيلها ويوجد معها الملف `composer.json`. 73 | 74 | {% highlight console %} 75 | composer install 76 | {% endhighlight %} 77 | 78 | بعدها، قم بإضافة هذا السطر إلى ملف برنامجك الأساسي، حتى يتمكن من إعلام PHP لتستخدم المدرج التلقائي autoloader التابع لـ Composer ليدرج التوابع لمشروعك. 79 | 80 | {% highlight php %} 81 | pear-channel/Package 59 | 60 | تم برمجة اللاحقة "pear" يدوياً للحد من حدوث تضاربات، فقد تستخدم قناة PEAR نفس الاسم لحزمة أو تابع مختلف للموزع مثلا، عندها اسم القناة القصير (أو العنوان الكامل URL) يُستخدم للإرشاد إلى أي قناة تَتْبَع هذه الحزمة. 61 | 62 | بعد تنصيب هذا التابع أعلاه سيكون متوفرا في مجلد `vendor` ويمكن إدراجه تلقائياً باستخدام Composer autoloader: 63 | 64 | > vendor/pear-pear2.php.net/PEAR2_HTTP_Request/pear2/HTTP/Request.php 65 | 66 | لاستخدام حزمة PEAR هذه قم باستخدامها هكذا: 67 | 68 | {% highlight php %} 69 | format('Y-m-d') . "\n"; 20 | {% endhighlight %} 21 | 22 | يمكن إجراء عمليات حسابية باستخدام DateTime وذلك باستخدام صنف DateInterval. 23 | يحتوي صنف DateTime على دوال مثل `add()` و `sub()` التي تَسْتخدم مُخْرَجات صنف DateInterval كمعطيات. 24 | لا تقم مطلقاً بكتابة دوال للقيام بعمليةِ حسابِ الثواني في اليوم أو حساب الفترة النهارية أو حتى حساب فرق التوقيت الزمني، ولا تقم باستخدام بدائل أخرى بشكل عام. اسْتَخْدِم DateInterval عوضاً عن ذلك. 25 | للقيام بحساب فَرْقِ التاريخ بين تاريخين قم باستخدام الدالة `diff()` فهي تقوم بإرجاع DateInterval وعندها يمكن عرضه واستخدامه بسهولة. 26 | 27 | {% highlight php %} 28 | add(new DateInterval('P1M6D')); 32 | 33 | $diff = $end->diff($start); 34 | echo 'الفرق هو: ' . $diff->format('%m شهر, %d يوم (المجموع: %a يوم)') . "\n"; 35 | // الفرق هو: 1 شهر, 6 يوم (المجموع: 37 يوم) 36 | {% endhighlight %} 37 | 38 | يمكن لكائن DateTime أن يُستخدم لإجراء عملية مقارنة بالطريقة التقليدية باستخدام: 39 | 40 | {% highlight php %} 41 | format('Y-m-d') . ' '; 57 | } 58 | {% endhighlight %} 59 | 60 | من لواحق واجهات البرمجة (API) المشهورة للغة PHP [Carbon](http://carbon.nesbot.com). تقوم بوراثة كل شيء من صنف DateTime، لتَقُوم بتعديل طفيف على الشفرة البرمجية، ولكن بخواص أخرى إضافية تضم ميزة التعريب بالإضافة لعمليات إضافة وطرح التاريخ بصيغ مختلفة مما يعني أنه يمكن اختبار التطبيق باستخدام تاريخ من اختيارك. 61 | 62 | * [Read about DateTime][datetime] 63 | * [Read about date formatting][dateformat] (accepted date format string options) 64 | * [اقرأ المزيد عن DateTime][datetime] 65 | * [اقرأ المزيد عن تنسيق التاريخ][dateformat] (التنسيقات المعتمدة) 66 | 67 | [datetime]: http://php.net/book.datetime 68 | [dateformat]: http://php.net/function.date 69 | -------------------------------------------------------------------------------- /_posts/05-04-01-Design-Patterns.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: نماذج التصميم 3 | isChild: true 4 | anchor: design_patterns 5 | --- 6 | 7 | ## نماذج التصميم {#design_patterns_title} 8 | 9 | عندما تقوم ببناء برنامج من المفيد أن تستخدم الممارسات البرمجية المعروفة أثناء الكتابة، واتباع النماذج المعروفة للهيكلة العامة للمشروع. استخدام هذه النماذج يسهل عملية إدارة المصدر ويسهل على مبرمجين فهم كيفية عمل الأشياء سوياً. 10 | 11 | إذا كنت تستخدم إطار عمل Framework عندها سيكون هيكل مشروعك في إطاره. عندها الكثير من القرارات الهيكلية قد تم اتخاذها لك مسبقاً 12 | ولكن ما يزال عليك أن تختار النماذج المثلى لتتبعها في المصدر الذي تقوم بكتابته لبناء المشروع في هذا الإطار. 13 | إذا كنت لا تستخدم إطار عمل لبناء برنامج يجب عليك أن تجد وتستخدم النماذج المثلى التي تنطبق على نوع وحجم البرنامج الذي تقوم ببنائه. 14 | 15 | * إكمال القراءة عن [نماذج التصميم](pages/Design-Patterns.html) 16 | -------------------------------------------------------------------------------- /_posts/05-05-01-PHP-and-UTF8.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: العمل بترميز UTF-8 3 | isChild: true 4 | anchor: php_and_utf8 5 | --- 6 | 7 | ## العمل بترميز UTF-8 {#php_and_utf8_title} 8 | 9 | _هذا الفصل تم كتابته من قبل [أليكس كابال](https://alexcabal.com/) في [أفضل ممارسات PHP](https://phpbestpractices.org/#utf-8) حيث تم استخدامها كأساس لنصائحنا للعمل بترميز UTF-8_. 10 | 11 | ### كن منتبهاً، دقيقاً ومهتماً بالتفاصيل. فليس هناك طريق واحد. 12 | 13 | حتى الآن لم تقم PHP بدعم ترميز Unicode في مستوياتها الأساسية. هناك طرق للتَّأكد من أن النصوص قد تمت معالجتها بالترميز UTF-8، ولكنها عملية ليست سهلة وتحتاج الكثير من البحث والتنقيب في كل مستويات تطبيق الويب، ابتداءً من HTML إلى SQL وحتى PHP. 14 | سوف نقوم بإيجاز نبذة عن تطبيقات عملية. 15 | 16 | ### UTF-8 على مستوى PHP 17 | 18 | لا تحتاج عمليات النصوص، مثل دمج النصوص وتعيين قيم نصية إلى متغيرات، إلى أي شيء خاص لكي تتبع ترميز UTF-8. 19 | لكن كثيرا من دوال النصوص مثل `strpos()` و`strlen()` تحتاج عناية خاصة. 20 | هذه الدوال عادة ما تكون لها نظيراتها باللاَّحِقة `mb_*` مثلاً: `mb_strpos()` و`mb_strlen()`. هذه الدوال عن طريق إضافة [Multibyte String Extension] وهي مُخَصَّصَة للتعامل مع النصوص بترميز Unicode. 21 | 22 | يجب عليك أن تستخدم دوال `mb_*` كلما أردت التَّعامل مع نص بترميز Unicode. مثلا إذا قمت باستخدام `substr()` على نص بترميز UTF-8 هناك احتمال أَنَّ النتيجة ستحتوي رموزَا مشوَّهة. في هذه الحالة الطريقة الصحيحة هي استخدام دالة تأخذ النصوص متعددة البايت بالإعتبار (Multibyte) `mb_substr()`. 23 | 24 | الصعوبة تَكْمُن في تَذَكُّر استخدام دوال `mb_*` دائماً عوضاً عن الدوال الأصلية. إذا قمت بنسيان ذلك ذات مرة فأي نص بترميز Unicode يكون مهدَّدًا بالتشوه في أي عملية لاحقة قد تطرأ عليه، مما يعني نتائج غير محمودة! 25 | 26 | ليس كل دوال النصوص لديها معالجات في دوال `mb_*`. إذَا لم يكن هناك واحدة توفر لك الاستخدام المطلوب فأنت غير محظوظ! 27 | 28 | يجب استخدام الدَّالة `mb_internal_encoding()` في بداية كل مصدر PHP تقوم بكتابته (كملف الإستدعاء الرئيس لبقية الملفات مثلاً)، 29 | تليها دالة `mb_http_output()` إذا كنت ستقوم بطباعة نص على المتصفح. 30 | تعيين الترميز بشكل صريح في كل نصوصك يَقِيك الكثير مِمَّا لا تُحمد عقباه خلال عملية التطوير. 31 | 32 | إضافةً إلى ذلك هناك العديد من الدوال المدمجة تتيح إدارة النصوص عبر معطيات اختيارية لتحديد ترميز النصوص. عندها يجب عليك تحديد 33 | UTF-8 عندما يكون هذا الخيار متاحاً. مثلا دالة `htmlentities()` لديها معطى اختياري لتحديد الترميز، سيتوجب عليك دائما تحديد 34 | ترميز UTF-8 للتعامل مع النصوص. 35 | ملاحظة: `htmlentities()` و`htmlspecialchars()` تستخدمان الترميز UTF-8 كترميز نصوص افتراضي منذ إصدار PHP 5.4.0. 36 | 37 | أخيراً، إذا كنت تقوم ببناء تطبيق تنوي نشره وكنت غير متأكد من أن إضافة `mbstring` ستكون متوفرة أم لا، يجب عليك التفكير في استخدام حزمة Composer تسمى [patchwork/utf8]. ستقوم هذه الحزمة بإتاحة استخدام `mbstring` إذا كانت متوفرة، أو تقوم باستخدام الدوال الإفتراضية إذا لم تكن الأخرى متوفرة. 38 | 39 | [Multibyte String Extension]: http://php.net/book.mbstring 40 | [patchwork/utf8]: https://packagist.org/packages/patchwork/utf8 41 | 42 | ### UTF-8 على مستوى قاعدة البيانات 43 | 44 | إذا كان تطبيقك يقوم بالوصول إلى قاعدة البيانات MySQL، عندها هناك احتمال أنَّ النصوص تُحفظ بترميز غير UTF-8 في قاعدة البيانات 45 | حتى ولو اتبعت كل التحذيرات أعلاه! 46 | 47 | لكي تكون متأكداً من أن النصوص تُنتقل من PHP إلى MySQL بترميز UTF-8، تَأَكَّد من أن جميع الجداول في قاعدة البيانات قد تم ضبط ترميزها لتسخدم الترميز `utf8mb4` في كل من الترميز والترتيب (Character set and Collation)، وأن تقوم باستخدام `utf8mb4` عند الاتصال باستخدام PDO، قم بالإطلاع على المثال أدناه فهو _هام جدا_. 48 | 49 | ملاحظة: يجب استخدام ترميز `utf8mb4` لدعمِ كاملِ لترميز UTF-8 وليس الترميز `utf8`! أكمل القراءة لمعرفة السبب. 50 | 51 | ### UTF-8 على مستوى المتصفح 52 | 53 | استخدم الدَّالة `mb_http_output()` للتَّأكد من أن تطبيقك يطبع نصوصا بترميز UTF-8 على المتصفح. 54 | 55 | سيلزم عندها إخبار المتصفح -باستخدام HTTP Response- أن هذه الصفحة يجب أن تعتبر مُرَمَّزة باستخدام UTF-8. 56 | سابقاً كان يتم إدراج هذا الإجراء عن طريق إدراج [charset في وسم ``](http://htmlpurifier.org/docs/enduser-utf8.html) 57 | بداخل وسم `` في الصفحة. هذا الإجراء سليم تماماً ولكن إضافة `Content-Type` كترويسة (header) هو عملياً [أكثر سرعة](https://developers.google.com/speed/docs/best-practices/rendering#SpecifyCharsetEarly). 58 | 59 | {% highlight php %} 60 | PDO::ERRMODE_EXCEPTION, 83 | PDO::ATTR_PERSISTENT => false 84 | ) 85 | ); 86 | 87 | // قم بتخزين النص المُحَوَّل بترميز UTF-8 في قاعدة البيانات 88 | // هل قاعدة البيانات والجداول تستخدم ترميز وترتيب `utf8mb4` Charset and collation؟ 89 | $handle = $link->prepare('insert into ElvishSentences (Id, Body) values (?, ?)'); 90 | $handle->bindValue(1, 1, PDO::PARAM_INT); 91 | $handle->bindValue(2, $string); 92 | $handle->execute(); 93 | 94 | // قم باسترجاع النص الذي قمنا بتخزينه حتى يتم إثبات أنه قد تم تخزينه بطريقة صحيحة 95 | $handle = $link->prepare('select * from ElvishSentences where Id = ?'); 96 | $handle->bindValue(1, 1, PDO::PARAM_INT); 97 | $handle->execute(); 98 | 99 | // قم بتخزين النتيجة إلى كائن حتى نتمكن من طباعته لاحقاً في HTML 100 | $result = $handle->fetchAll(\PDO::FETCH_OBJ); 101 | 102 | header('Content-Type: text/html; charset=UTF-8'); 103 | ?> 104 | 105 | 106 | 107 | 108 | UTF-8 صفحة تجريبية 109 | 110 | 111 | Body); // يجب أن يتم طباعة هذا النص المُحَوَّل بترميز UTF-8 بصور صحيحة في المتصفح 114 | } 115 | ?> 116 | 117 | 118 | {% endhighlight %} 119 | 120 | ### لمزيد من المصادر 121 | 122 | * [PHP Manual: String Operations](http://php.net/language.operators.string) 123 | * [PHP Manual: String Functions](http://php.net/ref.strings) 124 | * [`strpos()`](http://php.net/function.strpos) 125 | * [`strlen()`](http://php.net/function.strlen) 126 | * [`substr()`](http://php.net/function.substr) 127 | * [PHP Manual: Multibyte String Functions](http://php.net/ref.mbstring) 128 | * [`mb_strpos()`](http://php.net/function.mb-strpos) 129 | * [`mb_strlen()`](http://php.net/function.mb-strlen) 130 | * [`mb_substr()`](http://php.net/function.mb-substr) 131 | * [`mb_internal_encoding()`](http://php.net/function.mb-internal-encoding) 132 | * [`mb_http_output()`](http://php.net/function.mb-http-output) 133 | * [`htmlentities()`](http://php.net/function.htmlentities) 134 | * [`htmlspecialchars()`](http://php.net/function.htmlspecialchars) 135 | * [PHP UTF-8 Cheatsheet](http://blog.loftdigital.com/blog/php-utf-8-cheatsheet) 136 | * [Handling UTF-8 with PHP](http://www.phpwact.org/php/i18n/utf-8) 137 | * [Stack Overflow: What factors make PHP Unicode-incompatible?](http://stackoverflow.com/questions/571694/what-factors-make-php-unicode-incompatible) 138 | * [Stack Overflow: Best practices in PHP and MySQL with international strings](http://stackoverflow.com/questions/140728/best-practices-in-php-and-mysql-with-international-strings) 139 | * [How to support full Unicode in MySQL databases](http://mathiasbynens.be/notes/mysql-utf8mb4) 140 | * [Bringing Unicode to PHP with Portable UTF-8](http://www.sitepoint.com/bringing-unicode-to-php-with-portable-utf8/) 141 | * [Stack Overflow: DOMDocument loadHTML does not encode UTF-8 correctly](http://stackoverflow.com/questions/8218230/php-domdocument-loadhtml-not-encoding-utf-8-correctly) 142 | -------------------------------------------------------------------------------- /_posts/06-01-01-Dependency-Injection.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: حقن التوابع Dependency Injection 3 | anchor: dependency_injection 4 | --- 5 | 6 | # حقن التوابع Dependency Injection {#dependency_injection_title} 7 | 8 | مقتبس من ويكيبيديا الإنجليزية [Wikipedia](http://en.wikipedia.org/wiki/Dependency_injection): 9 | 10 | >حقن التوابع هو تصميم نموذجي برمجي يتيح إزالة التوابع المكتوبة صراحةً ثم جعلها متوفرة للتغيير سواء كان ذلك في مرحلة 11 | >التشغيل أو في مرحلة البناء. 12 | 13 | هذا الإقتباس يجعل هذا المفهوم مُعَقَّدا أكثر مما هو عليه فعلا. عملية حقن تابع هو تجهيز محتوياته وتوابعه سواء باستخدام حقن عند الإنشاء أو تنفيذ الدوال أو في الضبط. إنه بهذه السهولة. 14 | -------------------------------------------------------------------------------- /_posts/06-02-01-Basic-Concept.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: المفهوم الأساسي 3 | isChild: true 4 | anchor: basic_concept 5 | --- 6 | 7 | ## المفهوم الأساسي {#basic_concept_title} 8 | 9 | يمكن شرح هذا المفهوم باستخدام مثال سَهْل. 10 | 11 | لدينا صنف `Database` يعتمد على مُحول للتخاطب مع قاعدة البيانات. نقوم بإنشاء المحول في دالة الإنشاء ثم نقوم بحقن ثابت. 12 | هذا يجعل عملية التجربة والإختبار عملية صعبة مما يعني أن الصنف `Database` مرتبط بشدة مع المحول. 13 | 14 | {% highlight php %} 15 | adapter = new MySqlAdapter; 25 | } 26 | } 27 | 28 | class MysqlAdapter {} 29 | {% endhighlight %} 30 | 31 | يمكن إعادة صياغة هذه الشفرة البرمجية لاستخدام حقن التوابع وفك الإرتباط من التوابع: 32 | 33 | {% highlight php %} 34 | adapter = $adapter; 44 | } 45 | } 46 | 47 | class MysqlAdapter {} 48 | {% endhighlight %} 49 | 50 | الآن يمكننا أن نعطي صنف `Database` توابعه عن طريق إنشائها بنفسه. ويمكن أيضاً إنشاء دالة تستقبل التابع كقيمة ثم إسنادها مباشرة، أو إذا كان المحول `$adapter` في وصف عام `public property` عندها يمكن إسناده مباشرةً. 51 | -------------------------------------------------------------------------------- /_posts/06-03-01-Complex-Problem.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: مشكلة معقدة 3 | isChild: true 4 | anchor: complex_problem 5 | --- 6 | 7 | ## مشكلة معقدة {#complex_problem_title} 8 | 9 | إذا كنت قرأت عن حقن التوابع سابقاً قد يكون لفت انتباهك مصطلح *"Inversion of Control"* انعكاس التحكم أو *"Dependency Inversion Principle"* مفهوم عكس تحكم التوابع. 10 | هذه المشاكل المعقدة هي ما يقوم حقن التوابع بحلها. 11 | 12 | ### انعكاس التحكم 13 | 14 | انعكاس التحكم كما يدل عليها الاسم هو إبقاء التحكم التنظيمي بالكامل بمنئى عن العناصر أو الكائنات. في مصطلح حقن التوابع هذا يعني فك الإرتباط مع التوابع وعكس التحكم بهذه التوابع في مكان آخر في النظام. 15 | 16 | طوال عدة سنين، أطر النظام في PHP تستخدم عكس التحكم، ولكن يبقى السؤال: أي جزء من التحكم هو الذي تقوم بعكسه؟ وإلى أين؟ 17 | مثلا أطر العمل بنموذج MVC تقدم بشكل عام كائن أساسي أو متحكم أساسي يجب على المتحكمات الفرعية الأخرى أن تستمد منه لكي تحصل على وصول لتوابعه. 18 | هذا **هو** عكس التحكم، لكن عوضاً عن فك ارتباط التوابع هذه الطريقة تقوم بترحيلهم. 19 | 20 | حقن التوابع يتيح لنا حل هذه المشكلة بسلاسة عن طريق حقن التوابع التي نريد عند الحاجة، دون الحاجة لأي كتابة صريحة لأي تابع في المصدر على الإطلاق. 21 | 22 | ### مفهوم عكس التحكم 23 | 24 | مفهوم عكس التحكم هو حرف "D" في مجموعة مفاهيم البرمجة الشيئية S.O.L.I.D وينص على أنه يجب *"الإعتماد على التجريد، لا على التحجير أو الإنغلاق"*. هذا يعني أن التوابع يجب أن تكون واجهات أو مجردات عوضاً عن التطبيقات الجامدة أو المحجرة. عندها 25 | يمكننا إعادة صياغة وكتابة المفهوم أعلاه بسهولة: 26 | 27 | {% highlight php %} 28 | adapter = $adapter; 38 | } 39 | } 40 | 41 | interface AdapterInterface {} 42 | 43 | class MysqlAdapter implements AdapterInterface {} 44 | {% endhighlight %} 45 | 46 | هنالك عدة فوائد يستفيد منها صنف `Database` الآن، فهوالآن يعتمد على واجهة بدلاً من كائن جامد. 47 | 48 | ضع بالإعتبار أنك تعمل ضمن فريق وأن أحد الزملاء يقوم بالعمل على المحول. في المثال الأول يجب أن نقوم بانتظار زميلنا حتى يخبرنا بأنه قد انتهى من المحول حتى يتسنى لنا الاعتماد عليه في إختبار الوحدة. الآن التابع هو عبارة عن واجهة يمكننا أن 49 | نعتمد عليها باعتبار أن زميلنا سيقوم ببناء المحول وفق الواجهة المحددة. 50 | 51 | فائدة أكبر وهي أن هذه الطريقة تجعل المصدر قابل للتطوير. فمثلا بعد سنة قررنا أن نقوم بالترحيل إلى نوع آخر من قواعد البيانات، يمكن أن نقوم بكاتبة محول يتبع شروط الواجهة الأصلية ثم يحقن عوضاً عنه. عندها لا يوجد تعديل أو إعادة صياغة ويمكن أن نجزم بأن ذلك 52 | المحول الجديد يتبع الشروط الموضوعة من قبل الواجهة. 53 | -------------------------------------------------------------------------------- /_posts/06-04-01-Containers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: الحاويات Containers 3 | isChild: true 4 | anchor: containers 5 | --- 6 | 7 | ## الحاويات Containers {#containers_title} 8 | 9 | أول شيء يجب أن تفهمه عن حاويات حقن التوابع هو أنها تختلف عن عملية حقن التوابع. الحاوية هي أداة تسهيلية تساعدنا في بناء حقن توابع، ولكن يمكن أن يساء ٱستخدامها لبناء (ضد النمذجة) تحديد للخدمة. حقن تابع بصفته محدد خدمة في الصنف يقوم بإنشاء ٱرتباط أقوى للتوابع في داخل الحاوية بدلاً من التابع الذي تستبدله. 10 | وتقوم بتعقيد المصدر مما يجعل تجربته صعبة. 11 | 12 | معظم أطر العمل الحديثة تقوم بٱستخدام حاويات حقن التوابع بحيث تتيح لك كتابة توابعك جميعها عن طريق الضبط. 13 | ما يعني أن هذه الممارسة تمكنك من كتابة مصدر نظيف وغير مرتبط كإطار العمل الذي بُـني عليه. 14 | -------------------------------------------------------------------------------- /_posts/06-05-01-Further-Reading.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: اقرأ المزيد 3 | isChild: true 4 | anchor: further_reading 5 | --- 6 | 7 | ## اقرأ المزيد {#further_reading_title} 8 | 9 | * [Learning about Dependency Injection and PHP](http://ralphschindler.com/2011/05/18/learning-about-dependency-injection-and-php) 10 | * [What is Dependency Injection?](http://fabien.potencier.org/article/11/what-is-dependency-injection) 11 | * [Dependency Injection: An analogy](https://mwop.net/blog/260-Dependency-Injection-An-analogy.html) 12 | * [Dependency Injection: Huh?](http://net.tutsplus.com/tutorials/php/dependency-injection-huh/) 13 | * [Dependency Injection as a tool for testing](http://philipobenito.github.io/dependency-injection-as-a-tool-for-testing/) 14 | -------------------------------------------------------------------------------- /_posts/07-01-01-Databases.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: قواعد البيانات 3 | anchor: databases 4 | --- 5 | 6 | # قواعد البيانات {#databases_title} 7 | 8 | عادةً ما تقوم بٱستخدام قاعدة بيانات لبرنامجك لتخزين المعلومات. لديك خيارات محدودة للٱتصال والتعامل مع قاعدة البيانات. 9 | الطريقة المستحسنة **حتى إصدار PHP 5.1.0** هي ٱستخدام لاحقات التشغيل المدمجة مثل [mysqli] و [pgsql] و [mssql] ... ألخ. 10 | 11 | لاحقات التشغيل المدمجة ممتازة إذا كنت تستخدم _قاعدة بيانات واحدة_ في برنامجك، ولكن مثلاً إذا كنت تستخدم MySQL والقليل من MSSQL، أو ربما تريد أن تتصل مع قاعدة بيانات أوراكل، عندها لن تتمكن من ٱستخدام نفس تلك اللواحق. 12 | سوف تحتاج لتعلم طريقة API جديدة لكل لاحقة قاعدة بيانات — وهذا شيء مجهد. 13 | 14 | 15 | [mysqli]: http://php.net/mysqli 16 | [pgsql]: http://php.net/pgsql 17 | [mssql]: http://php.net/mssql 18 | -------------------------------------------------------------------------------- /_posts/07-02-01-Databases_MySQL.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: لاحقة MySQL 3 | isChild: true 4 | anchor: mysql_extension 5 | --- 6 | 7 | ## لاحقة MySQL {#mysql_extension_title} 8 | 9 | لاحقة [mysql] هي لاحقة مدمجة في PHP وقد باتت قديمة وتم الٱستغناء عنها وٱستبدالها بلاحقتين أخريين: 10 | 11 | - [mysqli] 12 | - [pdo] 13 | 14 | لم يتوقف التطوير على اللاحقة [mysql] منذ زمن بعيد فحسب، بل وقد تم [إهمالها منذ إصدار PHP 5.5.0][mysql_deprecated] 15 | ثم تم **إزالتها [حصرياً في أول إصدار من PHP 7.0][mysql_removed]** 16 | 17 | لمعرفة ما إذا كان تطبيق ما يعمل بهذه اللاحقة يمكنك البحث باستخدام محرر النصوص لديك عن دوال مثل `mysql_connect()` و`mysql_query` فإذا ظهرت نتائج بحث إيجابية فهذا يعني أن هذه اللاحقة مستخدمة في التطبيق. وهذا عوضاً عن البحث في ملف 18 | `php.ini` للتحقق من وجود اللاحقة. 19 | 20 | حتى وإن لم تكن تستخدم إصدار PHP 7.x بعد، عدم الٱهتمام بالتحديث في أقرب فرصة يزيد صعوبة المهمة عندما تحدث الترقية. 21 | أفضل حل هو ٱستبدال ٱستخدام mysql بأي من [mysqli] أو [PDO] في تطبيقاتك كممارسة أساسية في عملية التطوير حتى لا تضطر لتنفيذها على عجالة في وقت لاحق. 22 | 23 | **إذا كنت تنوي الترقية من [mysql] إلى [mysqli]، هنالك موجهات سهلة تقترح عليك بأن تقوم بالبحث عن `mysql_*` واستبدالها بـ `mysqli_*`. هذا المقترح مفرط السهولة، ولكنه يفقد العديد من فوائد وخواص تقدمها mysqli مثل ربط القيم، وهي متوفرة أيضاً في [PDO][pdo].** 24 | 25 | * [PHP: Choosing an API for MySQL][mysql_api] 26 | * [PDO Tutorial for MySQL Developers][pdo4mysql_devs] 27 | 28 | [mysql]: http://php.net/mysql 29 | [mysql_deprecated]: http://php.net/migration55.deprecated 30 | [mysql_removed]: http://php.net/manual/en/migration70.removed-exts-sapis.php 31 | [mysqli]: http://php.net/mysqli 32 | [pdo]: http://php.net/pdo 33 | [mysql_api]: http://php.net/mysqlinfo.api.choosing 34 | [pdo4mysql_devs]: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers 35 | -------------------------------------------------------------------------------- /_posts/07-03-01-Databases_PDO.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: لاحقة PDO 3 | isChild: true 4 | anchor: pdo_extension 5 | --- 6 | 7 | ## لاحقة PDO {#pdo_extension_title} 8 | 9 | تعتبر [PDO] مكتبة مجردة للٱتصال بقاعدة البيانات — تم بنائها في PHP منذ الإصدار 5.1.0 — بحيث توفر واجهات ٱتصال عادية للعديد من قواعد البيانات المختلفة. مثلا يمكن ٱستخدام نفس الشفرة المصدرية للٱتصال والعمل بقاعدة بيانات MySQL أو SQLite: 10 | 11 | {% highlight php %} 12 | query("SELECT some_field FROM some_table"); 16 | $row = $statement->fetch(PDO::FETCH_ASSOC); 17 | echo htmlentities($row['some_field']); 18 | 19 | // PDO + SQLite 20 | $pdo = new PDO('sqlite:/path/db/foo.sqlite'); 21 | $statement = $pdo->query("SELECT some_field FROM some_table"); 22 | $row = $statement->fetch(PDO::FETCH_ASSOC); 23 | echo htmlentities($row['some_field']); 24 | {% endhighlight %} 25 | 26 | لا تقوم PDO بترجمة أو تحويل الٱستعلامات SQL Queries أو مماثلة الخصائص المفقودة، ولكنها بالفعل تتصل بأكثر من نوع من قواعد البيانات بنفس الوجهة البرمجية API. 27 | 28 | للأهمية: `PDO` تتيح بسهولة حقن مدخلات خارجية (كالمفاتح ID مثلا) في ٱستعلام SQL Query من دون القلق بشأن تهديدات SQL Injection. 29 | وهذا ممكن بٱستخدام جمل PDO وتقييد وربط القيم PDO Statements. 30 | 31 | فلنفترض أن في مصدر PHP نقوم بٱستقبال مفتاح رقمي ID وهو عبارة عن قيمة في ٱستعلام. هذا المفتاح يجب أن يستخدم لٱستخراج بيانات مستخدم من قاعدة البيانات. الطريقة التالية هي الطريقة `الخاطئة` للقيام بهذه العملية: 32 | 33 | {% highlight php %} 34 | query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- خطأ! 37 | {% endhighlight %} 38 | 39 | هذا مصدر خاطئ تماماً. فهو يقوم بإدخال قيم خام إلى ٱستعلام SQL. مما يسبب تَعَرُّضك للٱختراق بسهولة باستخدام أسلوب حقن الٱستعلام [SQL Injection]. تصور أن مخترقا قام بإرسال قيمة `ID` عن طريق تنفيذ عنوان مثل `http://domain.com/?id=1%3BDELETE+FROM+users`. 40 | سوف يقوم بإسناد للمتغير `$_GET['id']` القيمة `1;DELETE FROM users` مما يتسبب بحذف جميع سجلات المستخدمين! 41 | عوضاً عن ذلك يجب أن تقوم (بتعقيم) المفتاح ID المدخل بٱستخدام جمل التقييد في PDO. 42 | 43 | {% highlight php %} 44 | prepare('SELECT name FROM users WHERE id = :id'); 47 | $id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT); // <-- قم بترشيح بياناتك أولاً (أنظر [ترشيح البيانات](#data_filtering))، مهم جداً خصوصاً لعمليتي INSERT و UPDATE.. 48 | $stmt->bindParam(':id', $id, PDO::PARAM_INT); // <-- تلقائياً يتم تعقيم القيم بٱستخدام PDO 49 | $stmt->execute(); 50 | {% endhighlight %} 51 | 52 | وهذا مصدر صحيح. يتم ٱستخدام تقييد القيم في جملة PDO. فبدورها تقوم تلقائياً بتعقيم المدخل ID قبل أن تقوم بإدراجه لقاعدة البيانات مما يمنع ٱحتمال هجمات SQL Injection. 53 | 54 | عند كتابة عمليات مثل INSERT أو UPDATE، يجب (للأهمية القصوى) أن تقوم [بترشيح البيانات](#data_filtering) أولاً ثم بتعقيمها من العناصر الأخرى مثل (حذف أوسم HTML و JavaScript وغيرها..). سيقوم PDO فقط بتعقيم المدخلات لٱستخدامها في SQL وليس لكي تستخدمها أنت في تطبيقك. 55 | 56 | * [تعرف على المزيد عن PDO] 57 | 58 | يجب عليك أن تكون على دراية بأن ٱتصال قاعدة البيانات يقوم بٱستخدام مصادر وأنه ليس من الغريب ٱستهلاك هذه المصادر بسبب تلك الٱتصالات التي لم تغلق، ولكن هذا شيء معتاد في الكثير من لغات البرمجة الأخرى. بٱستخدام PDO يمكنك إغلاق الٱتصال فقط بحذف الكائن وذلك للتأكد من أن كل الٱرتباطات قد تم حذفها. مثلاً إسنادها للقيم الفارغة NULL. إذا لم تقم بهذا يدوياً فسوف تقوم PHP تلقائياً بإغلاق هذه الٱتصالات عندما يتم تنفيذ المصدر إلا إذا كنت تستخدم ٱتصالات مستمرة بالطبع. 59 | 60 | * [تعرف على المزيد عن ٱتصالات PDO] 61 | [pdo]: http://php.net/pdo 62 | [SQL Injection]: http://wiki.hashphp.org/Validation 63 | [Learn about PDO]: http://php.net/book.pdo 64 | [Learn about PDO connections]: http://php.net/pdo.connections 65 | -------------------------------------------------------------------------------- /_posts/07-04-01-Interacting-via-Code.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: التفاعل مع قواعد البيانات 3 | isChild: true 4 | anchor: databases_interacting 5 | --- 6 | 7 | ## التفاعل مع قواعد البيانات {#databases_interacting_title} 8 | 9 | عندما يبدأ المطورون تَعَلُّم لغة البرمجة PHP للمرة الأولى، عادة ما يقومون بدمج عمليات قواعد البيانات مع الطرح المنطقي، بكتابة مصدر كهذا: 10 | 11 | {% highlight php %} 12 |
    13 | query('SELECT * FROM table') as $row) { 15 | echo "
  • ".$row['field1']." - ".$row['field1']."
  • "; 16 | } 17 | ?> 18 |
19 | {% endhighlight %} 20 | 21 | هذه ممارسة سيئة من كل النواحي، فهي صعبة الفحص وتصحيح الأخطاء، وصعبة التجربة، وصعبة القراءة وستقوم أيضاً بإخراج العديد من الحقول التي لم تقم بعمل حد لها. 22 | 23 | هنالك العديد من الحلول - سواء كنت تفضل ٱستخدام البرمجة الشيئية [OOP](#object-oriented-programming) أو البرمجة الوظيفية [Functional Programming](#functional-programming)- ما يزال يتوجب عليك أن تقوم بالفصل. 24 | 25 | مثال لطريقة بدائية: 26 | 27 | {% highlight php %} 28 | query('SELECT * FROM table'); 31 | } 32 | 33 | foreach (getAllFoos($db) as $row) { 34 | echo "
  • ".$row['field1']." - ".$row['field1']."
  • "; // خطأ!! 35 | } 36 | {% endhighlight %} 37 | 38 | هذه بداية جيدة. قم بوضع كل منهما في ملفين مختلفين عندها تحصل على عملية فصل نظيفة. 39 | 40 | قم بإنشاء صنف عوضاً عن تلك الطريقة عندها سيكون لديك نموذج "Model". قم بإنشاء ملف `.php` ثم ضع فيه محتوى العرض المنطقي، عندها سيكون لديك العرض "View"، ستلاحظ أنه قريب من نموذج [MVC] - طريقة معتادة في معمارية البرمجة الشيئية لأغلبية أطر العمل [frameworks](/#frameworks). 41 | 42 | **foo.php** 43 | 44 | {% highlight php %} 45 | getAllFoos(); 55 | 56 | // قم بإدراج العرض View 57 | include 'views/foo-list.php'; 58 | {% endhighlight %} 59 | 60 | 61 | **models/FooModel.php** 62 | 63 | {% highlight php %} 64 | db = $db; 72 | } 73 | 74 | public function getAllFoos() { 75 | return $this->db->query('SELECT * FROM table'); 76 | } 77 | } 78 | {% endhighlight %} 79 | 80 | **views/foo-list.php** 81 | 82 | {% highlight php %} 83 | 84 | - 85 | 86 | {% endhighlight %} 87 | 88 | هذا التطبيق هو مماثل جداً لمعظم ما تقوم به أطر العمل الحديثة، ولو تشببها قليلا. 89 | قد لا تحتاج أن تقوم بهذه الممارسة في كل مرة، ولكن خلط العرض المنطقي والنموذج التفاعلي لقاعدة البيانات من شأنه أن يُكَوِن مشكلة حقيقية إذا ما أردت أن تقوم بٱختبار وحدات [unit-test](#unit-testing) لتطبيقك. 90 | 91 | هنالك مصدر في موقع [PHPBridge] يسمى إنشاء صنف بيانات [Creating a Data Class] يقوم بتغطية جميع المواضيع المشابهة، من الجيد للمطورين بأن يتعودوا على مفهوم التفاعل مع قواعد البيانات. 92 | 93 | 94 | [MVC]: http://code.tutsplus.com/tutorials/mvc-for-noobs--net-10488 95 | [PHPBridge]: http://phpbridge.org/ 96 | [Creating a Data Class]: http://phpbridge.org/intro-to-php/creating_a_data_class 97 | -------------------------------------------------------------------------------- /_posts/07-05-01-Abstraction-Layers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: طبقات التجريد 3 | isChild: true 4 | anchor: databases_abstraction_layers 5 | --- 6 | 7 | ## طبقات التجريد {#databases_abstraction_layers_title} 8 | 9 | العديد من أطر العمل لديها طبقات التجريد الخاصة بها مما قد يجعلها تكون فوق طبقة أو لا [PDO][1]. 10 | غالباً ما يتم محاكاة خواص لنظام قاعدة بيانات مفقودة في الأخرى عن طريق ربط الٱستعلامات في دوال PHP، وتعطيك نفس التجريد لقاعدة البيانات عوضاً عن مجرد ٱتصال تجريدي كما تفعل PDO. بالطبع سوف هذه الممارسة تحتاج قليلا من الجهد، ولكن إذا كنت تنوي بناء نظام متنقل يمكنه العمل على كل من MySQL و PostgreSQL و SQLite عندها ستقوم بالقليل من الجهد وكتابة بضع السطور البرمجية. 11 | 12 | بعض طبقات التجريد تم بنائها بٱستخدام التوصية [PSR-0][psr0] أو [PSR-4][psr4] بأسماء فضاء قياسية حتى تتمكن من تنصيب أي تطبيق تريد، مثل: 13 | 14 | * [Aura SQL][6] 15 | * [Doctrine2 DBAL][2] 16 | * [Propel][7] 17 | * [Zend-db][4] 18 | 19 | 20 | [1]: http://php.net/book.pdo 21 | [2]: http://www.doctrine-project.org/projects/dbal.html 22 | [4]: https://packages.zendframework.com/docs/latest/manual/en/index.html#zendframework/zend-db 23 | [6]: https://github.com/auraphp/Aura.Sql 24 | [7]: http://propelorm.org/ 25 | [psr0]: http://www.php-fig.org/psr/psr-0/ 26 | [psr4]: http://www.php-fig.org/psr/psr-4/ 27 | -------------------------------------------------------------------------------- /_posts/08-01-01-Templating.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: النمذجة Templating 3 | isChild: false 4 | anchor: templating 5 | --- 6 | 7 | # النمذجة Templating {#templating_title} 8 | 9 | توفر النمذجة طريقة مناسبة لفصل التحكم المنطقي من العرض المنطقي. 10 | تحتوي النماذج على HTML لتطبيقك، وقد تستخدم صيغ أخرى مثل XML. 11 | عادة ما تسمى النماذج بالعرض (أو "views") فهي تمثل المكون الثاني من النموذج المعماري للبرمجة الكائنية (MVC) [model–view–controller](pages/Design-Patterns.html#model-view-controller). 12 | -------------------------------------------------------------------------------- /_posts/08-02-01-Benefits.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: الفوائد 3 | isChild: true 4 | anchor: templating_benefits 5 | --- 6 | 7 | ## الفوائد {#templating_benefits_title} 8 | 9 | تكمن الفائدة الأساسية لٱستخدام النماذج في إنشاء فصل «نظيف» بين العرض المنطقي وبقية البرنامج. 10 | تكون مسؤولية النماذج الوحيدة هي عرض محتوى مهيء. ولا تحمل أي مسؤولية تنفيذ ٱستخراج بيانات أو عمل مهام معقدة. مما يؤدي إلى مصدر شفرة سهل القراءة ومفيدا خاصة في بيئة العمل في فريق عندها يقوم المطورون بكتابة المصدر البرمجي للعمليات التي 11 | تنفذ على الخادم server-side (Controller و Models) ويقوم المصممون بالعمل على جانب العميل client-side. 12 | 13 | تقوم النماذج أيضا بتطوير تنظيم شكل ومصدر العرض المنطقي. فالنماذج توضع في مجلد العرض ("Views") كلٌ محدد بملف واحد. هذا الأسلوب يساعد على وجود مصدر قابل للٱستخدام وإعادة الٱستخدام بحيث أنه يتم تقسيم مجموعات المصدر الكبيرة إلى قطع صغيرة وقابلة للٱستخدام، عادة ما تسمى الأجزاء Partials. مثلاً في الموقع هنالك رأس وذيل كل منهما يمكن أن يعرفا كنماذج يمكن إدراج كل منهما قبل وبعد نموذج أي صفحة. 14 | 15 | أخيراً، حسب المكتبة التي تقوم بٱستخدامها، يمكن أن توفر بعض النماذج حماية تلقائياً عن طريق ترشيح المحتوى. 16 | بعض المكتبات توفر وضع الحماية sand-boxing بحيث أنه مصممي النماذج لديهم وصول فقط للدوال والمتغيرات في القائمة البيضاء أي في القائمة المسموح بها للٱستخدام في النماذج. 17 | -------------------------------------------------------------------------------- /_posts/08-03-01-Plain-PHP-Templates.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: نماذج PHP العادية 3 | isChild: true 4 | anchor: plain_php_templates 5 | --- 6 | 7 | ## نماذج PHP العادية {#plain_php_templates_title} 8 | 9 | نماذج PHP العادية هي عبارة عن النماذج التي تستخدم مصدر PHP لكتابة محتواها. هنالك العديد من الخيارات بما أن PHP 10 | هي عبارة عن لغة نمذجة في نفسها. فهذا يعني أنه يمكن دمج مصدر PHP مع مصادر أخرى مثل توسيم HTML. 11 | هذا مفيد لمطوري PHP فهو لا يضيف جمل جديدة لتعلمها، وهم يعلمون الدوال المتوفرة لديهم ومحرر النصوص يحتوي على تخطيط PHP 12 | والإكمال التلقائي مدمج معه. 13 | تصنف نماذج PHP العادية بأنها سريعة فهي لا تتطلب أي عملية تجميع وبناء. 14 | 15 | كل أطر العمل الحديثة تقوم بتوظيف شكل من أشكال نظام النمذجة، فالبعض يستخدم نماذج PHP عادية. 16 | بعيداً عن أطر العمل، هنالك مكتبات مثل [Plates][plates] أو [Aura.View][aura] تقوم بالعمل على نماذج PHP العادية بطريقة أسهل وذلك عن طريق توفير وظائف نمذجة متطورة مثل التوريث والقوالب والإضافات. 17 | 18 | ### مثال لنماذج PHP عادية 19 | 20 | باستخدام مكتبة [Plates][plates]. 21 | 22 | {% highlight php %} 23 | 24 | 25 | insert('header', ['title' => 'ملف المستخدم']) ?> 26 | 27 |

    ملف المستخدم

    28 |

    مرحباً escape($name)?>

    29 | 30 | insert('footer') ?> 31 | {% endhighlight %} 32 | 33 | ### مثال للتوريث في نماذج PHP عادية 34 | 35 | باستخدام مكتبة [Plates][plates]. 36 | 37 | {% highlight php %} 38 | 39 | 40 | 41 | 42 | <?=$title?> 43 | 44 | 45 | 46 |
    47 | section('content')?> 48 |
    49 | 50 | 51 | 52 | {% endhighlight %} 53 | 54 | {% highlight php %} 55 | 56 | 57 | layout('template', ['title' => 'ملف المستخدم']) ?> 58 | 59 |

    ملف المستخدم

    60 |

    مرحباً escape($name)?>

    61 | {% endhighlight %} 62 | 63 | 64 | [plates]: http://platesphp.com/ 65 | [aura]: https://github.com/auraphp/Aura.View 66 | -------------------------------------------------------------------------------- /_posts/08-04-01-Compiled-Templates.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: نماذج التجميع Compiled Templates 3 | isChild: true 4 | anchor: compiled_templates 5 | --- 6 | 7 | ## نماذج التجميع Compiled Templates {#compiled_templates_title} 8 | 9 | بالرغم أن PHP تطورت بطبيعتها لتكون لغة برمجة كائنية، ولكنها [لم تتطور بكونها لغة نمذجة][article_templating_engines]. 10 | نماذج التجميع مثل [Twig] و[Brainy] و[Smarty] تملأ هذا الفراغ بتوفير صيغ كتابة جديدة تمتلك المواصفات الحقيقة مثل كونها نماذج. ابتداءً من الترشيح التلقائي حتى التوريث وسهولة التحكم في الهياكل، نماذج التجميع قد صممت لكي تكون سهلة الكتابة والقراءة وآمنة للإستخدام. نماذج التجميع يمكن أن تنتشر وتستخدم عبر لغات مختلفة، [Mustache] هو مثال جيد لهذا. بما أن هذه النماذج تستوجب عملية التجميع فهنالك فرق في الأداء ولكنه فرق طفيف إذا تم استخدام تخزين مؤقت بطريقة جيدة (caching). 11 | 12 | **بالرغم أن Smarty يوفر ترشيح تلقائي ولكنه غير مفعل بشكل إفتراضي.* 13 | 14 | ### مثال لنموذج تجميعي 15 | 16 | باستخدام مكتبة [Twig]. 17 | 18 | {% highlight html+jinja %} 19 | {% raw %} 20 | {% include 'header.html' with {'title': 'ملف المستخدم'} %} 21 | 22 |

    ملف المستخدم

    23 |

    مرحباً {{ name }}

    24 | 25 | {% include 'footer.html' %} 26 | {% endraw %} 27 | {% endhighlight %} 28 | 29 | ### مثال بسيط للتوريث في نموذج تجميعي 30 | 31 | باستخدام مكتبة [Twig]. 32 | 33 | {% highlight html+jinja %} 34 | {% raw %} 35 | // template.html 36 | 37 | 38 | 39 | {% block title %}{% endblock %} 40 | 41 | 42 | 43 |
    44 | {% block content %}{% endblock %} 45 |
    46 | 47 | 48 | 49 | {% endraw %} 50 | {% endhighlight %} 51 | 52 | {% highlight html+jinja %} 53 | {% raw %} 54 | // user_profile.html 55 | 56 | {% extends "template.html" %} 57 | 58 | {% block title %}ملف المستخدم{% endblock %} 59 | {% block content %} 60 |

    ملف المستخدم

    61 |

    مرحباً {{ name }}

    62 | {% endblock %} 63 | {% endraw %} 64 | {% endhighlight %} 65 | 66 | 67 | [article_templating_engines]: http://fabien.potencier.org/article/34/templating-engines-in-php 68 | [Twig]: http://twig.sensiolabs.org/ 69 | [Brainy]: https://github.com/box/brainy 70 | [Smarty]: http://www.smarty.net/ 71 | [Mustache]: http://mustache.github.io/ 72 | -------------------------------------------------------------------------------- /_posts/08-05-01-Further-Reading.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: المزيد من القراءة 3 | isChild: true 4 | anchor: templating_further_reading 5 | --- 6 | 7 | ## المزيد من القراءة {#templating_further_reading_title} 8 | 9 | ### مقالات ودروس 10 | 11 | * [Templating Engines in PHP](http://fabien.potencier.org/article/34/templating-engines-in-php) 12 | * [An Introduction to Views & Templating in CodeIgniter](http://code.tutsplus.com/tutorials/an-introduction-to-views-templating-in-codeigniter--net-25648) 13 | * [Getting Started With PHP Templating](http://www.smashingmagazine.com/2011/10/17/getting-started-with-php-templating/) 14 | * [Roll Your Own Templating System in PHP](http://code.tutsplus.com/tutorials/roll-your-own-templating-system-in-php--net-16596) 15 | * [Master Pages](https://laracasts.com/series/laravel-from-scratch/episodes/7) 16 | * [Working With Templates in Symfony 2](http://code.tutsplus.com/tutorials/working-with-templates-in-symfony-2--cms-21172) 17 | * [Writing Safer Templates](https://github.com/box/brainy/wiki/Writing-Safe-Templates) 18 | 19 | ### مكتبات 20 | 21 | * [Aura.View](https://github.com/auraphp/Aura.View) *(مدمجة)* 22 | * [Blade](http://laravel.com/docs/blade) *(تجميعية، مخصصة لإطار عمل)* 23 | * [Brainy](https://github.com/box/brainy) *(تجميعية)* 24 | * [Dwoo](http://dwoo.org/) *(تجميعية)* 25 | * [Latte](https://github.com/nette/latte) *(تجميعية)* 26 | * [Mustache](https://github.com/bobthecow/mustache.php) *(تجميعية)* 27 | * [PHPTAL](http://phptal.org/) *(تجميعية)* 28 | * [Plates](http://platesphp.com/) *(مدمجة)* 29 | * [Smarty](http://www.smarty.net/) *(تجميعية)* 30 | * [Twig](http://twig.sensiolabs.org/) *(تجميعية)* 31 | * [Zend\View](http://framework.zend.com/manual/2.3/en/modules/zend.view.quick-start.html) *(مدمجة، مخصصة لإطار عمل)* 32 | -------------------------------------------------------------------------------- /_posts/09-01-01-Errors-and-Exceptions.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: الأخطاء والإستثناءات Errors and Exceptions 3 | isChild: false 4 | anchor: errors_and_exceptions 5 | --- 6 | 7 | # الأخطاء والإستثناءات Errors and Exceptions {#errors_and_exceptions_title} 8 | 9 | -------------------------------------------------------------------------------- /_posts/09-02-01-Errors.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: الأخطاء 3 | isChild: true 4 | anchor: errors 5 | --- 6 | 7 | ## الأخطاء {#errors_title} 8 | 9 | في الكثير من لغات البرمجة التي تعتمد بكثافة على الإستثناءات "Exceptions" عندما يحدث خطأ ما سوف يتم القاء إستثناء. 10 | فهذه هي الطريقة المعتمدة لعمل الأشياء، ولكن لغة PHP لا تعتمد بكثافة على الإستثناءات. ولكن توجد إستثناءات بداخلها 11 | والعديد من الدوال الجوهرية بدأت فعلياً باستخدام الإستثناءات ثم التعامل بالكائنات، فالعديد من PHP نفسها تحاول ان 12 | تواصل العمل بغض النظر عما يحدث، إلا إذا حدث خطأ ما. 13 | 14 | مثلاً: 15 | 16 | {% highlight console %} 17 | $ php -a 18 | php > echo $foo; 19 | Notice: Undefined variable: foo in php shell code on line 1 20 | {% endhighlight %} 21 | 22 | هذه مجرد ملاحظة ، PHP ستواصل العمل ولن تتوقف. وهذا قد يربك المطورين من لغات اخرى معتمدة على الإستثناءات بكثافة، 23 | لأنه عند استخدام متغير غير معرف في لغة Python مثلاً سيقوم برمي إستثناء: 24 | 25 | {% highlight console %} 26 | $ python 27 | >>> print foo 28 | Traceback (most recent call last): 29 | File "", line 1, in 30 | NameError: name 'foo' is not defined 31 | {% endhighlight %} 32 | 33 | الإختلاف الحقيقي فقط هو أن لغة Python سوف تتوقف لأي شي حتى ولو كان صغيراً، إذاً سيكون المبرمج متأكداً جداً من أي مشكلة قد تحدث 34 | سيتم إكتشافها، بالمقابل PHP ستواصل قدماً في المعالجة إلا إذا حدث شيء كبير، عندها ستقوم برمي خطأ وتقرير هذا الخطاً. 35 | 36 | ### شدة الخطأ 37 | 38 | لدى PHP عدة مستويات لشدة الخطأ. يوجد ثلاث أنو معروفة من أنواع رسائل الخطأ والملاحظات والتحذيرات. 39 | هنالك عدة مستويات مختلفة من الشدة: `E_ERROR` و `E_NOTICE` و `E_WARNING`. الأولى هي الأخطاء الفادحة التي تحدث أثناء 40 | التنفيذ وغالباً ما تسبب فشل في تنفيذ المصدر ويتوجب عليك فحص هذا الخطأ حتى تتمكن من إكمال التنفيذ لأن PHP ستقوم بإيقاف 41 | التنفيذ. الثانية وهي رسائل نصحية تسبب المصدر في ظهورها ربما تتسبب أو قد لا تتسبب في حدوث خطأ اثناء تنفيذ المصدر، ولكن 42 | لن توقف PHP التنفيذ. والأخيرة هي أخطاء غير فادحة ولن يتوقف التنفيذ 43 | 44 | هنالك نوع آخر من رسائل التقرير بالخطأ في مرحلة البناء والتجميع وهي `E_STRICT`. هذه الرسائل تستخدم لإقتراح تغيير في 45 | المصدر لتأكيد انه يقوم بنجاح بالتشغيل البيني و متوافق مع الإصدارات القادمة من PHP 46 | 47 | ### تغيير طريقة PHP لتقرير الأخطاء 48 | 49 | يمكن تغيير طريقة تقرير الأخطاء باستخدام ضبط PHP أو/و عن طريق تنفيذ دوال. باستخدام الدالة المدمجة `error_reporting()` 50 | يمكنك أن تحدد مستوى تقرير الأخطاء والمدة التي يتم فيها تنفيذ المصدر بارسال واحدة من ثوابت تقرير الأخطاء، بمعنى أنه 51 | يمكنك أن تحدد ما إذا كنت تريد أن تحصل على تقارير أخطاء وتحذيرات من دون ملاحظات فسيكون عليك ان يكون الضبط كالآتي: 52 | 53 | {% highlight php %} 54 | upload->get_error()` لكي تعرف ماذا حدث. تكمن المشكلة هنا أنه يتوجب عليك الذهاب الى مستندات التوثيق ومعرفة 18 | ما هي دالة إظهار الخطأ لهذا الكلاس، بدلا من جعلها ظاهرة بشكل أوضح. 19 | 20 | مشكلة اخرى هي عندما يقوم كلاس برمي خطأ على الشاشة وإيقاف التنفيذ بشكل تلقائي. عندما تقوم بهذا فأنت تقوم بمنع المطور الآخر أن 21 | يقوم بالتعامل مع هذا الخطأ بشكل حيوي تلقائي. الإستثناءت يجب ان ترمى لكي تجعل المطور على دراية بحدوث الخطأ، ثم بعدها يكون 22 | لديه الحرية في طريقة التعامل معه. مثال: 23 | 24 | {% highlight php %} 25 | subject('العنوان'); 28 | $email->body('كيف حالك؟'); 29 | $email->to('guy@example.com', 'فلان الفلاني'); 30 | 31 | try 32 | { 33 | $email->send(); 34 | } 35 | catch(Fuel\Email\ValidationFailedException $e) 36 | { 37 | // فشل في التحقق 38 | } 39 | catch(Fuel\Email\SendingFailedException $e) 40 | { 41 | // فشل في إرسال البريد الإلكتروني 42 | } 43 | finally 44 | { 45 | // يتم تنفيذه بغض النظر عن ما إذا تم رمي استثناء ، وقبل ان يواصل التنفيذ 46 | } 47 | {% endhighlight %} 48 | 49 | ### إستثناءات SPL 50 | 51 | الكلاس العام `Exception` يتيح القليل من السياقات للتحقق للمبرمج. ولكن لعلاج هذا يمكن إنشاء `Exception` مخصصة من الكلاس 52 | الأصلي: 53 | 54 | {% highlight php %} 55 | الكثير من الإستثناءات الفرعية، يمكن الإبتعاد عن بعضها باستخدام إستثناءات SPL متوفرة في [SPL extension][splext]. 61 | 62 | فمثلا عندما تستخدم الدالة السحرية `__call()` وتم طلب دالة غير صالحة فبدلاً من رمي إستثناء عادي أو إنشاء استثناء خاص بك يمكنك رمي: 63 | `throw new BadMethodCallException;`. 64 | 65 | * [قراءة المزيد عن Exceptions][exceptions] 66 | * [قراءة المزيد عن SPL Exceptions][splexe] 67 | * [الإستثناءات المتداخلة Nesting Exceptions In PHP][nesting-exceptions-in-php] 68 | * [أفضل المماراست في الإستثناءات Exception Best Practices in PHP 5.3][exception-best-practices53] 69 | 70 | 71 | [splext]: /#standard_php_library 72 | [exceptions]: http://php.net/language.exceptions 73 | [splexe]: http://php.net/spl.exceptions 74 | [nesting-exceptions-in-php]: http://www.brandonsavage.net/exceptional-php-nesting-exceptions-in-php/ 75 | [exception-best-practices53]: http://ralphschindler.com/2010/09/15/exception-best-practices-in-php-5-3 76 | -------------------------------------------------------------------------------- /_posts/10-01-01-Security.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: الحماية 3 | isChild: false 4 | anchor: security 5 | --- 6 | 7 | # الحماية {#security_title} 8 | -------------------------------------------------------------------------------- /_posts/10-02-01-Web-Application-Security.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: حماية تطبيق الويب 3 | isChild: true 4 | anchor: web_application_security 5 | --- 6 | 7 | ## حماية تطبيق الويب {#web_application_security_title} 8 | 9 | هنالك العديد من الأناس السيئين متعدين لإستغلال تطبيقك. من المهم أن تتخذ التحوطات اللازمة لزيادة حماية التطبيق. 10 | لحسن الحظ الأناس الجيدين في [المشروع المفتوح لحماية تطبيقات الويب The Open Web Application Security Project OWASP][1] 11 | قاموا بتجميع قائمة شاملة لكل مشاكل الحماية، وطرق الحماية منها. الإطلاع على هذا المشروع هو مطلب لاي مطور مدرك لأهمية الحماية. 12 | الديل [Survive The Deep End: PHP Security][3] كتبت بواسطة باراديك برادي، وهو أحد الأدلة الجيدة لحماية تطبيقات PHP. 13 | 14 | * [قراءة دليل OWASP][2] 15 | 16 | 17 | [1]: https://www.owasp.org/ 18 | [2]: https://www.owasp.org/index.php/Guide_Table_of_Contents 19 | [3]: http://phpsecurity.readthedocs.org/en/latest/index.html 20 | -------------------------------------------------------------------------------- /_posts/10-03-01-Password-Hashing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: تشفير كلمات المرور 3 | isChild: true 4 | anchor: password_hashing 5 | --- 6 | 7 | ## تشفير كلمات المرور {#password_hashing_title} 8 | 9 | دائماً ما يتم بناء تطبيقات PHP تعتمد على تسجيل دخول مستخدمين. فإسم المستخدم وكلمة المرور يتم حفظهما في قاعدة البيانات 10 | حتى يتم استخدامهما للتحقق من هوية المستخدم عن تسجيل الدخول. 11 | 12 | من المهم أن تقوم [_بتشفير_][3] كلمات السر قبل حفظها. تشفير كلمة المرور هو عملية تشفير أحادية الاتجاه لا يمكن استرجاعها 13 | وتنفذ على كلمة مرور المستخدم. يتم انشاء نص محدد المدى لا يمكن فكه. هذا يعني نه ستقوم بمقارنة المحتوى المشفر بمثله للتأكد 14 | من أنهما متطابقين، فسوف يكونا كذلك إذا كانا من نفس المصدر، ولكن لا يمكن معرفة المحتوى الأصلي. 15 | إذا لم يتم تشفير كلمات المرور وتم الوصول غير المصرح به لقاعدة البيانات، فسيكون كل حسابات المستخدمين قد تم السيطرة عليها. 16 | يجب تشفير كلمات المرور بشكل مستقل عن طريق إضافة نص عشوائي [_ملح_][5] لكل كلمة مرور قبل تشفيرها. فذلك يساعد على تجنب هجمات القوامين التي تقوم باستخدام جداول قوس المطر "Rainbow tables" (وهي قائمة عكسية معدة مسبقاً من مجموعة تشفيرات لشفرات كلمات مرور كثيرة الاستخدام). 17 | التشفير والتمليح مهم جدا حيث انه بعض المستخدمين يقوم باستخدام نفس كلمة المرور في عدة أجهزة أو خدمات أخرى وقد تكون جودة كلمات مرورهم غير قوية كفاية. 18 | لحسن الحظ، PHP قد سهلت هذه المهمة! 19 | 20 | **تشفير كلمات المرور باستخدام `password_hash`** 21 | 22 | في إصدارة PHP 5.5 تم إضافة دالة `password_hash()`. حالياً تستخدم هذه الدالة لوغاريثمية BCrypt، وهي اللوغاريثمية الأقوى حتى 23 | الآن في PHP. ستيم مستقبلاً إضافة الدعم لعدة لوغاريثمات أخرى حسب الحاجة. تم إنشاء مكتبة `password_compat` لإتاحة توافقية 24 | لإصدارات PHP المتقدمة PHP >= 5.3.7. 25 | 26 | أدناه سنقوم بتشفير نص، ثم نقوم بمقارنته بنص آخر. بما أن كلا النصين مختلفين، (كلمة مرور صحيحة مقارنة بـ كلمة مرور خاطئة) 27 | ستفشل عملية تسجيل الدخول. 28 | 29 | {% highlight php %} 30 | = 5.3.7 && < 5.5] [2] 46 | * [Learn about hashing in regards to cryptography] [3] 47 | * [Learn about salts] [5] 48 | * [PHP `password_hash()` RFC] [4] 49 | 50 | 51 | [1]: http://php.net/function.password-hash 52 | [2]: https://github.com/ircmaxell/password_compat 53 | [3]: http://en.wikipedia.org/wiki/Cryptographic_hash_function 54 | [4]: https://wiki.php.net/rfc/password_hash 55 | [5]: https://en.wikipedia.org/wiki/Salt_(cryptography) 56 | -------------------------------------------------------------------------------- /_posts/10-04-01-Data-Filtering.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: تصفية البيانات 3 | isChild: true 4 | anchor: data_filtering 5 | --- 6 | 7 | ## تصفية البيانات {#data_filtering_title} 8 | 9 | لا تقم (أبداً) بالوثوق بأي مدخلات إلى التطبيق أو المصدر. دائماً قم بتعقيم ومراجعة هذه المدخلات قبل استخدامها في المصدر. 10 | الدالتان `filter_var()` و `filter_input()` يمكنهما تعقيم ومراجعة صيغ النصوص ( كيغة البريد الإلكتروني مثلاً). 11 | 12 | المدخلات الأجنبية يمكن أن تكون أي شيء: `$_GET` و `$_POST` كمدخلات النماذج، بعض القيم من المتغيرات العامة `$_SERVER`، 13 | وأي محتوى طلب HTTP باستخدام `fopen('php://input', 'r')`. تذكر بأن المدخلات الأجنبية ليست محصورة على المدخلات من النماذج 14 | المرسلة من المستخدم. الملفات المرفوعة والمحملة وقيم المتغيرات وبيانات الكوكيز وبيانات تطبيقات وخدمات الويب 15 | هي مدخلات أجنبية أيضاً. 16 | 17 | طالما يحتمل أن يتم حفظ البيانات والوصول إليها لاحقاً، فهي ما تزال مدخلات أجنبية. في كل مرة تقوم بمعالجة أو دمج أو أدراج 18 | بيانات في المصدر، تسأل ما إذا كانت البيانات تم تصفيها بطريقة صحيحة ويمكن الوثوق بها. 19 | 20 | بشكل عام البيانات _تصفى_ بشكل مختلف بناءً على كيفيتها. مثلا، عند تمرير مدخلات أجنبية إلى مخرجات صفحة HTML عندها سيتم 21 | تنفيذ HTML و JavaScript في الموقع! هذا ما يسمى Cross-Site Scripting (XSS) ويمكن أن يكون هجوماً خطيراً جداً. 22 | طريقة لتفادي هذا الهجوم هو عن طريق تعقيم كل البيانات التي ستعرض للمسخدم قبل عرضها في الصفحة عن طريق حذف كل وسوم HTML 23 | باستخدام الدالة `strip_tags()` أو إسقاط الرموز والوسوم باستخدام دوال ذات معنى خاص بعناصر HTML `htmlentities()` أو 24 | `htmlspecialchars()`. 25 | 26 | مثال آخر، تمرير قيم لكي يتم تنفيذها على شكل أمر. فهذا يعتبر من أخطر المهددات (وهي فكرة سيئة)، ولكن يمكن استخدام 27 | الدالة `escapeshellarg()` لتعقيم وتنفيذ قيم الأمر. 28 | 29 | مثال أخير وهو قبوم مدخلات أجنبية لتحديد ملف ما لعرضه من الملفات. قد تكون هذه ثغرة عن طريق تغيير اسم الملف إلى مسار ملف 30 | ما. فستحتاج أن تقوم بإزالة كل من `"/"` و `"../"` وما يسمى [null bytes][6] وأي رموز من مسار الملف حتى لا يتم إدراج 31 | ملفات خاصة أو محمية من العرض أو ملفات حساسة. 32 | 33 | * [تعرف على المزيد عن data filtering][1] 34 | * [تعرف على المزيد عن `filter_var`][4] 35 | * [تعرف على المزيد عن `filter_input`][5] 36 | * [تعرف على المزيد عن إدارة null bytes][6] 37 | 38 | ### التعقيم 39 | 40 | التعقيم هو إزالة أو إسقاط أي رموز غير آمنة أو غير مصرح بها من المدخلات الأجنبية. 41 | 42 | مثلاً يجب أن تقوم بتعقيم المدخلات الأجنبية قبل إدراج المدخل في HTML أو قبل إدراجها في إستعلام SQL مباشرة. 43 | عندما تستخدم ربط القيم باستخدام [PDO](#databases) فستقوم PDO بتعقيم المدخلات تلقائياً. 44 | 45 | بعض الأحيان قد تسمح ببعض وسوم HTML الآمن كمدخلات لتتضمن في محتوى صفحة HTML. تطبيق هذا صعب للغاية والبعض يقومون بتجنبه 46 | باستخدام صيغة أكثر إحكاماً مثل Markdown أو BBCode بالرغم بأن هنالك مكتبات مخصصة لهذا السبب [HTML Purifier][html-purifier]. 47 | 48 | [Sanitization Filters][2] 49 | 50 | ### Unserialization 51 | 52 | من الخطير تنفيذ عملية `unserialize()` من بيانات مدخلة من المستخدم أو من مصادر غير موثوقة. القيام بذلك يسمح للمستخدم أن يقوم بإنشاء 53 | كائنات (بمحتوى مسبق التعريف) فسيتم تنفيذها من قبل destructor **حتى ولو لم يتم استخدام هذه الكائنات**. عندها يجب أن لا يتم عمل 54 | unserialize لأي بيانات غير موثوقة. 55 | 56 | إذا كان لابد أن تقوم بعمل unserialize لبيانات من مصادر غير موثوقة، عندها قم باستخدام خيار [`allowed_classes`][unserialize] 57 | لتحديد أي نوع من الكائنات يمكن أن يتم عمل unserialize عليه. متوفر في إصدارة PHP7 فقط 58 | 59 | ### التحقق 60 | 61 | يتم التحقق من البيانات الأجنبية المدخلة كما تتوقع منها أن تكون. مثلا قد تريد ان تتحقق من بريد إلكتروني و رقم هاتف 62 | وعمر عندما تقوم بمعالجة طلب تسجيل. 63 | 64 | [Validation Filters][3] 65 | 66 | 67 | [1]: http://php.net/book.filter 68 | [2]: http://php.net/filter.filters.sanitize 69 | [3]: http://php.net/filter.filters.validate 70 | [4]: http://php.net/function.filter-var 71 | [5]: http://php.net/function.filter-input 72 | [6]: http://php.net/security.filesystem.nullbytes 73 | [html-purifier]: http://htmlpurifier.org/ 74 | [unserialize]: https://secure.php.net/manual/en/function.unserialize.php 75 | -------------------------------------------------------------------------------- /_posts/10-05-01-Configuration-Files.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ملفات الضبط 3 | isChild: true 4 | anchor: configuration_files 5 | --- 6 | 7 | ## ملفات الضبط {#configuration_files_title} 8 | 9 | عندما تقوم بإنشاء ملف ضبط لتطبيقك، فهنالك أفضل الممارسات التي ينصح بتطبيق إحداها: 10 | 11 | - من الأفضل أن تقوم بحفظ معلومات الضبط في مسار لا يمكن الوصول إليه مباشرة ويتم الوصول إليه عن طريق المسار الداخلي للنظام. 12 | - إذا كان لابد من حفظ ملف الضبط في المسار الرئيس للمشروع، قم بتسمية ملف الضبط بلاحقة `.php`. وهذا يضمن أنه حتى وإن تم الوصول 13 | للملف مباشرة، فلن يتم طباعة أي نص. 14 | - المعلومات التي في ملف الضبط يجب أن يتم حمايتها، إما عن طريق تشفيرها أو إعطائها صلاحيات على المستخدم/المجموعة في النظام. 15 | - من الجيد التأكد من عدم إعتماد ملفات الضبط التي تحتوي على بيانات حساس مثل كلمات المرور أو رموز API ونشرها في نظام التحكم في الكود المصدري (GIT). 16 | -------------------------------------------------------------------------------- /_posts/10-06-01-Register-Globals.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Register Globals 3 | isChild: true 4 | anchor: register_globals 5 | --- 6 | 7 | ## Register Globals {#register_globals_title} 8 | 9 | **وهو خيار ضبط في إعدادات PHP** 10 | **ملاحظة: منذ الإصدارة PHP 5.4.0 تم إزالة خيار ضبط `register_globals` تمام. وتم إدراج هذا الفصل بمثابة تحذير لكل من 11 | ينوي الترقية لتطبيق متوافق مع إصدار قديم. 12 | 13 | عندما يتم تفعيل `register_globals`، فسيقوم بإنشاء عدد من المتغيرات من متغيرات عامة من: 14 | `$_POST` و `$_GET` و `$_REQUEST` وجعلها متوفرة في النطاق العام لتطبيقك. ويتسبب بسهولة إلى مشاكل في الحماية فلا يتمكن 15 | تطبيقك من التأكد من مصدر البيانات ومن أين تأتي. 16 | 17 | مثلاً: `$_GET['foo']` سيكون متوفراً بالإسم `$foo` مما يتسبب في الكتابة على المتغيرات التي لم يتم تعريفها. 18 | فإذا كنت تستخدم إصدارة أقل من PHP 5.4.0 __قم بالتأكد__ من أن الخيار `register_globals` __غير مفعل__. 19 | 20 | * [Register_globals في دليل PHP](http://php.net/security.globals) 21 | -------------------------------------------------------------------------------- /_posts/10-07-01-Error-Reporting.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: تدوين وتقرير الأخطاء 3 | isChild: true 4 | anchor: error_reporting 5 | --- 6 | 7 | ## تدوين وتقرير الأخطاء {#error_reporting_title} 8 | 9 | يفيد تدوين الأخطاء في إيجاد المشكل في تطبيقك، ولكن يمكن أن تعرض معلومات حساسة عن هيكلة التطبيق للعالم الخارجي. 10 | لحماية تطبيقك بكفاءة عالية من المشاكل التي قد تحدث من مخرجات هذه الرسائل يجب أن يتم ضبط المخدم بطريقة مختلفة في بيئة 11 | العمل النهائية عما هو عليه في بيئة التطوير. 12 | 13 | ### بيئة التطوير 14 | 15 | لإظهار أي خطأ يحدث أثناء **التطوير**، قم بضبط الخيارات في `php.ini` كالاتي: 16 | 17 | {% highlight ini %} 18 | display_errors = On 19 | display_startup_errors = On 20 | error_reporting = -1 21 | log_errors = On 22 | {% endhighlight %} 23 | 24 | > إسناد القيمة `-1` يقوم بتفعيل ظهور أي خطأ محتمل وأي مستويات يتم إضافتها في المستقبل على إصدارات PHP مستقبلية. 25 | > الثابت `E_ALL` سيقوم أيضاً بنفس الشيء ابتداءً من إسدارة PHP 5.4 26 | > [php.net](http://php.net/function.error-reporting) 27 | 28 | مستوى تقرير الخطأ في الثابت `E_STRICT` قد تم إدراجه في الإصدارة 5.3.0 وهو خيار منفصل من المستوى `E_ALL` ولكن صار 29 | جزءً من `E_ALL` في الإصدار 5.4.0. ما معنى هذا؟ 30 | هذا يعني أنه إذا كنت تريد تقرير كل الأخطاء في الإصدار 5.3 سيتوجب عليك أن تستخدم `-1` أو `E_ALL | E_STRICT`. 31 | 32 | **تقرير كل الأخطاء المحتملة بناء على إصدارات PHP** 33 | 34 | * < 5.3 `-1` or `E_ALL` 35 | *   5.3 `-1` or `E_ALL | E_STRICT` 36 | * > 5.3 `-1` or `E_ALL` 37 | 38 | ### بيئة العمل النهائي 39 | 40 | لإخفاء الأخطاء في **بيئة العمل النهائية** قم بضبط الخيارات في `php.ini` كالآتي: 41 | 42 | {% highlight ini %} 43 | display_errors = Off 44 | display_startup_errors = Off 45 | error_reporting = E_ALL 46 | log_errors = On 47 | {% endhighlight %} 48 | 49 | بخيارات الضبط هذه في بيئة العلم النهائية، سيتم تدوين الأخطاء في سجل الأخطاء في المخدم ولكن لن يظهر أي منها للتمسخدم. 50 | للمزيد من المعلومات عن هذه الخيارات، قم بالإطلاع عليها في دليل PHP: 51 | 52 | * [error_reporting](http://php.net/errorfunc.configuration#ini.error-reporting) 53 | * [display_errors](http://php.net/errorfunc.configuration#ini.display-errors) 54 | * [display_startup_errors](http://php.net/errorfunc.configuration#ini.display-startup-errors) 55 | * [log_errors](http://php.net/errorfunc.configuration#ini.log-errors) 56 | -------------------------------------------------------------------------------- /_posts/11-01-01-Testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: التجربة والإختبار 3 | isChild: false 4 | anchor: testing 5 | --- 6 | 7 | # التجربة والإختبار {#testing_title} 8 | 9 | يعتبر كتابة الإختبارات التلقائية لكود PHP هو من أفضل الممارسات التي تؤدي لتطبيقات مبنية بصور صحيحة. 10 | الإختبارات التلقائية هي أداة ممتازة للتأكد من أن تطبيقك لن يتوقف عندما تقوم بإدراج أو إضافة خواص وعمليات جديدة 11 | ويجب عدم إهمالها! 12 | 13 | هنالك أنواع معدودة لإدوات الإختبار (أو أطر عمل) متوفرة للغة PHP، وكل نوع يقوم باستخدام طريقة مختلفة كلها تقوم بتحقيق 14 | هدف تفادي القيام بعمليات الإختبار اليدوية وتلبية إحتياج فرق تأكيد الجودة، للتأكد من أن التغييرات الجديدة لم تقم بإيقاف 15 | عمل تلك الخواص الموجودة مسبقاً. -------------------------------------------------------------------------------- /_posts/11-02-01-Test-Driven-Development.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: التطوير الموجه بالاختبار 3 | isChild: true 4 | anchor: test_driven_development 5 | --- 6 | 7 | ## التطوير الموجه بالاختبار TDD {#test_driven_development_title} 8 | 9 | مقتبس من ويكيبيديا Test Driven Development 10 | [بالعربية](https://ar.wikipedia.org/wiki/%D8%AA%D8%B7%D9%88%D9%8A%D8%B1_%D9%85%D9%88%D8%AC%D9%87_%D8%A8%D8%A7%D9%84%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1): 11 | [بالإنجليزية](http://en.wikipedia.org/wiki/Test-driven_development): 12 | 13 | > تطوير موجه بالاختبار (بالإنجليزية: Test-driven development (TTD))، 14 | > هو مصطلح يطلق على إحدى عمليات تطوير البرمجيات التي تعتمد على تكرار دورة تطوير قصيرة جداً: 15 | > بدايةً، يقوم المبرمج بكتابة حالة فحص أوتوماتيكية فاشلة ويجب على حالة الفحص هذه أن تعرّف تحسينا 16 | > معينا أو وظيفة جديدة. ومن ثم يقوم بكتابة الشيفرة التي تجعل حالة الفحص ناجحة وأخيرا يقوم بإعادة 17 | > تصنيع الشيفرة كي تتلاءم مع المعايير. 18 | 19 | هنالك بضع أنواع مختلفة من الإختبارات التي يمكن تنفيذها على تطبيقك: 20 | 21 | ### إختبار الوحدة 22 | 23 | Unit Testing هو طريقة برمجية للتأكد من أن الدوال والكلاسات والعمليات يعملون كما يجب، ابتداءً من نقطة بنائهم وطول فترة وجودهم 24 | في دائرة التطوير. وذلك عن طريق إختبار القيم المدخلة والمخرجة من دوال والعمليات لضمان أن المنطق الداخلي يعمل بصورة صحيحة. 25 | باستخدام حقن التوابع Dependency Injection وبناء بيانات افتراضية "mock" من كلاسات وصفات، تمكنك من التأكد بأن التوابع مستخدمة 26 | بطريقة مثلى في تغطية الإختبار. 27 | 28 | عندما تقوم بإنشاء كلاس أو دالة يجب أن تقوم بعمل إختبار وحدة لكل وظيفة يجب أن يقوم بعملها. ابتداءً من انه يجب ان تتأكد من 29 | فشل الإختبار عندما تقوم باستخدام قيم خاطئة قم التأكد من نجاحه عند استخدام قيم صحيحة. فهذا سيساعد بانه عندما تقوم بعمل تغييرات 30 | أو تطويرات على هذه الكلاس أو الدالة لاحقاً في دورة التطوير بإن الوظائف القديمة لن تتوقف وستعمل معاً كما هو متوقع. البديل الوحيد 31 | قد يكون الدالة `var_dump()` في ملف test.php حيق لا يمكن بناء أي تطبيق صغير كان أو كبير. 32 | 33 | الإستخدام الآخر لوحدات الإختبار هو المشاركة في مشاريع مفتوحة المصدر. إذا كان يمكنك كتابة إختبار يظهر فشل وظيفة معينة، عندها 34 | قم بإصلاح هذا الخطأ ثم اظهر نجاح الإختبار، فعندها التعديلات يتم قبولها بسرعة. 35 | إذا كان لديك مشروع يقبل طلبات الدمج pull requests عندها يجب اقتراح اختبار الوحداك كمطلب أساسي. 36 | 37 | [PHPUnit](http://phpunit.de) هو إطار عمل إختباري لكتابة الإختبارات لتطبيقات PHP ولكن هنالك بضع بدائل أخرى: 38 | 39 | * [atoum](https://github.com/atoum/atoum) 40 | * [Kahlan](https://github.com/crysalead/kahlan) 41 | * [Peridot](http://peridot-php.github.io/) 42 | * [SimpleTest](http://simpletest.org) 43 | 44 | ### الإختبارات المتكاملة 45 | 46 | [من ويكيبيديا بالإنجليزية](http://en.wikipedia.org/wiki/Integration_testing): 47 | 48 | > الإختبارات المتكاملة (يطلق عليها التكامل والإختبار بعض الأحيان ويرمز لها بالإختصار "I&T") وهو في مرحلة إختبار البرنامج 49 | > بحيث يتم دمج دول البرنامج وإختبارها كمجموعة متكاملة. وتحدث بعد إختبار الوحدات وقبل إختبار التحقق. الإختبارات المتكاملة 50 | > تأخذ كمعطيات الدوال التي تم تطبيق إختبار وحدة عليها ثم جمعها معاً في تجميعه تتوائم مع خطة تجميع الوظائف سوياً ثم إخراج 51 | > مخرجات جاهزة لإختبار النظام. 52 | 53 | العديد من الأدوات التي تستخدم في اختبار الوحدات يمكن استخدامها في الإختبارات المتكاملة فهما يتشابهان في عديد من المفاهيم الأساسية. 54 | 55 | ### الإختبار الوظيفي 56 | 57 | يعرف أيضاً بإختبار القبول، يعتمد الإختبار الوظيفي على استخدام أدوات لإنشاء اختبارات تلقائية تقوم فعلياً باستخدام البرنامج 58 | بدلاً من التحقق من كل وحدة على حدة تقوم بالوظيفة الصحيحة، وأن هذه الوحدات تقوم بالتخاطب والعمل سوياً بشكل صحيح. هذه الأدوات 59 | تعمل باستخدام بيانات حقيقية وتقوم بمحاكاة مستخدمين حقيقيين للبرنامج. 60 | 61 | #### أدوات الإختبار الوظيفي 62 | 63 | * [Selenium](http://seleniumhq.com) 64 | * [Mink](http://mink.behat.org) 65 | * [Codeception](http://codeception.com) إطار عمل إختباري متكامل يحتوي على أدوات إختبار القبول. 66 | * [Storyplayer](http://datasift.github.io/storyplayer) إطار عمل إختباري متكامل يحتوي على دعم لإنشاء وهدم بيئات إختبار 67 | -------------------------------------------------------------------------------- /_posts/11-03-01-Behavior-Driven-Development.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: التطوير الموجه بالسلوك 3 | isChild: true 4 | anchor: behavior_driven_development 5 | --- 6 | 7 | ## التطوير الموجه بالسلوك BDD {#behavior_driven_development_title} 8 | 9 | Behavior Driven Development. 10 | هنالك نوعان من هذا النمط: 11 | SpecBDD و StoryBDD. 12 | SpecBDD: يركز على السلوك التقني للكود. 13 | StoryBDD: يركز على الخواص والتفاعلات الفعلية. 14 | هنالك إطارا عمل لكلا النوعين. 15 | 16 | باستخدام StoryBDD يمكن كتابة قصص مقروءة تقوم بوصف سلوك التطبيق. هذه القسس يمكن ان تقوم بتنفيذ إختبارات حقيقية للتطبيق. 17 | إطار العمل المستخدم في تطبيقات PHP للنوع StoryBDD [Behat] وتم استيحائه من مشروع [Cucumber] في Ruby. 18 | 19 | باستخدام SpecBDD يمكن كتابة مواصفات تصف كيف يجب أن يكون سلوك الكود الفعلي. فبدلاً من إختبار الدالة أو العملية، فأنت تقوم 20 | بوصف سلوك الدالة أو العملية. يوجد في PHP إطار عمل [PHPSpec] لنفس الغرض. هذا الإطار تم استيحائه من مشروع [RSpec project][Rspec] في Ruby. 21 | 22 | ### روابط BDD 23 | 24 | * [Behat] : StoryBDD إطار عمل اختباري للغة PHP مستوحى من مشروع [Cucumber] في لغة Ruby; 25 | * [PHPSpec] : SpecBDD إطار عمل إختباري للغة PHP مستوحى من مضروع [RSpec] في لغة Ruby; 26 | * [Codeception] : هو إطار إختباري يقوم باستخدام مفاهيم التطوير الموجه بالسلوك BDD. 27 | 28 | 29 | [Behat]: http://behat.org/ 30 | [Cucumber]: http://cukes.info/ 31 | [PHPSpec]: http://www.phpspec.net/ 32 | [RSpec]: http://rspec.info/ 33 | [Codeception]: http://codeception.com/ 34 | -------------------------------------------------------------------------------- /_posts/11-04-01-Complementary-Testing-Tools.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: أدوات الإختبار المتكاملة 3 | isChild: true 4 | anchor: complementary_testing_tools 5 | --- 6 | 7 | ## أدوات الإختبار المتكاملة {#complementary_testing_tools_title} 8 | 9 | بجانب اطر العمل الإختبارية والسلوكية، هنالك عدد من الأطر العامة والمكتبات المساعدة المفيدة لأي وسيلة مفضلة. 10 | 11 | ### روابط الأدوات 12 | 13 | * [Selenium] أداة متصفح تلقائية يمكنها [الدمج مع PHPUnit] 14 | * [Mockery] أطار عمل لعمل كائنات للإختبار يمكن دمجها مع [PHPUnit] أو [PHPSpec] 15 | * [Prophecy] من أعنف وأقوى أطر العمل لإنشاء كائنات اختبار وتدمج مع [PHPSpec] ويمكن استخدامها مع [PHPUnit] أيضاً. 16 | 17 | 18 | [Selenium]: http://seleniumhq.org/ 19 | [integrated with PHPUnit]: https://github.com/giorgiosironi/phpunit-selenium/ 20 | [Mockery]: https://github.com/padraic/mockery 21 | [PHPUnit]: http://phpunit.de/ 22 | [PHPSpec]: http://www.phpspec.net/ 23 | [Prophecy]: https://github.com/phpspec/prophecy 24 | -------------------------------------------------------------------------------- /_posts/12-01-01-Servers-and-Deployment.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: السيرفرات والنشر 3 | isChild: false 4 | anchor: servers_and_deployment 5 | --- 6 | 7 | # السيرفرات والنشر {#servers_and_deployment_title} 8 | 9 | يمكن لتطبيقات PHP ان تنشر وتعمل على سيرفرات عمل نهائية بعدة طرق. 10 | PHP applications can be deployed and run on production web servers in a number of ways. 11 | -------------------------------------------------------------------------------- /_posts/12-02-01-Platform-as-a-Service.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Platform as a Service (PaaS) 3 | isChild: true 4 | anchor: platform_as_a_service 5 | --- 6 | 7 | ## Platform as a Service (PaaS) {#platform_as_a_service_title} 8 | 9 | **أو المنصة كخدمة** وتوفر النظام ومعمارية الشبكة اللازمة لتشغيل تطبيق PHP على الويب. 10 | هذا يعني انه لا يوجد ضبط لتشغيل تطبيقات PHP أو أطر عمل PHP. 11 | 12 | مؤخراً صار PaaS طريقة مشهورة لنشر واستضافة وتطوير تطبيقات PHP بكل الأحجام. يمكن ايجاد قائمة ببعض هذه المنصات 13 | [PHP PaaS "Platform as a Service" providers](#php_paas_providers) في فصل المصادر [resources section](#resources). -------------------------------------------------------------------------------- /_posts/12-03-01-Virtual-or-Dedicated-Servers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: السيرفرات المخصصة أو الإفتراضية 3 | isChild: true 4 | anchor: virtual_or_dedicated_servers 5 | --- 6 | 7 | ## السيرفرات المخصصة أو الإفتراضية {#virtual_or_dedicated_servers_title} 8 | 9 | **Virtual or Dedicated Servers** 10 | إذا كنت مرتاح بالعمل كمشرف نظام أو مهتم بتعلمه فالسيرفرات المخصصة والإفتراضية تتيح لك مطلق الحرية والتحكم في بيئة التطبيق النهائية. 11 | 12 | ### nginx و PHP-FPM 13 | 14 | تقترن PHP مع [nginx] باستخدام البنية المدمجة FastCGI Process Manager (FPM) وهو سيرفر خفيف ذو كفاءة عالية. 15 | ويقوم باستخدام ذاكرة أقل من نظيره Apache ويقوم بإدارة عدد أكبر من الطلبات المتزامنة. وهو مناسب في السيرفرات الإفتراضية 16 | بحيث لا يوجد الكثير من الذاكرة لإهدارها. 17 | 18 | * [قراءة المزيد عن nginx][nginx] 19 | * [قراءة المزيد عن PHP-FPM][phpfpm] 20 | * [قراءة المزيد عن ضبط nginx مع PHP-FPM بصورة آمنة][secure-nginx-phpfpm] 21 | 22 | ### Apache و PHP 23 | 24 | تملك PHP و Apache تاريخاً طويلاً معاً. فـ Apache واسع الإنتشاء ولديه العديد من [الوحدات][apache-modules] لتمديد وظائفه. 25 | فهو خيار مشهور لكل السيرفرات المشتركة وطريقة سهلة لتشغيل إطر عمل PHP وتطبيقات المصدر المفتوح مثل WordPress. 26 | للأسف Apache يستخدم الكثير من المصادر بعكس Nginx ولا يقوم بإدراة العديد من الزوار في نفس الزمن. 27 | 28 | يوجد عدة طرق لضبط PHP للعمل مع Apache. فالطريقة الأكثر شيوعاً وأسهلها هي تنصيب [prefork MPM] مع الوحدة mod_php5. 29 | بينما هو ليس بخيار جيد في استهلاك الذاكرة ولكنه الأبسط للإستخدام والتشغيل. ويعتبر أفضل خيار إذا كنت لا تنوي التعمق في 30 | إدارة السيرفرات. لاحظ أنه عند استخدام mod_php5 فإنه يجب عليك استخدام [prefork MPM]. 31 | 32 | عوضاً عن ذلك، إذا كنت تريد أن تعتصر المزيد من كفاءة الأداء والإستقرار من Apache عندها يمكن الإستفادة من نفس نظام FPM مثل 33 | Nginx وتشغيل [worker MPM] أو [event MPM] مع الوحدة mod_fastcgi أو mod_fcgid. 34 | هذا الضبط سيكون ذا تأثير واضح وكبير على الذاكرة وسرعة ملحوظة ولكن هنالك جهد أكبر للتنصيب. 35 | 36 | إذا كنت تستخدم Apache 2.4 أو احدث فيمكنك استخدام [mod_proxy_fcgi] لكي تزيد من كفاءة الأداء وهو سهل التنصيب والضبط. 37 | 38 | * [قراءة المزيد عن Apache][apache] 39 | * [قراءة المزيد عن دوال المعالجة المتعددة Multi-Processing Modules][apache-MPM] 40 | * [قراءة المزيد عن mod_fastcgi][mod_fastcgi] 41 | * [قراءة المزيد عن mod_fcgid][mod_fcgid] 42 | * [قراءة المزيد عن mod_proxy_fcgi][mod_proxy_fcgi] 43 | * [قراءة المزيد عن ضبط Apache مع PHP-FPM باستخدام mod_proxy_fcgi][tutorial-mod_proxy_fcgi] 44 | 45 | 46 | [nginx]: http://nginx.org/ 47 | [phpfpm]: http://php.net/install.fpm 48 | [secure-nginx-phpfpm]: https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/ 49 | [apache-modules]: http://httpd.apache.org/docs/2.4/mod/ 50 | [prefork MPM]: http://httpd.apache.org/docs/2.4/mod/prefork.html 51 | [worker MPM]: http://httpd.apache.org/docs/2.4/mod/worker.html 52 | [event MPM]: http://httpd.apache.org/docs/2.4/mod/event.html 53 | [apache]: http://httpd.apache.org/ 54 | [apache-MPM]: http://httpd.apache.org/docs/2.4/mod/mpm_common.html 55 | [mod_fastcgi]: https://blogs.oracle.com/opal/entry/php_fpm_fastcgi_process_manager 56 | [mod_fcgid]: http://httpd.apache.org/mod_fcgid/ 57 | [mod_proxy_fcgi]: https://httpd.apache.org/docs/current/mod/mod_proxy_fcgi.html 58 | [tutorial-mod_proxy_fcgi]: https://serversforhackers.com/video/apache-and-php-fpm 59 | -------------------------------------------------------------------------------- /_posts/12-04-01-Shared-Servers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: السيرفرات المشتركة 3 | isChild: true 4 | anchor: shared_servers 5 | --- 6 | 7 | ## السيرفرات المشتركة {#shared_servers_title} 8 | 9 | **Shared Servers** يوجد العديد من السيرفرات المشتركة، والفضل يعود لشهرة PHP نفسها. من الصعب إيجاد استضافة بدون PHP 10 | ولكن تأكد من أنها أحدث إصدارة. السيرفرات المشتركة تتيح لك وللمطورين الآخرين بنشر مواقع على جهاز واحد. 11 | على الرغم من أنها سلعة رخيصة، ألا أنه لا تعلم ما قد يحدث من "جيرانك" على نفس السيرفر من أذى ومشاكل مشتركة من بطئ السيرفر 12 | وفتح ثغرات أمنية تهددك أيضاً معهم وهو من أخطر ما قد يحدث. فإذا كانت ميزانية المشروع تتيح لك أن لا تستأجر في استضافة مشتركة 13 | فعندها لا تستخدم السيرفرات المشتركة. 14 | 15 | الرجاء التأكد من أن السيرفرات المشتركة توفر آخر إصدارة من PHP، قم بمعرفة [إسدارات PHP](http://phpversions.info/shared-hosting/). 16 | -------------------------------------------------------------------------------- /_posts/12-05-01-Building-your-Application.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: بناء ونشر التطبيقات 3 | isChild: true 4 | anchor: building_and_deploying_your_application 5 | --- 6 | 7 | ## بناء ونشر التطبيقات {#building_and_deploying_your_application_title} 8 | 9 | إذا وجدت نفسك تقوم بتغيير مخططات قاعدة البيانات يدوياً أو تشغيل الإختبارات يدوياً قبل تحديث الملفات (يدوياً) فعليك التفكير مرة اخرى. 10 | في كل مرة تقوم فيها بتحديث تطبيقك إلى نسخة أحدث يدوياً، هنالك فرصة لحدوث خطأ. سواء كنت تتعامل مع وسيلة سهلة للتحديث و أو عملية 11 | بناء شاملة أو حتى خطة تكامل مستمرة Continues Integration. عندها [البناء التقائي][buildautomation] هو صديقك! 12 | 13 | من بين المهام التي قد تحتاج أن تكون بصورة تلقائية: 14 | 15 | * إدارة التوابع 16 | * تجميع وتصغير ملفات الميديا "Assets" كالصور وملفات css و js مثلا. 17 | * تشغيل الإختبارات 18 | * إنشاء التوثيق 19 | * انشاء الحزم 20 | * النشر 21 | 22 | 23 | ### أدوات النشر 24 | 25 | يمكن وصف أدوات النشر بأنها مجموعة من الأوامر الكتابية تقوم بإدارة مهام نشر البرنامج. أدوات التطوير لا تعتبر جزء من البرنامج فهي تمثل البرنامج من الخارج فقط. 26 | 27 | هنالك العديد من الأدوات المتوفر ومفتوحة المصدر تساعدك للبناء والنشر التلقائي. بعضها كتب بلغة PHP وبعضها لا. وهذا ليس سبب يدعوك لعدم استخدامها، إذا كانت تناسب ما تقوم به. بعض الأمثلة: 28 | 29 | [Phing] تمكنك من التحكم في عملية تحزيم وإختبار ونشر تطبيقك في إطار استخدام ملف XML. Phing (وهو مبني على [Apache Ant]) يتيح مجموعة مهام عادة ما تستخدم لتنصيب أو تحديث تطبيقات الويب ويمكن تمديدها للمزيد من المهام. وتكتب بلغة PHP. فهي أداة فعالة وثابتة وموجودة منذ مدة طويلة، ولكن يمكن النظر لهذه الأداة بأنها قديمة بعض الشيء بسبب الطريقة التي تتعامل بها مع ملفات الضبط XML. 30 | 31 | [Capistrano] وهو نظام يخص *المطورين المتوسطين - المتقدمين* لتنفيذ أوامر في بنائية متكررة واحدة منها أو أكثر في أجهزة عن بعد. تم ضبطه لمشر تطبيقات Ruby on Rails، ولكن يمكن بنجاح نشر تطبيقات وأنظمة PHP باستخدامه. الإستخدام الناجح لـ Capistrano يعتمد على خلفية عمل باستخدام Ruby و Rake. نشر ديف جاردنرز مقالة بعنوان [PHP Deployment with Capistrano][phpdeploy_capistrano] فهي بداية جيدة لمطوري PHP المهتمين باستخدام Capistrano. 32 | 33 | [Rocketeer] إستمدت فلسفتها من إطار عمل لارافيل Laravel. يهدف لأن يكون سريع وسهل الإستخدام مع إفتراضيات ذكية. يقوم بالعمل على عدة سيرفرات عدة منصات و نشر كلي وجزئي يمكن تنفيذهم على التوازي. كل شيء في هذه الأداة يمكن أن يتم تحويله أو تمديده وكل شيء مكتوب بلغة PHP. 34 | 35 | [Deployer] وهي أداة نشر كتبت بلغة PHP فهي بسيطة وعملية. تقوم بتنفيذ مهام على التوازي والنشر الجزئي مع التنسيق ما بين السيرفرات. وصفات لمهام مكررة لأطر عمل مثل Symfony و Laravel و Zend Framework و Yii. مقالة يونس رفيع [Easy Deployment of PHP Applications with Deployer][phpdeploy_deployer] تعتبر درس ممتاز لنشر التطبيقات باستخدام هذه الأداة. 36 | 37 | [Magallanes] وهي أداة أخرى مكتوبة بلغة PHP مع ضبط بسيط في ملفات YAML. تدعم بيئات وسيرفرات متعددة و النشر الجزئية ومدمج معها بعض المهام المضمنة والتي تتيح لك النفوذ مع أدوات وأطر عمل مشهورة. 38 | 39 | #### المزيد من القراءة 40 | 41 | * [Automate your project with Apache Ant][apache_ant_tutorial] 42 | * [Expert PHP Deployments][expert_php_deployments] - كتاب مجاني يشرح عملية النشر باستخدام Capistrano و Phing و Vagrant. 43 | * [Deploying PHP Applications][deploying_php_applications] - كتاب مدفوع من أفضل الممارسات والأدوات لنشر تطبيقات PHP. 44 | 45 | ### تموين السيرفر 46 | 47 | إدارة وضبط السيرفر هي مهمة شاقة خصوصاً عندما تكون موجهة على عدة سيرفرات. هنالك أدوات تتعامل مع هذا الوضع وأتمتتة البنية التحتية للتأكد من أنه لديك سيرفرات تم ضبطها بطريقة مثلى. عادة ما تتكامل مع استضافات سحابية مثل Amazon Web Service و Heroku و DigitalOcean وغيرها. لإدارة الوحدات التي تقوم بتنسيق التطبيق بشكل أبسط. 48 | 49 | [Ansible] وهي أداة لإدارة البنية التحتية باستخدام ملفات YAML. من السهل البدء بالاستخدام وإدارة وتنسيق تطبيقات كبيرة ومعقدة. هنالك API لإدارة الوحدات السحابية باستخدام بضع أدوات. 50 | 51 | [Puppet] وهي أداة تستخدم ملفات ولغة خاصة بها لإدارة وضبط السيرفرات. يمكن استخدامها في Master/Client وايضا يمكن استخدامها في طور "master-less". في طور master/client يقوم Client باقتراع الماستر المركزي لطلب ضبط جديد في وحدات زمنية متفرقة لتحديث نفسها إذا لزم الأمر. وفي طور master-less يتم إرسال التحديثات إلى النقاط. 52 | 53 | [Chef] وهو إطار عمل قوي مبني على Ruby يمكن من بناء بيئة السيرفر بالكامل أو صناديق افتراضية وترتبط بشكل جيد باستخدام خدمة في Amazon Web Services تسمى OpsWorks. 54 | 55 | #### المزيد من القراءة: 56 | 57 | * [An Ansible Tutorial][an_ansible_tutorial] 58 | * [Ansible for DevOps][ansible_for_devops] - كتاب مدفوع لكل شيء باستخدام Ansible 59 | * [Ansible for AWS][ansible_for_aws] - كتاب مدفوع لربط Ansible مع Amazon Web Services 60 | * [Three part blog series about deploying a LAMP application with Chef, Vagrant, and EC2][chef_vagrant_and_ec2] 61 | * [Chef Cookbook which installs and configures PHP and the PEAR package management system][Chef_cookbook] 62 | * [Chef video tutorial series][Chef_tutorial] 63 | 64 | ### الربط المستمر Continuous Integration 65 | 66 | > الربط المستمر هو ممارة في تطوير البرامج حين يكون هنالك أعضاء فريق يقومون بربط أعمالهم بشكل متواصل، عادة ما يكون كل 67 | > شخص بالربط على الأقل مرة في اليوم - مما يعني العديد من الربط في خلال اليوم الواحد. العديد من الفرق ترى أن استخدام هذه 68 | > الممارسة يؤدي إلى خفض فعلي لمشاكل الربط وتتيح للفرق أن تقوم بتطوير برامج متماسكة بسرعة. 69 | 70 | *-- مارتين فولر* 71 | 72 | هنالك طرق مختلفة لتطبيق الربط المستمر في PHP. يعد [Travis CI] من أفضلهم فهو يقوم بتحقيق الربط المتواصل بشكل حتى للمشاري الصغيرة. 73 | وهو عبارة عن خدمة مستضافة لمجتمع المصدر المفتوح. وترتبط مع GitHub وتوفر دعم من الدرجة الأولى للعديد من اللغات من ضمنها PHP. 74 | 75 | #### المزيد من القراءة: 76 | 77 | * [Continuous Integration with Jenkins][Jenkins] 78 | * [Continuous Integration with PHPCI][PHPCI] 79 | * [Continuous Integration with Teamcity][Teamcity] 80 | 81 | 82 | [buildautomation]: http://en.wikipedia.org/wiki/Build_automation 83 | [Phing]: http://www.phing.info/ 84 | [Apache Ant]: http://ant.apache.org/ 85 | [Capistrano]: https://github.com/capistrano/capistrano/wiki 86 | [phpdeploy_capistrano]: http://www.davegardner.me.uk/blog/2012/02/13/php-deployment-with-capistrano/ 87 | [phpdeploy_deployer]: http://www.sitepoint.com/deploying-php-applications-with-deployer/ 88 | [Chef]: https://www.chef.io/ 89 | [chef_vagrant_and_ec2]: http://www.jasongrimes.org/2012/06/managing-lamp-environments-with-chef-vagrant-and-ec2-1-of-3/ 90 | [Chef_cookbook]: https://github.com/chef-cookbooks/php 91 | [Chef_tutorial]: https://www.youtube.com/playlist?list=PL11cZfNdwNyPnZA9D1MbVqldGuOWqbumZ 92 | [apache_ant_tutorial]: http://net.tutsplus.com/tutorials/other/automate-your-projects-with-apache-ant/ 93 | [Travis CI]: https://travis-ci.org/ 94 | [Jenkins]: http://jenkins-ci.org/ 95 | [PHPCI]: http://www.phptesting.org/ 96 | [Teamcity]: http://www.jetbrains.com/teamcity/ 97 | [Deployer]: http://deployer.org/ 98 | [Rocketeer]: http://rocketeer.autopergamene.eu/ 99 | [Magallanes]: http://magephp.com/ 100 | [expert_php_deployments]: http://viccherubini.com/assets/Expert-PHP-Deployments.pdf 101 | [deploying_php_applications]: http://www.deployingphpapplications.com 102 | [Ansible]: https://www.ansible.com/ 103 | [Puppet]: https://puppet.com/ 104 | [ansible_for_devops]: https://leanpub.com/ansible-for-devops 105 | [ansible_for_aws]: https://leanpub.com/ansible-for-aws 106 | [an_ansible_tutorial]: https://serversforhackers.com/an-ansible-tutorial 107 | -------------------------------------------------------------------------------- /_posts/13-01-01-Virtualization.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: الإفتراضية 3 | isChild: false 4 | anchor: virtualization 5 | --- 6 | 7 | # الإفتراضية {#virtualization_title} 8 | 9 | تشغيل التطبيق على بيئات مختلفة من تلك التي في بيئة التطوير والعمل النهائي تسبب في ظهور أخطاء غريبة. ومن الصعب إدارة 10 | البيئات المختلفة محدثة وتعمل بنفس الإصدارات لكل المكتبات عندما يكون التطوير في فريق. 11 | 12 | إذا كنت تقوم بالتطوير على Windows وتقوم بالنشر على Linux أو أي شيء غير ويندوز أو يتم التطوير في فريق يجب عليك استخدام 13 | آلات افتراضية. قد يكون غريباً بعض الشء ولكن بجانب الإفتراضية المعروفة للبيئة مثل برامج VMWare و VirtualBox هنالك أدوات 14 | إضافية تساعد في إنشاء بيئة إقتراضية بخطوات سهلة وبسيطة. 15 | -------------------------------------------------------------------------------- /_posts/13-02-01-Vagrant.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Vagrant 3 | isChild: true 4 | anchor: vagrant 5 | --- 6 | 7 | ## Vagrant {#vagrant_title} 8 | 9 | يساعد [Vagrant] على بناء صناديق افتراضية فوق ما يعرف بالبيئة الإفتراضية Virtual Environment ويتم ضبط هذه البيئة بناءً 10 | على ملف ضبط واحد. هذه الصناديق يمكن تنصيبها بشكل يدوي أو باستخدام أدوات "التموين" مثل [Puppet] أو [Chef]. تموين الصناديق 11 | هو طريقة فعالة لضمان أن جميع الصناديق تعمل بشكل متساوي وتزيل كل التعقيدات لتنصيب الأوامر. ويمكن أيضاً تدمير الصناديق وإعادة 12 | إنشائها بدون أي خطوات يدوية مما يجعل من السهل انشاء نسخ جديدة. 13 | 14 | يقوم Vagrant بانشاء مجلدات لكي تقوم بمشاركة الكود مابين الجهاز الحلي والجهاز الإفتراضي مما يعني أنه يمكن إنشاء وتعديل ملفاتك 15 | وتنفيذها من الجهاز الحالي من دون الحاجة للدخول للجهاز الإفتراضي. 16 | 17 | ### القليل من المساعدة 18 | 19 | إذا كنت تريد المساعدة للبدء في استخدام Vagrant هنالك بعض الخدام التي قد تكون مفيدة لك: 20 | 21 | - [Rove][Rove]: خدمة تتيح لك أن تقوم بتوليد بنائية Vagrant بشكل مسبق بناءً على خيارات ويتم التموين باستخدام Chef. 22 | 23 | - [Puphpet][Puphpet]: أداة سهلة تدار باستخدام واجهة رسومية لتنصيب أجهزة إفتراضية لتطوير PHP. **تركز فقط على PHP**. بجانب 24 | أجهزة افتراضية يمكن استخدامها للنشر على خدمات استضافة سحابية أيضاً. ويتم التموين باستخدام Puppet. 25 | 26 | - [Protobox][Protobox]: وهي طبقة فوق Vagrant وهو تطبيق ويب بواجهة استخدام لتنصيب أجهزة افتراضية لتطوير الويب. تستخدم ملف 27 | YAML واحد للتحكم بكل شيء يتم تنصيبه داخل الجهاز الإفتراضي. 28 | 29 | - [Phansible][Phansible]: يوفر طريقة سهلة لاستخدام واجهة تساعد في توليد خطط Ansible للمشاريع المبنية بلغة PHP. 30 | 31 | 32 | [Vagrant]: http://vagrantup.com/ 33 | [Puppet]: http://www.puppetlabs.com/ 34 | [Chef]: https://www.chef.io/ 35 | [Rove]: http://rove.io/ 36 | [Puphpet]: https://puphpet.com/ 37 | [Protobox]: http://getprotobox.com/ 38 | [Phansible]: http://phansible.com/ 39 | -------------------------------------------------------------------------------- /_posts/13-03-01-Docker.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Docker 3 | isChild: true 4 | anchor: docker 5 | --- 6 | 7 | ## Docker {#docker_title} 8 | 9 | [Docker] هو بديل اخف ثقلاً من استخدام جهاز كامل في بيئة تشغيل افتراضية وذلك لأنه يعتمد على ما يسمى الحاويات "Containers". الحاوية هي عبارة عن بناء من مجموعة أجزاء تقوم في ابسط صورها بوظيفة واحدة فقط، كأن تقوم بتشغيل خادم ويب. الصورة "Image" وهي الحزمة التي تقوم باستخدامها لبناء حاوية. وDocker لديه مستودع مليء بالصور المبنية مسبقاً. 10 | تطبيقاً على حزمة بيئة التطوير LAMP سيكون هناك ثلاثة حاويات: حاوية الخادم، وحاوية مترجم PHP وحاوية قاعدة البيانات MySQL. كما هو الحال مع Vagrant يمكنك تحديد الملفات المسموحة بالمشاركة لكي تستخدمها الحاوية. 11 | بالإمكان ان تقوم بتوليد حاويات باستخدام سطر الأوامر (انظر المثال ادناه) أو لتسهيل عملية التطوير والصيانة يمكن انشاء ملف `docker-compose.yml` مع ملفات مشروعك، وتوصف فيه المتطلبات وكيفية تواصل الحاويات فيما بينها. 12 | يساعد Docker في تطوير عدة مواقع مع الحفاظ على العزلة التامة التي يصعب الحصول عليها بدون انشاء أجهزة افتراضية لكل موقع على حدة، ولكن هذا قد يتعارض مع مصادر الجهاز المتوفر، كالمساحة المتوفرة في القرص الصلب أو الزمن المستهلك في إبقاء كل الأجهزة محدثة. فالكفاءة تتمثل أيضا في انه سهل الاستخدام ويتم حفظ نسخة واحدة من كل صورة، بالإضافة لذلك ان الحاويات تستهلك كمية قليلة من ذاكرة النظام وتقوم بمشاركة لب نظام التشغيل الحالي. إذا يمكن انشاء وتشغيل عدد أكبر من الخوادم في نفس الوقت. وعملية انشاء وتشغيل وإيقاف وتدمير الحاويات يتطلب بضع ثوان فقط، ولا داعي لانتظار زمن اقلاع لنظام تشغيل. 13 | 14 | ### مثال: تنفيذ تطبيق PHP في Docker 15 | 16 | بعد [تنصيب docker][docker-install]على الجهاز، يمكن تشغيل خادم ويب باستخدام امر واحد. 17 | الامر التالي سيقوم بتحميل مخدم Apache كامل الوظائف مع اخر نسخة PHP واسناد المسار المحلي `/path/to/your/php/files` كالدليل الجذر له، ويمكن استعراض الصفحات بزيارة `http://localhost:8080`. 18 | 19 | {% highlight console %} 20 | docker run -d --name my-php-webserver -p 8080:80 -v /path/to/your/php/files:/var/www/html/ php:apache 21 | {% endhighlight %} 22 | 23 | بعد تنفيذ `docker run` عندها الحاوية تكون إنشئت وقيد العمل في الخلفية. 24 | إذا كنت تريد إيقاف أو تشغيل الحاوية مرة أخرى يمكن استخدام الإسم المقرون وببساطة تنفيذ 25 | `docker stop my-php-webserver` و `docker start my-php-webserver` بدون إدراج الأوامر المذكورة أعلاه مرة أخرى. 26 | 27 | ### إعرف المزيد عن Docker 28 | 29 | الأمر أعلاه يوضح كيفية انشاء خادم بصورة سريعة. هنالك الكثير ما يمكن تطبيقه، وهنالك آلاف الصور التي يمكن استخدامها على [Docker Hub][docker-hub]. قم بإمضاء بعض الوقت في تعلم وفهم المصطلحات وقراءة الدليل [Docker User Guide][docker-doc] لكي تستفيد بكل ما هو متاح. 30 | لا تقم ابدا بتنفيذ أي أوامر قمت بتحميلها او وجدتها في مكان ما بدون التأكد من امانها، الصور غير الرسمية لبعض التطبيقات قد لا تحتوي على اخر الرقع والتحديثات الأمنية، فان كان لديك شك، قم باستخدام فقط [المستودعات الرسمية][docker-hub-official]. 31 | موقع [PHPDocker.io] يقوم بتوليد كل الملفات التي تحتاجها للاستخدام في حزمة LAMP/LEMP مضمنة بنسخة PHP من اختيارك مع اللاحقات. 32 | 33 | * [Docker Website][Docker] 34 | * [Docker Installation][docker-install] 35 | * [Docker User Guide][docker-doc] 36 | * [Docker Hub][docker-hub] 37 | * [Docker Hub - official images][docker-hub-official] 38 | 39 | [Docker]: http://docker.com/ 40 | [docker-hub]: https://hub.docker.com/ 41 | [docker-hub-official]: https://hub.docker.com/explore/ 42 | [docker-install]: https://docs.docker.com/installation/ 43 | [docker-doc]: https://docs.docker.com/userguide/ 44 | [PHPDocker.io]: https://phpdocker.io/generator 45 | -------------------------------------------------------------------------------- /_posts/14-01-01-Caching.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: التخزين المؤقت 3 | isChild: false 4 | anchor: caching 5 | --- 6 | 7 | # التخزين المؤقت {#caching_title} 8 | 9 | تعتبر PHP سريعة في نفسها، ولكن بعض الإختناقات قد تحدث عندما تقوم بعمل إتصالات خارجية أو إدراج ملفات أو غيرها. 10 | لحسن الحظ هنالك عدة إدوات متوفرة لتقوم بتسريع أجزاء محددة في التطبيقات أو تقليل عدد مرات استهلاك تنفيذ هذه المهام في كل مرة. 11 | -------------------------------------------------------------------------------- /_posts/14-02-01-Opcode-Cache.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: التخزين المؤقت لشفرة التشغيل 3 | isChild: true 4 | anchor: opcode_cache 5 | --- 6 | 7 | ## التخزين المؤقت لشفرة التشغيل {#opcode_cache_title} 8 | 9 | عندما يتم تنفيذ ملف PHP يجب أن يتم تجميع الملف وتحويله [لشيفرة تشغير opcodes](http://php.net/manual/en/internals2.opcodes.php) (وهي لغة أوامر للمعالج). إذا لم يتغير المصدر البرمجي فإن الشيفرة المصدرية ستظل كما هي، إذاً هذه الخطوة التجميعية ستكون مضيعة لمصدر معالجة. 10 | 11 | التخزين المؤقت للشيفرة التشغيلية تمنع تكرار التجميعات عبر حفظ الشيفرة في الذاكرة واستخدامها عند الإستدعاء. فهي فعلياً ستقوم بفحص التوقيع أو زمن التعديل للملف أولاً للتأكد من أي تعديلات قد طرأت عليه. 12 | 13 | من الواضح أن تخزين شيفرة التشغيل سيؤثر بشكل ايجابي على سرعة التطبيق. منذ الإصدارة PHP 5.5 هنالك محرك مدمج واحد وهو [Zend OPcache][opcache-book]. باختلاف توزيعة PHP لديك عادة ما تكون هذه الخاصية مفعلة بشكل افتراضي - ابحث عن [opcache.enable](http://php.net/manual/en/opcache.configuration.php#ini.opcache.enable) في مخرجات الدالة `phpinfo()` للتأكد. للإصدارات القديمة هنالك لاحقة PECL يمكن استخدامها. 14 | 15 | إقرأ المزيد عن التخزين المؤقت للشيفرة البرمجية opcode caches: 16 | 17 | * [Zend OPcache][opcache-book] (مدمجة في PHP منذ الإصدارة 5.5) 18 | * Zend OPcache (رسمياً بالإسم Zend Optimizer+) صارت الآن [مفتوحة المصدر][Zend Optimizer+] 19 | * [APC] - PHP 5.4 والإصدارات الأقدم 20 | * [XCache] 21 | * [WinCache] (لاحقة للإستخدام في MS Windows Server) 22 | * [قائمة بكل مسرعات PHP على ويكيبيديا][PHP_accelerators] 23 | 24 | 25 | [opcache-book]: http://php.net/book.opcache 26 | [APC]: http://php.net/book.apc 27 | [XCache]: http://xcache.lighttpd.net/ 28 | [Zend Optimizer+]: https://github.com/zendtech/ZendOptimizerPlus 29 | [WinCache]: http://www.iis.net/download/wincacheforphp 30 | [PHP_accelerators]: http://en.wikipedia.org/wiki/List_of_PHP_accelerators 31 | -------------------------------------------------------------------------------- /_posts/14-03-01-Object-Caching.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: تخزين الكائنات 3 | isChild: true 4 | anchor: object_caching 5 | --- 6 | 7 | ## تخزين الكائنات {#object_caching_title} 8 | 9 | هنالك العديد من الأحيان يكون فيها من المفيد القيام بتخزين كائنات بشكل مؤقت في مصدرك مثل البيانات التي من الصعب الحصول 10 | عليها أو إتصالات قاعدة البيانات عندما تكون النتائج من الإستعلامات نادراً ما تتغير. يمكن استخدام التخزين المؤقت للكائنات 11 | لمخزن بيانات بعد استرجاعها ثم وضعها مباشرة من المخزن المؤقت للإستعلامات القادمة يمكن الحصول عندها على تطور ملحوظ في الأداء 12 | بجانب تقليل الحمل على سيرفرات قاعدة البيانات. 13 | 14 | العديد من حلول المخازن المؤقتة المشهورة من النوع bytecode تتيح إمكانية تخزين بيانات أخرى أيضاً مما يعني سبب آخر يجعلك 15 | تقوم بالإستفادة منها. يتيح كل من APCuو XCache و WinCache يقوموا بتوفير API لحفظ البيانات من كود PHP لمخازن بياناتهم 16 | على الذاكرة. 17 | 18 | أشهر أنظمة تخزين الكائنات هما APCu و memcached. APCu هو خيار ممتاز لتخزين الكائنات وتضم واجهة API سهلة الإستخدام لإضافة 19 | بياناتك الخاصة إلى الذاكرة وسهل التنصيب والإستخدام. التقييد الوحيدهو أنه مقيد بالسيرفر المنصب عليه. 20 | Memcached يتم تنصيبه كخدمة منفصلة ويمكن أن يتم الوصول إليه عبر الشبكة، مما يعني أنه يمكن تخزين الكائنات في مخازن بيانات 21 | فائقة السرعة في أماكن مركزية والعديد من الأنظمة تتمكن من الإستخدام منها. 22 | 23 | لاحظ أنه عند تشغيل PHP في طور Fast-CGI داخل سيرفر الويب، عندها كل عمليات PHP سيكون لديها المخزن المؤقت الخاص بها، مثلاً 24 | بيانات APCu سيتكون منفصلة تماماً ولن يتم مشاركتها مع العمليات الأخرى. في هذه الحالات قد تضطر لإستخدام memcached عوضاً عن الأول. 25 | نظراً لانه غير مقترن بأي عملية PHP. 26 | 27 | في التواصل الشبكي يحصل APCu على أعلى أداء نظراً للطريقة التي تتيح سرعة الوصول، ولكن بالمقابل memcached قابلة للتطوير 28 | بشكل أسرع وأكبر. إذا كنت لا تتوقع انه سيكون لديك عدة سيرفرات تخدم تطبيقك عندها لن تستفيد من خواص memcached، إذاً APCu 29 | هو أفضل خيار لتخزين الكائنات. 30 | 31 | أمثلة إستخدام منطقية لـ APCu: 32 | 33 | {% highlight php %} 34 | 18 | * @link http://www.phpdoc.org/docs/latest/index.html 19 | */ 20 | class DateTimeHelper 21 | { 22 | /** 23 | * @param mixed $anything Anything that we can convert to a \DateTime object 24 | * 25 | * @throws \InvalidArgumentException 26 | * 27 | * @return \DateTime 28 | */ 29 | public function dateTimeFromAnything($anything) 30 | { 31 | $type = gettype($anything); 32 | 33 | switch ($type) { 34 | // Some code that tries to return a \DateTime object 35 | } 36 | 37 | throw new \InvalidArgumentException( 38 | "Failed Converting param of type '{$type}' to DateTime object" 39 | ); 40 | } 41 | 42 | /** 43 | * @param mixed $date Anything that we can convert to a \DateTime object 44 | * 45 | * @return void 46 | */ 47 | public function printISO8601Date($date) 48 | { 49 | echo $this->dateTimeFromAnything($date)->format('c'); 50 | } 51 | 52 | /** 53 | * @param mixed $date Anything that we can convert to a \DateTime object 54 | */ 55 | public function printRFC2822Date($date) 56 | { 57 | echo $this->dateTimeFromAnything($date)->format('r'); 58 | } 59 | } 60 | {% endhighlight %} 61 | 62 | هذا التوثيق للكلاس بأكمله به وسم [@author] و [@link]. فوسم [@author] يستخدم لتوثيق محرر الكود ويمكن تكراره لتوثيق عده محررين. 63 | والوسم [@link] يستخدم لربط موقع يوضح العلاقة ما بين الموقع والكود. 64 | 65 | بداخل الكلاس في العملية الأولى بها وسم [@param] لتوثيق نو واسم ووصف المعطى الممر للعملية. بالإضافة لوسمي [@return] و [@throws] لتوثيق نوع الإرجاع وتوضيح أي إستثناءات يمكن رميها. 66 | 67 | العملية الثانية والثالثة متماثلتين فلديهما الوسم [@param] كما في العملية الأولى. الإختلاف المهم ما بين العملية الثانية والثالثة هي وجود/عدم وجودة وسم[@return]. 68 | `@return void` تعدي تنبيهنا بأنه لا يوجد مخرجات، وأيضاً إهمال كتابة `@return void` يعطي نفس النتيجة (لا يوجد مرتجعات من العملية). 69 | 70 | 71 | [tags]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/index.html 72 | [PHPDoc manual]: http://www.phpdoc.org/docs/latest/index.html 73 | [@author]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/author.html 74 | [@link]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/link.html 75 | [@param]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/param.html 76 | [@return]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/return.html 77 | [@throws]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/throws.html 78 | -------------------------------------------------------------------------------- /_posts/16-01-01-Resources.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: المصادر 3 | isChild: false 4 | anchor: resources 5 | --- 6 | 7 | # المصادر {#resources_title} 8 | -------------------------------------------------------------------------------- /_posts/16-02-01-From-the-Source.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: من المصادر الأصلية 3 | isChild: true 4 | anchor: from_the_source 5 | --- 6 | 7 | ## من المصادر الأصلية {#from_the_source_title} 8 | 9 | * [موقع PHP](http://php.net/) 10 | * [دليل توثيق PHP](http://php.net/docs.php) 11 | -------------------------------------------------------------------------------- /_posts/16-03-01-People-to-Follow.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: أشخاص تتابعهم 3 | isChild: true 4 | anchor: people_to_follow 5 | --- 6 | 7 | ## أشخاص تتابعهم {#people_to_follow_title} 8 | 9 | من الصعب إيجاد أعضاء في مجتمع PHP ذوي خبرة وعلم كبيرين في البداية. 10 | يمكن إيجاد قائمة جيدة من أعضاء مجتمع PHP وحساباتهم تويتر في: 11 | 12 | * [New Relic: 25 PHP Developers to Follow Online][php-developers-to-follow] 13 | * [OGProgrammer: How to get connected with the PHP community][og-twitter-list] 14 | 15 | 16 | [php-developers-to-follow]: https://blog.newrelic.com/2014/05/02/25-php-developers-follow-online/ 17 | [og-twitter-list]: https://www.ogprogrammer.com/2017/06/28/how-to-get-connected-with-the-php-community/ 18 | -------------------------------------------------------------------------------- /_posts/16-04-01-Mentoring.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: الإشراف والتوجيه 3 | isChild: true 4 | anchor: mentoring 5 | --- 6 | 7 | ## الإشراف والتوجيه {#mentoring_title} 8 | 9 | * [php-mentoring.org](http://php-mentoring.org/) - إشراف واحد لواحد رسمي في مجتمع PHP. 10 | -------------------------------------------------------------------------------- /_posts/16-05-01-PHP-PaaS-Providers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: مزودي PHP PaaS 3 | isChild: true 4 | anchor: php_paas_providers 5 | --- 6 | 7 | ## مزودي PHP PaaS {#php_paas_providers_title} 8 | 9 | * [PagodaBox](https://pagodabox.io/) 10 | * [AppFog](https://www.ctl.io/appfog/) 11 | * [Heroku](https://devcenter.heroku.com/categories/php) 12 | * [fortrabbit](https://www.fortrabbit.com/) 13 | * [Engine Yard Cloud](https://www.engineyard.com/features) 14 | * [Red Hat OpenShift Platform](https://www.openshift.com/) 15 | * [AWS Elastic Beanstalk](https://aws.amazon.com/elasticbeanstalk/) 16 | * [Windows Azure](http://www.windowsazure.com/) 17 | * [Google App Engine](https://cloud.google.com/appengine/docs/php/) 18 | * [Jelastic](http://jelastic.com/) 19 | * [Platform.sh](https://platform.sh/) 20 | * [Cloudways](https://www.cloudways.com/en/) 21 | * [IBM Bluemix Cloud Foundry](https://console.ng.bluemix.net/) 22 | * [Pivotal Web Service Cloud Foundry](https://run.pivotal.io/) 23 | 24 | للإطلاع على أي نسخة تعمل هذه الخدمات قم بالذهاب الى هنا [PHP Versions](http://phpversions.info/paas-hosting/). 25 | -------------------------------------------------------------------------------- /_posts/16-06-01-Frameworks.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: أطر العمل 3 | isChild: true 4 | anchor: frameworks 5 | --- 6 | 7 | ## أطر العمل {#frameworks_title} 8 | 9 | بدلاً من إعادة اختراع العجلة ، العديد من مطوري PHP يستخدمون إطر عمل لبنا تطبيقاتهم. أطر العمل تجرد العديد من المستويات الدنيا 10 | ومشاكلها وتعقيداتها وتقوم بتوفير واجهة مفيدة وسهلة الإستخدام لإنجاز المهام المعتادة. 11 | 12 | لا يتوجب عليك استخدام إطار عمل لكل مشروع. فبعض الأحيان تكون الطريقة التقليدية للكتابة هي الوسيلة المثلى للعمل، ولكن 13 | إذا كنت تريد إطار عمل، عندها هنالك ثلاث أنواع متوفرة: 14 | 15 | * أطر العمل الصغيرة 16 | * أطر العمل الكاملة 17 | * أطر عمل مكونات 18 | 19 | فأطر العمل الصغير هي عبارة عن ربط لطلبات HTTP إلى متحكمات ودوال وغيرها وعادة ما تكون سهلة وسريعة جداً وبعض الأحيان تكون 20 | مع بضع مكتبات للمساعدة في التطوير كمساعدات للإتصال والعمل علىقاعدة البيانات وما شابهها. عادة ما تستخدم لبناء خدمات HTTP عن بعد. 21 | 22 | العديد من أطر العمل تضيف عدد من المميزات على قالب أطر العمل الصغير وهذه الأطر هي أطر العمل الكاملة. وعادة ما يكون مدمجاً 23 | فيها حزم ORM و مصداقة وتحقق. 24 | 25 | أطر عمل المكونات عادة ما تكون تجميعة من مكتبات مخصصة لعمل وظيفة محددة. يمكن استخدام بضع منها سوياً لعمل أطار عمل صغير أو كامل. 26 | 27 | * [Popular PHP Frameworks](https://github.com/codeguy/php-the-right-way/wiki/Frameworks) -------------------------------------------------------------------------------- /_posts/16-07-01-Components.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: المكونات 3 | isChild: true 4 | anchor: components 5 | --- 6 | 7 | ## المكونات {#components_title} 8 | 9 | كما هو مذكور أعلاه "المكونات" هي هدف معروف لإنشاء ونشر وزرع ومشاركة الكود. العديد من حاويات المكونات موجودة بالفعل 10 | اشهرها: 11 | 12 | * [Packagist] 13 | * [PEAR] 14 | 15 | كلاهما حاويات لديها أدوات سطور أوامر تساعدك لتنصيب وتحديث وترقية المكونات وقد تم شرحها في فصل [Dependency Management]. 16 | 17 | هنالك أيضاً مكونات خاصة بأطر عمل ومزودين والتي لا تتيح أي أطار عمل على الإطلاق. هذه المشاريع توفع مصادر اخرى من الحزم 18 | المتطابقة مع القليل من الإعتمادية على حزم أخرى أو أطر عمل معينة. 19 | 20 | مثلاً يمك استخدام [FuelPHP Validation package] "حزمة للتحقق" من دون الحاجة لاستخدام أطار عمل FuelPHP. 21 | 22 | * [Aura] 23 | * [FuelPHP] 24 | * [Hoa Project] 25 | * [Orno] 26 | * [Symfony Components] 27 | * [The League of Extraordinary Packages] 28 | * مكونات من Laravel Illuminate components: 29 | * [IoC Container] 30 | * [Eloquent ORM] 31 | * [Queue] 32 | 33 | _[Illuminate components] قريباً سيتم عزله من إطار عمل Laravel. حتى الآن أفضل المكونات المعزولة من إطار عمل Laravel 34 | قد تم سردها أعلاه._ 35 | 36 | 37 | [Packagist]: /#composer_and_packagist 38 | [PEAR]: /#pear 39 | [Dependency Management]: /#dependency_management 40 | [FuelPHP Validation package]: https://github.com/fuelphp/validation 41 | [Aura]: http://auraphp.com/framework/2.x/en/ 42 | [FuelPHP]: https://github.com/fuelphp 43 | [Hoa Project]: https://github.com/hoaproject 44 | [Orno]: https://github.com/orno 45 | [Symfony Components]: http://symfony.com/doc/current/components/index.html 46 | [The League of Extraordinary Packages]: http://thephpleague.com/ 47 | [IoC Container]: https://github.com/illuminate/container 48 | [Eloquent ORM]: https://github.com/illuminate/database 49 | [Queue]: https://github.com/illuminate/queue 50 | [Illuminate components]: https://github.com/illuminate 51 | -------------------------------------------------------------------------------- /_posts/16-08-01-Sites.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: مصادر أخرى مفيدة 3 | isChild: true 4 | anchor: other_resources 5 | --- 6 | 7 | ## مصادر أخرى مفيدة {#other_resources_title} 8 | 9 | ### أوراق غش 10 | 11 | * [PHP Cheatsheets](http://phpcheatsheets.com/) - لإختبار ومقارنة ومعالجة المتغيرات واختبارها في عدة إصدارات PHP 12 | * [PHP Security Cheatsheet](https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet) 13 | 14 | ### المزيد من أفضل الممارسات 15 | 16 | * [PHP Best Practices](https://phpbestpractices.org/) 17 | * [Best practices for Modern PHP Development](https://www.airpair.com/php/posts/best-practices-for-modern-php-development) 18 | 19 | ### اخبار PHP ومجتمعات تطوير الويب 20 | يمكن ان تشترك في القوائم البريدية الأسبوعية لتبقى مواكبا بالمكتبات والاخبار والاحداث الجديدة، والتنبيهات العامة، كما هنالك مصادر يتم نشرها بين الحين والأخر: 21 | * [PHP الاسبوعية](http://www.phpweekly.com) 22 | * [JavaScript الاسبوعية](http://javascriptweekly.com) 23 | * [HTML5 الاسبوعية](http://html5weekly.com) 24 | * [Mobile Web الاسبوعية](http://mobilewebweekly.co) 25 | * [أسبوعية من منصات اخرى](https://github.com/jondot/awesome-weekly). 26 | 27 | ### عالم PHP 28 | 29 | * [PHP Developer blog](http://blog.phpdeveloper.org/) 30 | -------------------------------------------------------------------------------- /_posts/16-09-01-Videos.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: دروس فيديو 3 | isChild: true 4 | anchor: videos 5 | --- 6 | 7 | ## دروس فيديو {#videos} 8 | 9 | ### قنوات YouTube 10 | * [PHP Academy](https://www.youtube.com/user/phpacademy) 11 | * [The New Boston](https://www.youtube.com/user/thenewboston) 12 | * [Sherif Ramadan](https://www.youtube.com/user/businessgeek) 13 | * [Level Up Tuts](https://www.youtube.com/user/LevelUpTuts) 14 | 15 | ### دروس فيديو مدفوعة 16 | 17 | * [Standards and Best practices](http://teamtreehouse.com/library/standards-and-best-practices) 18 | * [PHP Training on Pluralsight](http://www.pluralsight.com/search/?searchTerm=php) 19 | * [PHP Training on Lynda.com](http://www.lynda.com/search?q=php) 20 | * [PHP Training on Tutsplus](http://code.tutsplus.com/categories/php/courses) 21 | * [Laracasts](https://laracasts.com/) 22 | -------------------------------------------------------------------------------- /_posts/16-10-01-Books.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: كتب 3 | isChild: true 4 | anchor: books 5 | --- 6 | 7 | ## كتب {#books_title} 8 | 9 | هنالك العديد من كتب PHP للأسف بات بعضها قديم جداً وغير دقيق. بالتحديد الكتب التي تتحدث عن "PHP 6" فهو إصدار غير موجود ولن يكون موجوداً اصلاً. لأن الإصدار الكبير بعد PHP 5.6 هو "PHP7" [partly because of this](https://wiki.php.net/rfc/php6). 10 | 11 | هذا الفصل يهدف إلى أن يكون مصدر للكتب الموصى بها في تطوير PHP بشكل عام. إذا كان لديك كتاب تريد إضافته قم بنشر طلب دمج 12 | أو Pull-request، وسيتم مراجعة محتواه. 13 | 14 | ### كتب مجانية 15 | 16 | * [PHP Pandas](http://daylerees.com/php-pandas/) - يهدف لتدريب أي شخص ليكون مطور ويب. 17 | * [PHP The Right Way](https://leanpub.com/phptherightway/) - هذا الموقع متوفر على شكل كتاب مجاناً. 18 | * [Using Libsodium in PHP Projects](https://paragonie.com/book/pecl-libsodium) - دليل لإستخدام لاحقة Libsodium لعمل شفرات 19 | حديثة وسهل وسريعة. 20 | 21 | ### كتب مدفوعة 22 | 23 | * [Build APIs You Won't Hate](https://apisyouwonthate.com/) - الكل يريد واجهة API، إذاً يستوجب عليك أن تتعلم كيف تبنيها. 24 | * [Modern PHP](http://shop.oreilly.com/product/0636920033868.do) - يقوم بتغطية ممزيات PHP الحديثة وأفضل الممارسات والإختبار والضبط والنشر وتنصيب بيئات تطوير. 25 | * [Building Secure PHP Apps](https://leanpub.com/buildingsecurephpapps) - تعلم مبادء الحماية التي يكتسبها المطور الخبير عبر سنين الخبرة، 26 | كلها مكثفة في كتاب واحد سهل وسريع. 27 | * [Modernizing Legacy Applications In PHP](https://leanpub.com/mlaphp) - قم بالتحكم في الكود عبر سلسلة من الخطوات المحددة والسريعة. 28 | * [Securing PHP: Core Concepts](https://leanpub.com/securingphp-coreconcepts) - دليل لبعض أشهر شروط الحماية وتوفير بعض الأمثلة. 29 | * [Scaling PHP](http://www.scalingphpbook.com/) - توقف عن اللعب كمدير نظام وقم بالعودة إلى البرمجة. 30 | * [Signaling PHP](https://leanpub.com/signalingphp) - PCNLT هو مساعدة مماتزة عندما تقوم بكتابة تطبيقات PHP تعمل على سطور الأوامر 31 | * [The Grumpy Programmer's Guide To Building Testable PHP Applications](https://leanpub.com/grumpy-testing) - تعلم كيفية كتابة 32 | كود قابل للتجربة والإختبار لا يتوقف. 33 | * [Minimum Viable Tests](https://leanpub.com/minimumviabletests) - من أقدم مبشري الإختبار والتجربة في PHP "كريس هارتجيس" يقوم بتوضيح أقل ما تريد أن تعرفه لكي تبدأ. 34 | * [Domain-Driven Design in PHP](https://leanpub.com/ddd-in-php) - استعرض امثلة حقيقية لمفهوم DDD التصميم المساق بالنطاق، وأساليب وهياكل وانماط تصميم تكتيكية والتكامل مع الإطار العام. 35 | -------------------------------------------------------------------------------- /_posts/17-01-01-Community.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: المجتمع 3 | isChild: false 4 | anchor: community 5 | --- 6 | 7 | # المجتمع {#community_title} 8 | 9 | مجمع PHP هو مجتمع متنوع وكبير، وأعضائها جاهزون ومستعدون لخدمة مبرمجي PHP الجدد. 10 | تشجع للإنضمام إلى مجموعة مستخدمي PHP وحضور مؤتمرات PHP لتعلم الكثير عن أفضل الممارسات 11 | موجودة. يمكنك التواجد في قناة #phpc في IRC على [irc.freenode.com][php-irc] وقم بمتابعة حساب تويتر 12 | [@phpc][phpc-twitter]. قم بالذهاب إلى هناك وقم بمقابلة مطورين جدد وتعلم مواضيع جديدة، وفوق كل هذا 13 | قم تكوين صداقات! مصادر لمجتمعات اخرى تضم مجموعة Google+ PHP [Programmer community][php-programmers-gplus] 14 | و [StackOverflow][php-so]. 15 | 16 | [قراءة المزيد عن الأحداث في رزنامة أحداث PHP][php-calendar] 17 | 18 | 19 | [php-irc]: http://webchat.freenode.net/?channels=phpc 20 | [phpc-twitter]: https://twitter.com/phpc 21 | [php-programmers-gplus]: https://plus.google.com/u/0/communities/104245651975268426012 22 | [php-so]: http://stackoverflow.com/questions/tagged/php 23 | [php-calendar]: http://php.net/cal.php 24 | -------------------------------------------------------------------------------- /_posts/17-02-01-User-Groups.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: مجموعات مستخدمي PHP 3 | isChild: true 4 | anchor: user_groups 5 | --- 6 | 7 | ## مجموعات مستخدمي PHP {#user_groups_title} 8 | 9 | إذا كنت تعيش في مدينة كبيرة، هنالك العديد من مجموعات PHP حولك. يمكنك ببساطة إيجاد مجموعات محلية PUG في قائمة 10 | [usergroup-list at php.net][php-uglist] والتي بنيت على على [PHP.ug][php-ug]. مصدر بديل قد يكون [Meetup.com][meetup] 11 | أو قم بالبحث عن ```php user group near me``` باستخدام محرك البحث المفضل لديك، مثلا [Google][google]. إذا كنت تعيش في 12 | مدينة صغيرة قد لا يكون هنالك مجموعة محلية، فلم لا تقوم ببدء بواحدة! 13 | 14 | من الجدير بالذكر مجموعتين عالمية: [NomadPHP] و [PHPWomen]. [NomadPHP] تقوم بتوفير إجتماع مستخدمين أونلاين مرتين شهرياً 15 | يقوم بالتحدث فيها بضع مشاهير مجتمع PHP. 16 | [PHPWomen] هي مجموعة غير حصرية تستهدف النساء في عالم PHP. العضوية مفتوحة للجميع ولكل من يدعم المجتمع. وتوفر شبكة من الدعم 17 | والإرشاد والتعلم وبشكل عام يروجون لإنشاء بيئة "نسائية" إحترافية. 18 | 19 | [قراءة المزيد عن المجموعات في ويكي PHP][php-wiki] 20 | 21 | [google]: https://www.google.com/search?q=php+user+group+near+me 22 | [meetup]: http://www.meetup.com/find/ 23 | [php-ug]: http://php.ug/ 24 | [NomadPHP]: https://nomadphp.com/ 25 | [PHPWomen]: http://phpwomen.org/ 26 | [php-wiki]: https://wiki.php.net/usergroups 27 | [php-uglist]: http://php.net/ug.php 28 | -------------------------------------------------------------------------------- /_posts/17-03-01-Conferences.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: مؤتمرات PHP 3 | isChild: true 4 | anchor: conferences 5 | --- 6 | 7 | ## مؤتمرات PHP {#conferences_title} 8 | 9 | مجتمع PHP يقوم باستضافة مؤتمرات عالمية ومحلية في العديد من المدن حول العالم. عادة ما يتحدث فيها اعضاء مجتمع PHP المعروفين 10 | وهي فرصة ممتازة للتعلم مباشرة من قائدي المنشأة. 11 | 12 | [قم بإيجاد مؤتمر PHP][php-conf] 13 | 14 | 15 | [php-conf]: http://php.net/conferences/index.php 16 | -------------------------------------------------------------------------------- /_posts/17-04-01-Elephpants.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: فيلة PHP 3 | isChild: true 4 | anchor: elephpants 5 | --- 6 | 7 | ## فيلة PHP {#elephpants_title} 8 | 9 | [ElePHPant][elephpant] وهي جالبة الحظ لكل مشروع PHP مع الفيل في تصميمها. تم تصميمها في الأساس لمشروع PHP في عام 1998 من قبل [فاينسنت بونتير][vincent-pontier] وهو الأب لكل فيلة PHP حول العالم بعد عشر سنوات تم تجسيمها كدمية. الآن فيلة PHP موجودة في العديد من مؤتمرات PHP ويمتلكها العديد من مطوري PHP في أجهزتهم لمجرد المرح والإيحاء. 10 | 11 | [مقابلة مع فاينسنت بونتير][vincent-pontier-interview] 12 | 13 | 14 | [elephpant]: http://php.net/elephpant.php 15 | [vincent-pontier-interview]: http://7php.com/elephpant/ 16 | [vincent-pontier]: http://www.elroubio.net/ 17 | -------------------------------------------------------------------------------- /banners.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: بانرات ويب 4 | description: "قم بالنشر على الويب باستخدام صور _PHP: بالطريقة الصحيحة_! قم بإخبار المطورين الطامحين لإيجاد معلومات مفيدة." 5 | sitemap: true 6 | --- 7 | 8 | # بانرات ويب 9 | 10 | قم بالنشر على الويب باستخدام صور _PHP: بالطريقة الصحيحة_! قم بإخبار المطورين الطامحين لإيجاد معلومات مفيدة. 11 | 12 | ## ازرار 1 (120x90) 13 | 14 |

    PHP: The Right Way

    15 | 16 | {% highlight html %} 17 | 18 | PHP: The Right Way 19 | 20 | {% endhighlight %} 21 | 22 | ## ازرار 2 (120x60) 23 | 24 |

    PHP: The Right Way

    25 | 26 | {% highlight html %} 27 | 28 | PHP: The Right Way 29 | 30 | {% endhighlight %} 31 | 32 | ## متصدرة (728x90) 33 | 34 |

    PHP: The Right Way

    35 | 36 | {% highlight html %} 37 | 38 | PHP: The Right Way 39 | 40 | {% endhighlight %} 41 | 42 | ## مستطيل كبير (386x280) 43 | 44 |

    PHP: The Right Way

    45 | 46 | {% highlight html %} 47 | 48 | PHP: The Right Way 49 | 50 | {% endhighlight %} 51 | 52 | ## مستطيل متوسط (300x250) 53 | 54 |

    PHP: The Right Way

    55 | 56 | {% highlight html %} 57 | 58 | PHP: The Right Way 59 | 60 | {% endhighlight %} 61 | 62 | ## مستطيل (180x150) 63 | 64 |

    PHP: The Right Way

    65 | 66 | {% highlight html %} 67 | 68 | PHP: The Right Way 69 | 70 | {% endhighlight %} 71 | 72 | ## زر مربع (125x125) 73 | 74 |

    PHP: The Right Way

    75 | 76 | {% highlight html %} 77 | 78 | PHP: The Right Way 79 | 80 | {% endhighlight %} 81 | 82 | ## مستطيل طولي (240x400) 83 | 84 |

    PHP: The Right Way

    85 | 86 | {% highlight html %} 87 | 88 | PHP: The Right Way 89 | 90 | {% endhighlight %} 91 | -------------------------------------------------------------------------------- /images/banners/btn1-120x90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/banners/btn1-120x90.png -------------------------------------------------------------------------------- /images/banners/btn2-120x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/banners/btn2-120x60.png -------------------------------------------------------------------------------- /images/banners/leaderboard-728x90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/banners/leaderboard-728x90.png -------------------------------------------------------------------------------- /images/banners/lg-rect-386x280.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/banners/lg-rect-386x280.png -------------------------------------------------------------------------------- /images/banners/med-rect-300x250.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/banners/med-rect-300x250.png -------------------------------------------------------------------------------- /images/banners/rect-180x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/banners/rect-180x150.png -------------------------------------------------------------------------------- /images/banners/sq-btn-125x125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/banners/sq-btn-125x125.png -------------------------------------------------------------------------------- /images/banners/vert-rect-240x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/banners/vert-rect-240x400.png -------------------------------------------------------------------------------- /images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/favicon.png -------------------------------------------------------------------------------- /images/nmc-logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/nmc-logo.gif -------------------------------------------------------------------------------- /images/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/og-image.png -------------------------------------------------------------------------------- /images/og-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adaroobi/php-the-right-way/412527bac670957d209c44ec7f2b0390c51148c7/images/og-logo.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | description: "هو دليل سريع وسهل للطرق القياسية لبرمجة وتطوير PHP الأكثر شهرة، وروابط لدروس ودلائل موثوقة على شبكة الإنترنت وكل ما يعتبره المساهمون كمعايير قياسية حتى هذه اللحظة" 4 | sitemap: true 5 | --- 6 | 7 | {% capture welcome_content %}{% include welcome.md %}{% endcapture %} 8 |
    9 | {{ welcome_content|markdownify }} 10 |
    11 | 12 | {% capture backtotop %}[للأعلى](#top){:.top}{% endcapture %} 13 | {% for post in site.posts reversed %} 14 | {% if post.isChild != true and loop.first != true %}
    {{ backtotop|markdownify }}
    {% endif %} 15 |
    16 | {{ post.content }} 17 |
    18 | {% endfor %} 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "php-the-right-way", 3 | "version": "2.0.0", 4 | "devDependencies": { 5 | "grunt": "~0.4.5", 6 | "grunt-contrib-less": "~1.0.1", 7 | "grunt-contrib-watch": "~0.6.1", 8 | "grunt-postcss": "^0.6.0", 9 | "autoprefixer": "^6.0.3" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /pages/Functional-Programming.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: البرمجة الوظيفية في PHP 3 | layout: page 4 | sitemap: true 5 | --- 6 | 7 | # البرمجة الوظيفية في PHP 8 | 9 | 10 | تقوم PHP بدعم دوال عالية مما يعني ان الدوال التي يمكن اسناده الى متغير. كل من الدوال المعرفة من قبل المستخدم والدوال 11 | المدمة يمكن ان يتم مرجعيتها باستخدام دوال وندائها بشكل تلقائي. الدوال يمكن تمريرها كقيم الى دولا والدوال يمكن ان ترجع 12 | دوال (خاصية تسمى دوال ذات ترتيب أعلى). 13 | 14 | العودية وهي خاصية تتيح للدالة نداء نفسها ، وهي مدعومة من اللغة ولكن الكثير من كود PHP يقوم بالتركيز على التكرارات. 15 | 16 | الدوال المجهولة (بالدعم بالأطار المغلق) تم عرضها منذ PHP 5.3 (2009). 17 | 18 | في PHP 5.4 تم إدراج الإمكانية لإنساب وربط الأطر الى مدى العناصر وقد تم تطوير دعم الدوال القابلة للنداء حت تتمكن من استخدام 19 | بشكل معاكس مع الدوال المجهولة في أغلب الحالات. 20 | 21 | الإستخدام المشهور للدوال الأعلى ترتيب وهو تطبيقها في نموذج الإستراتيجي. الدالة المدمجة `array_filter()` تطلب كل من 22 | كمدخل مصفوفة بيانات ودالة (استراتيجية او دالة للنداء) تستخدم كدالة فلترة لكل عنصر على المصفوفة. 23 | 24 | {% highlight php %} 25 | $min 53 | * 54 | * Returns a single filter out of a family of "greater than n" filters 55 | */ 56 | function criteria_greater_than($min) 57 | { 58 | return function($item) use ($min) { 59 | return $item > $min; 60 | }; 61 | } 62 | 63 | $input = array(1, 2, 3, 4, 5, 6); 64 | 65 | // Use array_filter on a input with a selected filter function 66 | $output = array_filter($input, criteria_greater_than(3)); 67 | 68 | print_r($output); // items > 3 69 | {% endhighlight %} 70 | 71 | كل دالة ترشيح من هذه العائلة تقوم باستقبال عناصر أكبر من أقل قيمة. الفلتر الواحد يقوم بارجاع 72 | `criteria_greater_than` دالة لا اسمية `$min` قيمة مغلقة بالقيمة في المدى المعطى كقيمة عندما تم استدعاء 73 | `criteria_greater_than`. 74 | 75 | يتم استخدام الربط المسبق بصورة افتراضية تقوم بادراج `$min` المتغير في الدالة المنشئة. لإنشاء دوال لا اسمية بربط لاحق 76 | يجب استخدام المرجع عند الإدرج. تصور مكتبة ترشيح المدخلات او قوالب موجودن في دالة لا اسمية لقبض المتغيرات في مدى معين 77 | والوصل اليهم لاحقاً عن تنفيذ الدالة اللا اسمية. 78 | 79 | * [قراءة المزيد عن الدوال المجهولة][anonymous-functions] 80 | * [المزيد من التفاصيل عن الدوال اللا أسمية][closures-rfc] 81 | * [قراءة المزيد عن الاستدعاء الدايناميكي للدوال باستخدام `call_user_func_array()`][call-user-func-array] 82 | 83 | 84 | [anonymous-functions]: http://php.net/functions.anonymous 85 | [closures-rfc]: https://wiki.php.net/rfc/closures 86 | [call-user-func-array]: http://php.net/function.call-user-func-array 87 | -------------------------------------------------------------------------------- /pages/example.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Example Stand-Alone Page 4 | --- 5 | 6 | # Page Title 7 | 8 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod 9 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 10 | quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 11 | consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse 12 | cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 13 | proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 14 | 15 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod 16 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 17 | quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 18 | consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse 19 | cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 20 | proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 21 | 22 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod 23 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 24 | quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 25 | consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse 26 | cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 27 | proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 28 | -------------------------------------------------------------------------------- /scripts/fastclick.js: -------------------------------------------------------------------------------- 1 | /** Shrinkwrap URL: 2 | * /v2/bundles/js?modules=fastclick%401.0.6%2Co-autoinit%401.0.1&shrinkwrap= 3 | */ 4 | !function(t){function e(o){if(n[o])return n[o].exports;var i=n[o]={exports:{},id:o,loaded:!1};return t[o].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){"use strict";n(1),window.Origami={fastclick:n(2),"o-autoinit":n(4)}},function(t,e){t.exports={name:"__MAIN__",dependencies:{fastclick:"fastclick#*","o-autoinit":"o-autoinit#^1.0.0"}}},function(t,e,n){t.exports=n(3)},function(t,e){"use strict";var n=!1;!function(){function e(t,n){function o(t,e){return function(){return t.apply(e,arguments)}}var r;if(n=n||{},this.trackingClick=!1,this.trackingClickStart=0,this.targetElement=null,this.touchStartX=0,this.touchStartY=0,this.lastTouchIdentifier=0,this.touchBoundary=n.touchBoundary||10,this.layer=t,this.tapDelay=n.tapDelay||200,this.tapTimeout=n.tapTimeout||700,!e.notNeeded(t)){for(var a=["onMouse","onClick","onTouchStart","onTouchMove","onTouchEnd","onTouchCancel"],c=this,s=0,u=a.length;u>s;s++)c[a[s]]=o(c[a[s]],c);i&&(t.addEventListener("mouseover",this.onMouse,!0),t.addEventListener("mousedown",this.onMouse,!0),t.addEventListener("mouseup",this.onMouse,!0)),t.addEventListener("click",this.onClick,!0),t.addEventListener("touchstart",this.onTouchStart,!1),t.addEventListener("touchmove",this.onTouchMove,!1),t.addEventListener("touchend",this.onTouchEnd,!1),t.addEventListener("touchcancel",this.onTouchCancel,!1),Event.prototype.stopImmediatePropagation||(t.removeEventListener=function(e,n,o){var i=Node.prototype.removeEventListener;"click"===e?i.call(t,e,n.hijacked||n,o):i.call(t,e,n,o)},t.addEventListener=function(e,n,o){var i=Node.prototype.addEventListener;"click"===e?i.call(t,e,n.hijacked||(n.hijacked=function(t){t.propagationStopped||n(t)}),o):i.call(t,e,n,o)}),"function"==typeof t.onclick&&(r=t.onclick,t.addEventListener("click",function(t){r(t)},!1),t.onclick=null)}}var o=navigator.userAgent.indexOf("Windows Phone")>=0,i=navigator.userAgent.indexOf("Android")>0&&!o,r=/iP(ad|hone|od)/.test(navigator.userAgent)&&!o,a=r&&/OS 4_\d(_\d)?/.test(navigator.userAgent),c=r&&/OS [6-7]_\d/.test(navigator.userAgent),s=navigator.userAgent.indexOf("BB10")>0;e.prototype.needsClick=function(t){switch(t.nodeName.toLowerCase()){case"button":case"select":case"textarea":if(t.disabled)return!0;break;case"input":if(r&&"file"===t.type||t.disabled)return!0;break;case"label":case"iframe":case"video":return!0}return/\bneedsclick\b/.test(t.className)},e.prototype.needsFocus=function(t){switch(t.nodeName.toLowerCase()){case"textarea":return!0;case"select":return!i;case"input":switch(t.type){case"button":case"checkbox":case"file":case"image":case"radio":case"submit":return!1}return!t.disabled&&!t.readOnly;default:return/\bneedsfocus\b/.test(t.className)}},e.prototype.sendClick=function(t,e){var n,o;document.activeElement&&document.activeElement!==t&&document.activeElement.blur(),o=e.changedTouches[0],n=document.createEvent("MouseEvents"),n.initMouseEvent(this.determineEventType(t),!0,!0,window,1,o.screenX,o.screenY,o.clientX,o.clientY,!1,!1,!1,!1,0,null),n.forwardedTouchEvent=!0,t.dispatchEvent(n)},e.prototype.determineEventType=function(t){return i&&"select"===t.tagName.toLowerCase()?"mousedown":"click"},e.prototype.focus=function(t){var e;r&&t.setSelectionRange&&0!==t.type.indexOf("date")&&"time"!==t.type&&"month"!==t.type?(e=t.value.length,t.setSelectionRange(e,e)):t.focus()},e.prototype.updateScrollParent=function(t){var e,n;if(e=t.fastClickScrollParent,!e||!e.contains(t)){n=t;do{if(n.scrollHeight>n.offsetHeight){e=n,t.fastClickScrollParent=n;break}n=n.parentElement}while(n)}e&&(e.fastClickLastScrollTop=e.scrollTop)},e.prototype.getTargetElementFromEventTarget=function(t){return t.nodeType===Node.TEXT_NODE?t.parentNode:t},e.prototype.onTouchStart=function(t){var e,n,o;if(t.targetTouches.length>1)return!0;if(e=this.getTargetElementFromEventTarget(t.target),n=t.targetTouches[0],r){if(o=window.getSelection(),o.rangeCount&&!o.isCollapsed)return!0;if(!a){if(n.identifier&&n.identifier===this.lastTouchIdentifier)return t.preventDefault(),!1;this.lastTouchIdentifier=n.identifier,this.updateScrollParent(e)}}return this.trackingClick=!0,this.trackingClickStart=t.timeStamp,this.targetElement=e,this.touchStartX=n.pageX,this.touchStartY=n.pageY,t.timeStamp-this.lastClickTimen||Math.abs(e.pageY-this.touchStartY)>n?!0:!1},e.prototype.onTouchMove=function(t){return this.trackingClick?((this.targetElement!==this.getTargetElementFromEventTarget(t.target)||this.touchHasMoved(t))&&(this.trackingClick=!1,this.targetElement=null),!0):!0},e.prototype.findControl=function(t){return void 0!==t.control?t.control:t.htmlFor?document.getElementById(t.htmlFor):t.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea")},e.prototype.onTouchEnd=function(t){var e,n,o,s,u,l=this.targetElement;if(!this.trackingClick)return!0;if(t.timeStamp-this.lastClickTimethis.tapTimeout)return!0;if(this.cancelNextClick=!1,this.lastClickTime=t.timeStamp,n=this.trackingClickStart,this.trackingClick=!1,this.trackingClickStart=0,c&&(u=t.changedTouches[0],l=document.elementFromPoint(u.pageX-window.pageXOffset,u.pageY-window.pageYOffset)||l,l.fastClickScrollParent=this.targetElement.fastClickScrollParent),o=l.tagName.toLowerCase(),"label"===o){if(e=this.findControl(l)){if(this.focus(l),i)return!1;l=e}}else if(this.needsFocus(l))return t.timeStamp-n>100||r&&window.top!==window&&"input"===o?(this.targetElement=null,!1):(this.focus(l),this.sendClick(l,t),r&&"select"===o||(this.targetElement=null,t.preventDefault()),!1);return r&&!a&&(s=l.fastClickScrollParent,s&&s.fastClickLastScrollTop!==s.scrollTop)?!0:(this.needsClick(l)||(t.preventDefault(),this.sendClick(l,t)),!1)},e.prototype.onTouchCancel=function(){this.trackingClick=!1,this.targetElement=null},e.prototype.onMouse=function(t){return this.targetElement?t.forwardedTouchEvent?!0:t.cancelable&&(!this.needsClick(this.targetElement)||this.cancelNextClick)?(t.stopImmediatePropagation?t.stopImmediatePropagation():t.propagationStopped=!0,t.stopPropagation(),t.preventDefault(),!1):!0:!0},e.prototype.onClick=function(t){var e;return this.trackingClick?(this.targetElement=null,this.trackingClick=!1,!0):"submit"===t.target.type&&0===t.detail?!0:(e=this.onMouse(t),e||(this.targetElement=null),e)},e.prototype.destroy=function(){var t=this.layer;i&&(t.removeEventListener("mouseover",this.onMouse,!0),t.removeEventListener("mousedown",this.onMouse,!0),t.removeEventListener("mouseup",this.onMouse,!0)),t.removeEventListener("click",this.onClick,!0),t.removeEventListener("touchstart",this.onTouchStart,!1),t.removeEventListener("touchmove",this.onTouchMove,!1),t.removeEventListener("touchend",this.onTouchEnd,!1),t.removeEventListener("touchcancel",this.onTouchCancel,!1)},e.notNeeded=function(t){var e,n,o,r;if("undefined"==typeof window.ontouchstart)return!0;if(n=+(/Chrome\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]){if(!i)return!0;if(e=document.querySelector("meta[name=viewport]")){if(-1!==e.content.indexOf("user-scalable=no"))return!0;if(n>31&&document.documentElement.scrollWidth<=window.outerWidth)return!0}}if(s&&(o=navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/),o[1]>=10&&o[2]>=3&&(e=document.querySelector("meta[name=viewport]")))){if(-1!==e.content.indexOf("user-scalable=no"))return!0;if(document.documentElement.scrollWidth<=window.outerWidth)return!0}return"none"===t.style.msTouchAction||"manipulation"===t.style.touchAction?!0:(r=+(/Firefox\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1],r>=27&&(e=document.querySelector("meta[name=viewport]"),e&&(-1!==e.content.indexOf("user-scalable=no")||document.documentElement.scrollWidth<=window.outerWidth))?!0:"none"===t.style.touchAction||"manipulation"===t.style.touchAction?!0:!1)},e.attach=function(t,n){return new e(t,n)},"function"==typeof n&&"object"==typeof n.amd&&n.amd?n(function(){return e}):"undefined"!=typeof t&&t.exports?(t.exports=e.attach,t.exports.FastClick=e):window.FastClick=e}()},function(t,e,n){t.exports=n(5)},function(t,e){"use strict";function n(t){t in o||(o[t]=!0,document.dispatchEvent(new CustomEvent("o."+t)))}var o={};window.addEventListener("load",n.bind(null,"load")),window.addEventListener("load",n.bind(null,"DOMContentLoaded")),document.addEventListener("DOMContentLoaded",n.bind(null,"DOMContentLoaded")),"complete"===document.readyState?(n("load"),n("DOMContentLoaded")):"interactive"===document.readyState&&n("DOMContentLoaded")}]); 5 | -------------------------------------------------------------------------------- /scripts/setup.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | // Attach FastClick 3 | var attachFastClick = Origami.fastclick; 4 | attachFastClick(document.body); 5 | 6 | // Mobile TOC menu 7 | var $window = $(window), 8 | $nav = $('.site-navigation'); 9 | $nav.click(function (e) { 10 | var $target = $(e.target); 11 | if ($target.is($nav) && $window.width() <= 375) { 12 | $nav.toggleClass('open'); 13 | } 14 | if ($target.is('a')) { 15 | $nav.removeClass('open'); 16 | } 17 | }); 18 | })(jQuery); 19 | -------------------------------------------------------------------------------- /styles/all.less: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | NMC Bootstrap 3 | 4 | This LESS file imports all other LESS files. You should compile 5 | and minify this file before site launch. 6 | ========================================================================== */ 7 | 8 | /* Import NMC bootstrap */ 9 | 10 | @import "base/all"; 11 | 12 | /* Import site-specific styles */ 13 | 14 | @import "site/site-header.less"; 15 | @import "site/site-navigation.less"; 16 | @import "site/site-content.less"; 17 | @import "site/site-footer.less"; 18 | 19 | /* Tablets and Smartphones */ 20 | 21 | @media only screen and (max-width : 1024px) { 22 | .build-date{ 23 | text-align: center; 24 | } 25 | .site-header{ 26 | height: 220px; 27 | position: absolute; 28 | top: 20px; 29 | left: 0; 30 | width: 100%; 31 | } 32 | .fork-me img{ 33 | height: 110px; 34 | width: 110px; 35 | } 36 | .site-navigation{ 37 | margin-top: 240px; 38 | padding: 20px; 39 | position: relative; 40 | width: auto; 41 | 42 | ul{ 43 | border: 1px solid #999; 44 | border-bottom: none; 45 | } 46 | li{ 47 | .man; 48 | .pan; 49 | } 50 | a{ 51 | background: #CCC; 52 | display: block; 53 | border-bottom: 1px solid #999; 54 | padding: 10px; 55 | text-decoration: none; 56 | } 57 | ul ul{ 58 | border: none; 59 | .man; 60 | .pan; 61 | } 62 | ul ul a{ 63 | background: transparent; 64 | } 65 | } 66 | .site-content{ 67 | padding: 20px; 68 | } 69 | .top{ 70 | display: inline-block; 71 | float: none; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /styles/base/all.less: -------------------------------------------------------------------------------- 1 | @import "reset"; 2 | @import "prefixer"; 3 | @import "spacing"; 4 | @import "typography"; 5 | @import "idioms"; 6 | @import "grid"; 7 | @import "bars-buttons"; 8 | @import "buttons"; -------------------------------------------------------------------------------- /styles/base/bars-buttons.less: -------------------------------------------------------------------------------- 1 | .button() { 2 | .border-box; 3 | cursor: pointer; 4 | display: inline-block; 5 | .phh; 6 | text-align: center; 7 | font-weight: bold; 8 | } 9 | .button-hover(){ 10 | text-decoration: none; 11 | } 12 | .bar() { 13 | display: block; 14 | .pah; 15 | text-align: center; 16 | font-weight: bold; 17 | } 18 | 19 | /* Sizes */ 20 | 21 | .btn-size(@scale){ 22 | height: @baseline * @scale !important; 23 | padding-bottom: 0 !important; 24 | padding-top: 0 !important; 25 | line-height: @baseline * (@scale * 0.9); 26 | } 27 | .btn-half{ 28 | .btn-size(1); 29 | font-size: 0.8em; 30 | } 31 | .btn-single{ 32 | .btn-size(1.5); 33 | font-size: 1em; 34 | } 35 | .btn-double{ 36 | .btn-size(2); 37 | font-size: 1.1em; 38 | } 39 | 40 | /* Shapes */ 41 | 42 | .bb-shape-square() { 43 | .border-radius(0); 44 | } 45 | .bb-shape-rounded(@rad:3px) { 46 | .border-radius(@rad); 47 | } 48 | .bb-shape-round() { 49 | .border-radius(@baseline); 50 | } 51 | 52 | /* Text */ 53 | 54 | .bb-text-dark(){ 55 | color: #333; 56 | text-shadow: 0 1px 0 #fff; 57 | } 58 | .bb-text-light(){ 59 | color: #fff; 60 | text-shadow: 0 -1px 0 rgba(0,0,0,.3); 61 | } 62 | .bb-text-color(@color){ 63 | 64 | } 65 | 66 | /* Color */ 67 | 68 | .bb-color-plain(@color){ 69 | background: @color; 70 | } 71 | .bb-color-gradient(@color){ 72 | .gradient(@color,lighten(@color,10%),darken(@color,10%)); 73 | } 74 | .bb-color-soft(@color){ 75 | .gradient(@color,lighten(@color,5%),darken(@color,5%)); 76 | } 77 | .bb-color-gloss(@color){ 78 | @topStart: desaturate(lighten(@color,40%),20%); 79 | @topStop: desaturate(lighten(@color,20%),40%); 80 | @bottomStart: desaturate(lighten(@color,10%),30%); 81 | @bottomStop: desaturate(lighten(@color,15%),30%); 82 | .linear-gradient-top(@color,@topStart,0%,@topStop,50%,@bottomStart,50%,@bottomStop,100%); 83 | } 84 | 85 | /* Border */ 86 | 87 | .bb-border-noborder(){ 88 | border: none; 89 | } 90 | .bb-border-plain(@color){ 91 | border: 1px solid darken(@color,10%); 92 | } 93 | .bb-border-contrast(@color){ 94 | border: 1px solid darken(@color,15%); 95 | .box-shadow(inset 0 0 1px 1px lighten(@color,15%)); 96 | } 97 | .bb-border-meta(@color){ 98 | border: 1px solid darken(@color,15%); 99 | .box-shadow(inset 0 2px 1px -1px lighten(@color,20%)); 100 | } 101 | 102 | /* Minimal */ 103 | 104 | .button-minimal(@color) { 105 | .button(); 106 | .bb-shape-rounded(); 107 | .bb-color-plain(@color); 108 | .bb-border-contrast(@color); 109 | .bb-text-dark(); 110 | } 111 | .button-minimal-hover(@color){ 112 | .button-minimal(darken(@color,5%)); 113 | .button-hover(); 114 | } 115 | .button-minimal-active(@color){ 116 | .button-minimal-hover(darken(@color,5%)); 117 | } 118 | .bar-minimal(@color) { 119 | .button-minimal(@color); 120 | .bar(); 121 | } 122 | 123 | /* Clean */ 124 | 125 | .button-clean(@color) { 126 | .button(); 127 | .bb-shape-rounded(); 128 | .bb-color-gradient(@color); 129 | .bb-border-plain(darken(@color,5%)); 130 | .bb-text-dark(); 131 | } 132 | .button-clean-hover(@color){ 133 | .button-clean(darken(@color,5%)); 134 | .button-hover(); 135 | } 136 | .button-clean-active(@color){ 137 | .button-clean-hover(darken(@color,5%)); 138 | } 139 | .bar-clean(@color){ 140 | .button-clean(@color); 141 | .bar(); 142 | } 143 | 144 | /* Soft */ 145 | 146 | .button-soft(@color) { 147 | .button(); 148 | .bb-shape-rounded(); 149 | .bb-color-soft(@color); 150 | .bb-border-meta(darken(@color,5%)); 151 | .bb-text-light(); 152 | } 153 | .button-soft-hover(@color){ 154 | .button-soft(darken(@color,5%)); 155 | .button-hover(); 156 | } 157 | .button-soft-active(@color){ 158 | .button-soft-hover(darken(@color,5%)); 159 | } 160 | .bar-soft(@color){ 161 | .button-soft(@color); 162 | .bar(); 163 | } 164 | 165 | /* Pill */ 166 | 167 | .button-pill(@color) { 168 | .button(); 169 | .bb-shape-round(); 170 | .bb-color-soft(@color); 171 | .bb-border-meta(darken(@color,5%)); 172 | .bb-text-light(); 173 | } 174 | .button-pill-hover(@color){ 175 | .button-pill(darken(@color,5%)); 176 | .button-hover(); 177 | } 178 | .button-pill-active(@color){ 179 | .button-pill-hover(darken(@color,5%)); 180 | } 181 | .bar-pill(@color){ 182 | .button-pill(@color); 183 | .bar(); 184 | } 185 | 186 | /* Gloss */ 187 | 188 | .button-gloss(@color) { 189 | .button(); 190 | .bb-shape-rounded(5px); 191 | .bb-color-gloss(@color); 192 | .bb-border-plain(darken(@color,5%)); 193 | .box-shadow(inset 0 1px 0 0 rgba(255,255,255,.5)); 194 | .bb-text-light(); 195 | } 196 | .button-gloss-hover(@color){ 197 | .button-gloss(darken(@color,5%)); 198 | .box-shadow(inset 0 1px 0 0 rgba(255,255,255,.3)); 199 | .button-hover(); 200 | } 201 | .button-gloss-active(@color){ 202 | .button-gloss-hover(darken(@color,5%)); 203 | .box-shadow(inset 0 0 5px 0 rgba(0,0,0,.3)); 204 | } 205 | .bar-gloss(@color){ 206 | .button-gloss(@color); 207 | .bar(); 208 | } 209 | 210 | @btn-minimal-color: #eee; 211 | .btn-minimal { .button-minimal(@btn-minimal-color); } 212 | .btn-minimal:hover { .button-minimal-hover(@btn-minimal-color); } 213 | .btn-minimal:active { .button-minimal-active(@btn-minimal-color); } 214 | 215 | @btn-clean-color: #eee; 216 | .btn-clean { .button-clean(@btn-clean-color); } 217 | .btn-clean:hover { .button-clean-hover(@btn-clean-color); } 218 | .btn-clean:active { .button-clean-active(@btn-clean-color); } 219 | 220 | @btn-soft-color: #6C84AB; 221 | .btn-soft { .button-soft(@btn-soft-color); } 222 | .btn-soft:hover { .button-soft-hover(@btn-soft-color); } 223 | .btn-soft:active { .button-soft-active(@btn-soft-color); } 224 | 225 | @btn-pill-color: #6C84AB; 226 | .btn-pill { .button-pill(@btn-pill-color); } 227 | .btn-pill:hover { .button-pill-hover(@btn-pill-color); } 228 | .btn-pill:active { .button-pill-active(@btn-pill-color); } 229 | 230 | @btn-gloss-color: #172D6E; 231 | .btn-gloss { .button-gloss(@btn-gloss-color); } 232 | .btn-gloss:hover { .button-gloss-hover(@btn-gloss-color); } 233 | .btn-gloss:active { .button-gloss-active(@btn-gloss-color); } 234 | 235 | 236 | .bar-minimal { .bar-minimal(@btn-minimal-color); } 237 | .bar-clean { .bar-clean(@btn-clean-color); } 238 | .bar-soft { .bar-soft(@btn-soft-color); } 239 | .bar-pill { .bar-pill(@btn-pill-color); } 240 | .bar-gloss { .bar-gloss(@btn-gloss-color); } -------------------------------------------------------------------------------- /styles/base/buttons.less: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | Settings 3 | ========================================================================== */ 4 | 5 | @import 'variables.less'; 6 | 7 | /* 8 | @baseline: @baseline; 9 | @button-color: @button-color; 10 | @button-primary-color: @button-primary-color; 11 | @button-info-color: @button-info-color; 12 | @button-success-color: @button-success-color; 13 | @button-warning-color: @button-warning-color; 14 | @button-danger-color: @button-danger-color; 15 | */ 16 | 17 | /* ========================================================================== 18 | Default 19 | ========================================================================== */ 20 | 21 | .btn{ 22 | .btn-s; 23 | background-clip: border-box !important; 24 | background-repeat: repeat-x; 25 | border: 1px solid rgba(0, 0, 0, 0.25); 26 | .border-box; 27 | .border-radius(4px); 28 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 29 | cursor: pointer; 30 | display: inline-block; 31 | .gradient(@button-color, lighten(@button-color, 10%), @button-color); 32 | .phh; 33 | .pvn; 34 | .transition(background-position linear 0.1s); 35 | vertical-align: middle; 36 | color: #333; 37 | font-family: @body-font-family; 38 | text-decoration: none !important; 39 | text-shadow: rgba(255,255,255,0.75) 0 1px 0; 40 | 41 | &:hover{ 42 | background-position: 0 -15px; 43 | } 44 | } 45 | 46 | /* ========================================================================== 47 | Styles 48 | ========================================================================== */ 49 | 50 | .btn-primary, 51 | .btn-info, 52 | .btn-success, 53 | .btn-warning, 54 | .btn-danger{ 55 | color: #FFF !important; 56 | text-shadow: rgba(0,0,0,0.25) 0 -1px 0 !important; 57 | } 58 | .btn-primary{ 59 | .btn; 60 | .gradient(@button-primary-color, lighten(@button-primary-color, 10%), @button-primary-color); 61 | } 62 | .btn-info{ 63 | .btn; 64 | .gradient(@button-info-color, lighten(@button-info-color, 10%), @button-info-color); 65 | } 66 | .btn-success{ 67 | .btn; 68 | .gradient(@button-success-color, lighten(@button-success-color, 10%), @button-success-color); 69 | } 70 | .btn-warning{ 71 | .btn; 72 | .gradient(@button-warning-color, lighten(@button-warning-color, 10%), @button-warning-color); 73 | } 74 | .btn-danger{ 75 | .btn; 76 | .gradient(@button-danger-color, lighten(@button-danger-color, 10%), @button-danger-color); 77 | } 78 | 79 | /* ========================================================================== 80 | Sizes (Half = h, Single = s, Double = d) 81 | ========================================================================== */ 82 | 83 | .btn-h, .btn-half{ 84 | height: @baseline; 85 | font-size: @baseline * 0.6; 86 | line-height: @baseline; 87 | } 88 | .btn-s, .btn-single{ 89 | height: @baseline * 1.5; 90 | font-size: @baseline * 0.75; 91 | line-height: @baseline * 1.5; 92 | } 93 | .btn-d, .btn-double{ 94 | height: @baseline * 2; 95 | font-size: @baseline; 96 | line-height: @baseline * 2; 97 | } -------------------------------------------------------------------------------- /styles/base/grid.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Hybrid Grid Sytem 3 | * 4 | * Blend of the Semantic Grid System and Zurb Foundation with a little Twitter Bootstrap 5 | */ 6 | 7 | /* Settings */ 8 | 9 | @import 'variables.less'; 10 | 11 | /* 12 | @fixed-column-width: 40px; 13 | @fixed-gutter-width: 20px; 14 | @fixed-columns: 12; 15 | 16 | @fluid-column-width: 4.3%; 17 | @fluid-gutter-width: 4.4%; 18 | @fluid-columns: 12; 19 | 20 | @mobile-break-width: 480px; 21 | @mobile-column-width: 8.6%; 22 | @mobile-gutter-width: 8.8%; 23 | @mobile-columns: 6; 24 | */ 25 | 26 | /* Grid */ 27 | 28 | #grid { 29 | 30 | .cols(@cols,@width,@gutter){ 31 | .border-box(); 32 | width: ((@cols * @width) + ((@cols - 1) * @gutter)); 33 | margin-left: @gutter; 34 | position: relative; 35 | display: inline; 36 | float: left; 37 | min-height: 1px; 38 | &:first-child { 39 | margin-left: 0; 40 | } 41 | &:last-child { 42 | float: right; 43 | } 44 | } 45 | 46 | } 47 | 48 | .grid-fixed,.grid-fluid { 49 | .clearfix; 50 | .row { 51 | .border-box(); 52 | display: block; 53 | width: 100%; 54 | margin: 0 auto; 55 | .clearfix; 56 | 57 | .center,.center:last-child { 58 | float: none; 59 | display: block; 60 | margin: 0 auto; 61 | } 62 | } 63 | } 64 | 65 | .grid-fixed { 66 | @total-width: (@fixed-column-width*@fixed-columns) + (@fixed-gutter-width*(@fixed-columns - 1)); 67 | @column-width: @fixed-column-width; 68 | @gutter-width: @fixed-gutter-width; 69 | @columns: @fixed-columns; 70 | width: @total-width; 71 | 72 | /* This is duplicated in both classes. Unavoidable. */ 73 | .colX (@index) when (@index > 0) { 74 | (~".col@{index}") { 75 | #grid > .cols(@index,@column-width,@gutter-width); 76 | } 77 | .colX(@index - 1); 78 | } 79 | .colX (0) {} 80 | .colX(@columns); 81 | 82 | .offsetX (@index) when (@index > 0) { 83 | (~".offset@{index}") { 84 | margin-left: (@index * @column-width) + ((@index + 1) * @gutter-width); 85 | } 86 | .offsetX(@index - 1); 87 | } 88 | .offsetX (0) {} 89 | .offsetX(@columns - 1); 90 | 91 | .pushX (@index) when (@index > 0) { 92 | (~".push@{index}") { 93 | left: @index * (@column-width + @gutter-width); 94 | } 95 | .pushX(@index - 1); 96 | } 97 | .pushX (0) {} 98 | .pushX(@columns - 1); 99 | 100 | .pullX (@index) when (@index > 0) { 101 | (~".pull@{index}") { 102 | right: @index * (@column-width + @gutter-width); 103 | } 104 | .pullX(@index - 1); 105 | } 106 | .pullX (0) {} 107 | .pullX(@columns - 1); 108 | } 109 | 110 | 111 | .grid-fluid { 112 | @total-width: 100%; 113 | @column-width: @fluid-column-width; 114 | @gutter-width: @fluid-gutter-width; 115 | @columns: @fluid-columns; 116 | width: @total-width; 117 | 118 | /* This is duplicated in both classes. Unavoidable. */ 119 | .colX (@index) when (@index > 0) { 120 | (~".col@{index}") { 121 | #grid > .cols(@index,@column-width,@gutter-width); 122 | } 123 | .colX(@index - 1); 124 | } 125 | .colX (0) {} 126 | .colX(@columns); 127 | 128 | .offsetX (@index) when (@index > 0) { 129 | (~".offset@{index}") { 130 | margin-left: (@index * @column-width) + ((@index + 1) * @gutter-width); 131 | } 132 | .offsetX(@index - 1); 133 | } 134 | .offsetX (0) {} 135 | .offsetX(@columns - 1); 136 | 137 | .pushX (@index) when (@index > 0) { 138 | (~".push@{index}") { 139 | left: @index * (@column-width + @gutter-width); 140 | } 141 | .pushX(@index - 1); 142 | } 143 | .pushX (0) {} 144 | .pushX(@columns - 1); 145 | 146 | .pullX (@index) when (@index > 0) { 147 | (~".pull@{index}") { 148 | right: @index * (@column-width + @gutter-width); 149 | } 150 | .pullX(@index - 1); 151 | } 152 | .pullX (0) {} 153 | .pullX(@columns - 1); 154 | } 155 | 156 | 157 | @media all and (max-width: @mobile-break-width) { 158 | 159 | // Reset all columns to full width 160 | .grid-fixed { 161 | .colX (@index) when (@index > 0) { 162 | (~".col@{index}") { 163 | width: 100%; 164 | margin: 0; 165 | left: 0; 166 | right: 0; 167 | } 168 | .colX(@index - 1); 169 | } 170 | .colX (0) {} 171 | .colX(@fixed-columns); 172 | } 173 | .grid-fluid { 174 | .colX (@index) when (@index > 0) { 175 | (~".col@{index}") { 176 | width: 100%; 177 | margin: 0; 178 | left: 0; 179 | right: 0; 180 | } 181 | .colX(@index - 1); 182 | } 183 | .colX (0) {} 184 | .colX(@fluid-columns); 185 | } 186 | 187 | .grid-fixed, .grid-fluid { 188 | @total-width: 100%; 189 | @column-width: @mobile-column-width; 190 | @gutter-width: @mobile-gutter-width; 191 | @columns: @mobile-columns; 192 | width: @total-width; 193 | 194 | .m-colX (@index) when (@index > 0) { 195 | (~".m-col@{index}") { 196 | #grid > .cols(@index,@column-width,@gutter-width); 197 | } 198 | .m-colX(@index - 1); 199 | } 200 | .m-colX (0) {} 201 | .m-colX(@mobile-columns); 202 | 203 | .m-offsetX (@index) when (@index > 0) { 204 | (~".m-offset@{index}") { 205 | margin-left: (@index * @column-width) + ((@index + 1) * @gutter-width); 206 | } 207 | .m-offsetX(@index - 1); 208 | } 209 | .m-offsetX (0) {} 210 | .m-offsetX(@columns - 1); 211 | 212 | .m-pushX (@index) when (@index > 0) { 213 | (~".m-push@{index}") { 214 | left: @index * (@column-width + @gutter-width); 215 | } 216 | .m-pushX(@index - 1); 217 | } 218 | .m-pushX (0) {} 219 | .m-pushX(@columns - 1); 220 | 221 | .m-pullX (@index) when (@index > 0) { 222 | (~".m-pull@{index}") { 223 | right: @index * (@column-width + @gutter-width); 224 | } 225 | .m-pullX(@index - 1); 226 | } 227 | .m-pullX (0) {} 228 | .m-pullX(@columns - 1); 229 | } 230 | 231 | } 232 | -------------------------------------------------------------------------------- /styles/base/idioms.less: -------------------------------------------------------------------------------- 1 | /** 2 | * New Media Campaigns Idioms 3 | * 4 | * These are common patterns we use in all of our 5 | * projects. They are consolidated here to keep code DRY. 6 | * 7 | * Listing 8 | * * .no-text, .text-replace 9 | * * .no-list 10 | * * .no-form 11 | * * .fixed-width(@width) 12 | * * .column-width(@width) 13 | * * .column-left(@width) 14 | * * .column-right(@width) 15 | * * .full-size 16 | * * .absolute-default 17 | * * .absolute-fullsize 18 | * * .clearfix 19 | */ 20 | 21 | /* Hides text when using image replacement */ 22 | .no-text, .text-replace{ 23 | overflow: hidden; 24 | text-indent: 100%; 25 | white-space: nowrap; 26 | } 27 | 28 | /* Removes bullets, margin, and padding from list */ 29 | .no-list{ 30 | list-style: none; 31 | margin: 0; 32 | padding: 0; 33 | } 34 | 35 | /* Removes webkit styling from form element */ 36 | .no-form{ 37 | border: none; 38 | margin: 0; 39 | padding: 0; 40 | -webkit-appearance: none; 41 | } 42 | 43 | /* Center a fixed width container */ 44 | .fixed-width(@width) { 45 | margin: 0 auto; 46 | width: @width; 47 | } 48 | 49 | /* Adds left or right columns (e.g. content and sidebar) */ 50 | .column-width(@width){ 51 | display: inline; 52 | width: @width; 53 | } 54 | .column-left(@width){ 55 | .column-width(@width); 56 | float: left; 57 | } 58 | .column-right(@width){ 59 | .column-width(@width); 60 | float: right; 61 | } 62 | 63 | /* Set width and height of element to that of its parent */ 64 | .full-size{ 65 | height: 100%; 66 | width: 100%; 67 | } 68 | 69 | /* Position element absolutely to 0,0 */ 70 | .absolute-default{ 71 | position: absolute; 72 | left: 0; 73 | top: 0; 74 | } 75 | 76 | /* Position element absolutely and set its width and height to that of its parent (useful for slideshows) */ 77 | .absolute-fullsize{ 78 | .absolute-default; 79 | .full-size; 80 | } 81 | 82 | /* The micro clearfix http://nicolasgallagher.com/micro-clearfix-hack/ */ 83 | .clearfix { 84 | *zoom:1; 85 | 86 | &:before, 87 | &:after { 88 | content:""; 89 | display:table; 90 | } 91 | &:after { 92 | clear:both; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /styles/base/reset.less: -------------------------------------------------------------------------------- 1 | /** 2 | * html5doctor.com Reset Stylesheet 3 | * v1.6.1 4 | * Last Updated: 2010-09-17 5 | * Author: Richard Clark - http://richclarkdesign.com 6 | * Twitter: @rich_clark 7 | */ 8 | 9 | html, body, div, span, object, iframe, 10 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 11 | abbr, address, cite, code, 12 | del, dfn, em, img, ins, kbd, q, samp, 13 | small, strong, sub, sup, var, 14 | b, i, 15 | dl, dt, dd, ol, ul, li, 16 | fieldset, form, label, legend, 17 | table, caption, tbody, tfoot, thead, tr, th, td, 18 | article, aside, canvas, details, figcaption, figure, 19 | footer, header, hgroup, menu, nav, section, summary, 20 | time, mark, audio, video { 21 | margin:0; 22 | padding:0; 23 | border:0; 24 | outline:0; 25 | font-size:100%; 26 | vertical-align:baseline; 27 | background:transparent; 28 | } 29 | 30 | body { 31 | line-height:1; 32 | } 33 | 34 | article,aside,details,figcaption,figure, 35 | footer,header,hgroup,menu,nav,section { 36 | display:block; 37 | } 38 | 39 | nav ul { 40 | list-style:none; 41 | } 42 | 43 | blockquote, q { 44 | quotes:none; 45 | } 46 | 47 | blockquote:before, blockquote:after, 48 | q:before, q:after { 49 | content:''; 50 | content:none; 51 | } 52 | 53 | a { 54 | margin:0; 55 | padding:0; 56 | font-size:100%; 57 | vertical-align:baseline; 58 | background:transparent; 59 | } 60 | 61 | /* change colours to suit your needs */ 62 | ins { 63 | background-color:#ff9; 64 | color:#000; 65 | text-decoration:none; 66 | } 67 | 68 | /* change colours to suit your needs */ 69 | mark { 70 | background-color:#ff9; 71 | color:#000; 72 | font-style:italic; 73 | font-weight:bold; 74 | } 75 | 76 | del { 77 | text-decoration: line-through; 78 | } 79 | 80 | abbr[title], dfn[title] { 81 | border-bottom:1px dotted; 82 | cursor:help; 83 | } 84 | 85 | table { 86 | border-collapse:collapse; 87 | border-spacing:0; 88 | } 89 | 90 | /* change border colour to suit your needs */ 91 | hr { 92 | display:block; 93 | height:1px; 94 | border:0; 95 | border-top:1px solid #cccccc; 96 | margin:1em 0; 97 | padding:0; 98 | } 99 | 100 | input, select { 101 | vertical-align:middle; 102 | } -------------------------------------------------------------------------------- /styles/base/spacing.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Spacing 3 | * 4 | * This LESS file defines margins and paddings for block-level 5 | * elements. Helper classes are included for use elsewhere 6 | * in site styles. 7 | */ 8 | 9 | /* Settings */ 10 | 11 | @import 'variables.less'; 12 | 13 | /* 14 | @baseline: @baseline; 15 | */ 16 | 17 | /** 18 | * Spacing 19 | * p, m, lh = padding, margin, line-height 20 | * a, t, r, b, l, h, v = all, top, right, bottom, left, horizontal, vertical 21 | * n, h, s, d = none(0px), half(@baseline / 2), single(@baseline), double(@baseline * 2), none(0px) 22 | */ 23 | 24 | .ptn, .pvn, .pan{ 25 | padding-top: 0 !important 26 | } 27 | .pth, .pvh, .pah{ 28 | padding-top: @baseline / 2 !important 29 | } 30 | .pts, .pvs, .pas{ 31 | padding-top: @baseline !important 32 | } 33 | .ptd, .pvd, .pad{ 34 | padding-top: @baseline * 2 !important 35 | } 36 | .prn, .phn, .pan{ 37 | padding-right: 0 !important 38 | } 39 | .prh, .phh, .pah{ 40 | padding-right: @baseline / 2 !important 41 | } 42 | .prs, .phs, .pas{ 43 | padding-right: @baseline !important 44 | } 45 | .prd, .phd, .pad{ 46 | padding-right: @baseline * 2 !important 47 | } 48 | .pbn, .pvn, .pan{ 49 | padding-bottom: 0 !important 50 | } 51 | .pbh, .pvh, .pah{ 52 | padding-bottom: @baseline / 2 !important 53 | } 54 | .pbs, .pvs, .pas{ 55 | padding-bottom: @baseline !important 56 | } 57 | .pbd, .pvd, .pad{ 58 | padding-bottom: @baseline * 2 !important 59 | } 60 | .pln, .phn, .pan{ 61 | padding-left: 0 !important 62 | } 63 | .plh, .phh, .pah{ 64 | padding-left: @baseline / 2 !important 65 | } 66 | .pls, .phs, .pas{ 67 | padding-left: @baseline !important 68 | } 69 | .pld, .phd, .pad{ 70 | padding-left: @baseline * 2 !important 71 | } 72 | .mtn, .mvn, .man{ 73 | margin-top: 0 !important 74 | } 75 | .mth, .mvh, .mah{ 76 | margin-top: @baseline / 2 !important 77 | } 78 | .mts, .mvs, .mas{ 79 | margin-top: @baseline !important 80 | } 81 | .mtd, .mvd, .mad{ 82 | margin-top: @baseline * 2 !important 83 | } 84 | .mrn, .mhn, .man{ 85 | margin-right: 0 !important 86 | } 87 | .mrh, .mhh, .mah{ 88 | margin-right: @baseline / 2 !important 89 | } 90 | .mrs, .mhs, .mas{ 91 | margin-right: @baseline !important 92 | } 93 | .mrd, .mhd, .mad{ 94 | margin-right: @baseline * 2 !important 95 | } 96 | .mbn, .mvn, .man{ 97 | margin-bottom: 0 !important 98 | } 99 | .mbh, .mvh, .mah{ 100 | margin-bottom: @baseline / 2 !important 101 | } 102 | .mbs, .mvs, .mas{ 103 | margin-bottom: @baseline !important 104 | } 105 | .mbd, .mvd, .mad{ 106 | margin-bottom: @baseline * 2 !important 107 | } 108 | .mln, .mhn, .man{ 109 | margin-left: 0 !important 110 | } 111 | .mlh, .mhh, .mah{ 112 | margin-left: @baseline / 2 !important 113 | } 114 | .mls, .mhs, .mas{ 115 | margin-left: @baseline !important 116 | } 117 | .mld, .mhd, .mad{ 118 | margin-left: @baseline * 2 !important 119 | } 120 | .lhh { 121 | line-height: @baseline / 2 !important; 122 | } 123 | .lhs { 124 | line-height: @baseline !important; 125 | } 126 | .lhd { 127 | line-height: @baseline * 2 !important; 128 | } 129 | .lhn { 130 | line-height: 0 !important; 131 | } 132 | -------------------------------------------------------------------------------- /styles/base/variables.less: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | Spacing 3 | ========================================================================== */ 4 | 5 | @baseline: 20px; 6 | 7 | /* ========================================================================== 8 | Typography 9 | ========================================================================== */ 10 | 11 | @body-color: #555; 12 | @body-font-family: "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, "Lucida Grande", sans-serif; 13 | @body-font-size: 14px; 14 | @body-accent-color: #f00; 15 | 16 | @header-color: #000; 17 | @header-font-family: "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, "Lucida Grande", sans-serif; 18 | @header-font-weight: bold; 19 | 20 | /* ========================================================================== 21 | Grid 22 | ========================================================================== */ 23 | 24 | @fixed-column-width: 40px; 25 | @fixed-gutter-width: 20px; 26 | @fixed-columns: 12; 27 | 28 | @fluid-column-width: 4.3%; 29 | @fluid-gutter-width: 4.4%; 30 | @fluid-columns: 12; 31 | 32 | @mobile-break-width: 480px; 33 | @mobile-column-width: 20%; 34 | @mobile-gutter-width: 6.6666%; 35 | @mobile-columns: 4; 36 | 37 | /* ========================================================================== 38 | Buttons 39 | ========================================================================== */ 40 | 41 | @button-color: #DDD; 42 | @button-primary-color: #0055CC; 43 | @button-info-color: #2F96B4; 44 | @button-success-color: #51A351; 45 | @button-warning-color: #FAA732; 46 | @button-danger-color: #BD362F; 47 | 48 | /* ========================================================================== 49 | Site Variables 50 | ========================================================================== */ 51 | 52 | @import "../site/variables"; -------------------------------------------------------------------------------- /styles/print.css: -------------------------------------------------------------------------------- 1 | body, .site-title, h1, h2, h3{ 2 | font-family: 'Georgia' !important; 3 | } 4 | 5 | 6 | nav.site-navigation, a.fork-me, a.top{ 7 | display:none; 8 | } 9 | 10 | div.site-content{ 11 | padding: 20px 40px 40px 20px; 12 | } -------------------------------------------------------------------------------- /styles/site/site-content.less: -------------------------------------------------------------------------------- 1 | .site-content{ 2 | padding: 20px 40px 40px 320px; 3 | 4 | h1{ 5 | clear: both; 6 | } 7 | } 8 | .interior-site-content{ 9 | .pad; 10 | } 11 | .top{ 12 | background: #333; 13 | display: inline-block; 14 | float: right; 15 | margin-right: -40px; 16 | padding: 4px 8px; 17 | color: #FFF; 18 | font-size: 12px; 19 | text-decoration: none !important; 20 | } 21 | -------------------------------------------------------------------------------- /styles/site/site-footer.less: -------------------------------------------------------------------------------- 1 | .site-footer{ 2 | clear: both; 3 | .ptd; 4 | font-size: 13px; 5 | text-align: center; 6 | } 7 | .site-footer img{ 8 | margin-left: 2px; 9 | position: relative; 10 | top: -2px; 11 | vertical-align: middle; 12 | } 13 | .site-footer ul{ 14 | list-style: none; 15 | .mhn; 16 | .phn; 17 | } 18 | -------------------------------------------------------------------------------- /styles/site/site-header.less: -------------------------------------------------------------------------------- 1 | .site-header{ 2 | position: relative; 3 | z-index: 1; 4 | text-align: center; 5 | } 6 | .site-title{ 7 | .mbn; 8 | font-family: 'Alfa Slab One'; 9 | font-size: @baseline * 4; 10 | font-weight: normal !important; 11 | line-height: @baseline * 5 !important; 12 | 13 | a{ 14 | text-decoration: none; 15 | } 16 | } 17 | .site-slogan{ 18 | font-weight: normal; 19 | } 20 | .fork-me, .fork-me img{ 21 | position: absolute; 22 | top: 0; 23 | right: 0; 24 | } 25 | .fork-me{ 26 | z-index: 2; 27 | } 28 | 29 | .interior-site-header{ 30 | background: #EEE; 31 | .inner-shadow(fade(#000, 7%) 0 0 40px); 32 | .pas; 33 | text-align: center; 34 | 35 | .site-title{ 36 | font-size: @baseline * 2; 37 | line-height: @baseline * 2 !important; 38 | } 39 | .site-slogan{ 40 | .mbs; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /styles/site/site-navigation.less: -------------------------------------------------------------------------------- 1 | .site-navigation{ 2 | background: #EEE; 3 | .inner-shadow(fade(#000, 7%) 0 0 40px); 4 | .pas; 5 | position: fixed; 6 | top: 0; 7 | bottom: 0; 8 | overflow: auto; 9 | width: 240px; 10 | } 11 | .build-date{ 12 | .mbs; 13 | color: #AAA; 14 | font-family: Helvetica, Arial, sans-serif; 15 | font-size: 11px; 16 | } 17 | .site-navigation ul{ 18 | .man; 19 | .pan; 20 | .no-list; 21 | font-size: 16px; 22 | margin-bottom: 10px; 23 | } 24 | .site-navigation > ul > li{ 25 | margin-bottom: 10px; 26 | } 27 | .site-navigation a{ 28 | text-decoration: underline; 29 | 30 | &:hover{ 31 | text-decoration: none; 32 | } 33 | } 34 | .site-navigation a.active{ 35 | background-color: #ff9; 36 | } 37 | .site-navigation ul ul{ 38 | .mls; 39 | .pth; 40 | font-size: 12px; 41 | 42 | a{ 43 | text-decoration: none; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /styles/site/variables.less: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | Spacing 3 | ========================================================================== */ 4 | 5 | @baseline: 20px; 6 | 7 | /* ========================================================================== 8 | Typography 9 | ========================================================================== */ 10 | 11 | @body-color: #666; 12 | @body-font-family: "Droid Serif", Georgia, "Times New Roman", Times, serif; 13 | @body-font-size: 14px; 14 | @body-accent-color: #000; 15 | 16 | @header-color: #111; 17 | @header-font-family: "Droid Serif", Georgia, "Times New Roman", Times, serif; 18 | @header-font-weight: 700; 19 | 20 | /* ========================================================================== 21 | Grid 22 | ========================================================================== */ 23 | 24 | @fixed-column-width: 60px; 25 | @fixed-gutter-width: 20px; 26 | @fixed-columns: 12; 27 | 28 | @fluid-column-width: 4.3%; 29 | @fluid-gutter-width: 4.4%; 30 | @fluid-columns: 12; 31 | 32 | @mobile-break-width: 480px; 33 | @mobile-column-width: 20%; 34 | @mobile-gutter-width: 6.6666%; 35 | @mobile-columns: 4; 36 | 37 | /* ========================================================================== 38 | Buttons 39 | ========================================================================== */ 40 | 41 | @button-color: #DDD; 42 | @button-primary-color: #0055CC; 43 | @button-info-color: #2F96B4; 44 | @button-success-color: #51A351; 45 | @button-warning-color: #FAA732; 46 | @button-danger-color: #BD362F; 47 | -------------------------------------------------------------------------------- /styles/syntax.css: -------------------------------------------------------------------------------- 1 | .highlight { background: #ffffff; margin: 0 4px; font-size: 0.8em; } 2 | .highlight .c { color: #999988; font-style: italic } /* Comment */ 3 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 4 | .highlight .k { font-weight: bold } /* Keyword */ 5 | .highlight .o { font-weight: bold } /* Operator */ 6 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ 7 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ 8 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ 9 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ 10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 11 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ 12 | .highlight .ge { font-style: italic } /* Generic.Emph */ 13 | .highlight .gr { color: #aa0000 } /* Generic.Error */ 14 | .highlight .gh { color: #999999 } /* Generic.Heading */ 15 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 16 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ 17 | .highlight .go { color: #888888 } /* Generic.Output */ 18 | .highlight .gp { color: #555555 } /* Generic.Prompt */ 19 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 20 | .highlight .gu { color: #aaaaaa } /* Generic.Subheading */ 21 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */ 22 | .highlight .kc { font-weight: bold } /* Keyword.Constant */ 23 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */ 24 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */ 25 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */ 26 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ 27 | .highlight .m { color: #009999 } /* Literal.Number */ 28 | .highlight .s { color: #d14 } /* Literal.String */ 29 | .highlight .na { color: #008080 } /* Name.Attribute */ 30 | .highlight .nb { color: #0086B3 } /* Name.Builtin */ 31 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ 32 | .highlight .no { color: #008080 } /* Name.Constant */ 33 | .highlight .ni { color: #800080 } /* Name.Entity */ 34 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ 35 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ 36 | .highlight .nn { color: #555555 } /* Name.Namespace */ 37 | .highlight .nt { color: #000080 } /* Name.Tag */ 38 | .highlight .nv { color: #008080 } /* Name.Variable */ 39 | .highlight .ow { font-weight: bold } /* Operator.Word */ 40 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 41 | .highlight .mf { color: #009999 } /* Literal.Number.Float */ 42 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */ 43 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */ 44 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */ 45 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */ 46 | .highlight .sc { color: #d14 } /* Literal.String.Char */ 47 | .highlight .sd { color: #d14 } /* Literal.String.Doc */ 48 | .highlight .s2 { color: #d14 } /* Literal.String.Double */ 49 | .highlight .se { color: #d14 } /* Literal.String.Escape */ 50 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */ 51 | .highlight .si { color: #d14 } /* Literal.String.Interpol */ 52 | .highlight .sx { color: #d14 } /* Literal.String.Other */ 53 | .highlight .sr { color: #009926 } /* Literal.String.Regex */ 54 | .highlight .s1 { color: #d14 } /* Literal.String.Single */ 55 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */ 56 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ 57 | .highlight .vc { color: #008080 } /* Name.Variable.Class */ 58 | .highlight .vg { color: #008080 } /* Name.Variable.Global */ 59 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */ 60 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ --------------------------------------------------------------------------------