Place your screenshot here
Essential
Tools for
Modern PHP
Alex Weissman
GIT
PSR
Composer NODE.JS
PHP
UNIT
PHP
DOCMARKDOWN
Fred Brooks, The Mythical Man-Month
We learn how to
make this in school
(or at home)
But this is what
we're building in
the "real world"
GitVersion control system,
the basis for Github.
Stores snapshots,
enhances collaboration.
ComposerA dependency manager
for PHP.
Node.jsAn open-source cross-
platform runtime
environment, helps with
asset management and
deployment. Node Package
Manager, npm, is its
dependency manager.
PSRCoding standards for
PHP that include
formatting, syntax, best
practices and
interoperability.
PHP UnitEssential tool for creating
and running automated
tests.
PHP DocStandards for low-level
documentation
(comments) in your code
base.
Overview
Essential
Tools
MarkdownA language for formatting
plain text. Makes
communication easier.
What is the main job of a
software developer?
The ratio of time spent reading versus writing is
well over 10 to 1. We are constantly reading old
code as part of the effort to write new code.
...[Therefore,] making it easy to read makes it
easier to write.
― Robert C. Martin, Clean Code: A Handbook of
Agile Software Craftsmanship
MARKDOWN, PHPDOC,
AND CODING STYLE
01
MARKDOWN● The format for writing readable content (especially code) on the web
● Alternative to allowing people to enter HTML, which:
○ Is more verbose and takes longer to write;
○ Requires special handling to prevent XSS attacks
MARKDOWN
MARKDOWN
https://daringfireball.net/projects/markdown/
PHPDOC● Document each file, class, member variable, and method with a DocBlock
● DocBlocks contain both free text descriptions and structured metadata (tags)
● DocBlocks can be automatically parsed by:
○ Text editors and IDEs for type-hinting and code completion;
○ Standalone tools to generate API documentation
/**
* A BelongsToMany relationship that supports ternary (three-way) pivot relationships.
*
* @author Alex Weissman (https://alexanderweissman.com)
* @link https://github.com/laravel/framework/
*/
class BelongsToTernary extends BelongsToMany
{
…
}
CODING STYLE
PHP Standards Recommendations (PSRs): PSR-1 and PSR-2
CODING STYLEusrefrostieng is a web framework for php
but other web framework offers a
compleate toolbox of pogram modules for
build app.its a fully-functioning user
managment ap unlike other php famework
right out of the box and full extandable
so that you can easly create the custom
feature userfroasting design hellp new and return
devlopers up to speed at modern php so youll be
comfortably intoduce to COMPOSER and PSR for
better structure ur code and easy manage when you'll
learn use node and Bower to cleanly manage client-
side packages (JAVASCRIPT and CSS)
UserFrosting is a web framework for PHP. Like other web
frameworks, it offers a complete toolbox of programmatic
components for building your application.
Unlike other PHP frameworks, it's a fully-functioning user
management application, right out of the box. And, it's fully
extendable so that you can easily create the custom features
you need.
UserFrosting is designed to bring new and returning
developers up to speed with the modern PHP community.
You'll be comfortably introduced to Composer (the
dependency manager), object-oriented design patterns, and
the PHP Standards Recommendations (PSR), making your
code better structured and easier to manage.
What's more, you'll learn how to use Node.js and Bower to
cleanly manage client-side packages (Javascript and CSS).
Transform yourself from a code monkey into a software
engineer.
CODING STYLEclass loggedInUser {
public $email = NULL;
public $hash_pw = NULL;
public $user_id = NULL;
public $csrf_token = NULL;
// Simple function to update the last sign in of a user
public function updateLastSignIn() {
updateUserLastSignIn($this->user_id);
}
// Return the timestamp when this user's account was registered
public function signupTimeStamp(){
return fetchUserField($this->user_id, 'sign_up_stamp');
}
//csrf tokens
public function csrf_token($regen = false)
{
if($regen === true) {
//*make sure token is set, if so unset*//
if(isset($_SESSION["__csrf_token"])) {
unset($_SESSION["__csrf_token"]);
}
if (function_exists('openssl_random_pseudo_bytes')) {
$rand_num =
openssl_random_pseudo_bytes(16);//pull 16 bytes from /dev/random
}else{
CODING STYLEnamespace App\Model;
class LoggedInUser
{
public $id = NULL;
public $email = NULL;
public $password = NULL;
public $csrfToken = NULL;
/**
* Update the last sign in time of a user
*
* @return \App\Model\LoggedInUser
*/
public function updateLastSignIn()
{
$this->updateField('last_sign_in');
return $this;
}
/**
* Return the timestamp for when this user's account was registered
*
* @return string
*/
public function signupTimeStamp()
{
return $this->fetchField('sign_up_stamp');
}
}
PSR-1 and PSR-2● Don’t use ?>
● 4 spaces for indentation
○ DON’T use tabs
○ DO configure your text editor to write 4 spaces when you press tab
● One statement;
● Per line;
● Control structures: opening brace on same line
● This code snippet encompasses a lot of the other formatting rules:
if ($a === $b) {
bar();
} elseif ($a > $b) {
$foo->bar($arg1);
} else {
BazClass::bar($arg2, $arg3);
}
<?php
/**
* Owl Fancy
*
* @link https://owlfancy.com
* @license All rights reserved
*/
namespace App\Models;
use App\Mail\Mailer;
class Member
{
/**
* Email member with reminder to renew subscription.
*
* @param App\Mail\Contact $senderInfo
* @param string $params
* @return string
*/
public function sendSubscriptionReminder($senderInfo, $params)
{
$message = new Mailer($senderInfo, $this->email);
return $message->render('bill-reminder.html.twig', $params);
}
...
}
Object-oriented programming
• Namespaces!
• Stricter naming conventions for
classes, methods
• One class per file!
• Separation of concerns. Avoid
side effects - A file should either
define symbols OR perform
logic/render content
PSR-1 and PSR-2
PSR’s don’t have rules for
everything, but you shouldBe consistent, even if PSR's do not provide a specific requirement!
• Variables - choose a style like camelCase;
• Functions - camelCase;
• Array keys - snake_case;
• Double vs single quotes - single quotes when double aren’t necessary
• Naming conventions – create vs createUser vs userCreate
GIT
02
WHAT IS VERSION CONTROL?
Version control systems are a category of software
tools that help a software team manage changes
to source code over time.
- Atlassian, Git Tutorial
Life before
version control
● What has been changed from one version to
the next?
● Who made those changes, and why?
● How can I integrate changes that have been
made by multiple developers in a non-blocking
way?
● Finding specific changes and stepping back to
previous states?
● I'd like to do these things efficiently and
automatically.
A tool that solves...
Life after
version control• I know who did what and when.
• I can easily see what has changed.
• Commit messages summarize changes.
• Collaboration with team members and the open source community.
• I can use it for deployment.
How git works
The working tree is my code, as it stands right
now.
A change is adding, modifying, or deleting a line
of code in my working tree.
A commit is a set of changes made by a
specific person at a specific point in time.
The repository is the current working tree
together with its commit history and various
references to specific commits.
This is all happening locally, on your machine.
ANATOMY OF A GIT REPOSITORY
alexw @ 2017-01-01 03:05:49
Fix directory traversal vulnerability
3 lines added, 4 changed, 2 removed
alexw @ 2017-01-01 22:11:17
Fix directory traversal vulnerability
for real this time
7 lines changed
sarah @ 2017-01-04 11:17:10
Improve Alex's terrible CSS
4 lines changed, 3 removedHEAD
alexw @ 2017-01-01 03:05:49
Fix directory traversal vulnerability
3 lines added, 4 changed, 2 removed
alexw @ 2017-01-01 22:11:17
Fix directory traversal vulnerability
for real this time
7 lines changed
sarah @ 2017-01-04 11:17:10
Improve Alex's terrible CSS
4 lines changed, 3 removed
HEAD
site/
├── config/
└── default.php
├── src/
└── composer.json
alexw @ 2017-01-05 23:18:01
Turn off debugging in config
2 lines changed, 1 removed
site/
├── config/
└── default.php
├── src/
└── composer.json
commit
stage
working tree commit history
older commits
ANATOMY OF A GIT REPOSITORY
Remotes
● A remote refers to an authoritative version
of the project on a server.
● Github offers public remote repositories for
free.
● For private repos, use Bitbucket for free,
run your own git server, or get a paid
Github account.
● git clone creates a new user’s local
copy of the project, with the full history
● git push adds a user’s local commits to
the repository
● git pull adds other team member’s
changes to a user’s local copy
● Git uses various strategies to deal with
complex changes. These are fetch and
merge strategies, and learn about these in
an advanced course. Merge conflicts can
be manually resolved where needed.
Branches
● git branch creates an alternative
timeline for experimental features,
bugfixes, and divergent ideas.
● Branches can be merged or discarded as
needed.
● git checkout allows you to switch
between branches
GIT
COMPOSER
03
COMPOSER
● The dependency (package) management tool for PHP since 2012
● Downloads and installs packages from packagist.org
● Automatically resolves dependency graphs
● Designed in conjunction with PSR-4 (autoloading)
<?php
error_reporting (E_ALL ^ E_WARNING);
require('./class_definitions.inc');
require('./user_profiles.inc');
require('./file_submission.inc');
require('configurator_object.inc');
$configurators = array();
require('load_objects.inc');
unset($configurators);
session_start();
<?php
require_once __DIR__ . '/../vendor/autoload.php';
COMPOSER
{
"name": "userfrosting/userfrosting",
"require": {
"pimple/pimple": "~3.1.0",
"slim/slim": ”^3.0"
},
"autoload": {
"psr-4": {
"UserFrosting\\Sprinkle\\Core\\": "src/"
}
}
}
composer.json
$ composer install
$ composer update
COMPOSER
userfrosting/userfrosting 4.1
pimple/pimple ~3.1.0
pimple/pimple 3.*
slimphp/slim ^3.0
psr/container 1.0
COMPOSER
userfrosting/userfrosting 4.1
pimple/pimple ~3.1.0
pimple/pimple 3.*
slimphp/slim ^3.0
psr/container 1.0
COMPOSERvendor/
├── pimple/pimple 3.1.2
├── slimphp/slim 3.9
└── psr/container 1.0
hey man you see
that package over
there
he doesn’t use
semantic versioning
COMPOSER
AUTOMATED TESTING
WITH PHPUNIT
04
AUTOMATED TESTING
• Prevent regressions!
• More confidence when
making changes
• Built-in specifications
AUTOMATED TESTINGFunctional tests
• Test overall behavior and I/O
• Fairly easy to write, even for
existing code
public function testBelongsToMany()
{
$worker = EloquentTestWorker::first();
$worker->jobs()->attach([1,2]);
$this->assertArrayEqual([
[
'id' => 1,
'label' => 'forager',
'pivot' => [
'worker_id' => 1,
'job_id' => 1
]
],
…
], $worker->jobs->toArray());
}
AUTOMATED TESTINGUnit tests
• Test individual methods
• Test both what your methods do
and how they do it
• Harder to write, requires careful
design (design for testability,
inversion of control)
• Often written before the code itself
as a specification (test-driven
development)
• Mockery
public function testSyncMethod($list)
{
$relation = $this->getRelation();
// Simulate determination of related key from builder
$relation->getRelated()->shouldReceive('getKeyName')->once()-
>andReturn('id');
// Simulate fetching of current relationships (1,2,3)
$query = m::mock('stdClass');
$relation->shouldReceive('newQuery')->once()->andReturn($query);
$query->shouldReceive('pluck')->once()->with('id')->andReturn(new
BaseCollection([1, 2, 3]));
// withoutGlobalScopes will get called exactly 3 times
$relation->getRelated()->shouldReceive('withoutGlobalScopes')-
>times(3)->andReturn($query);
// Test deletions of items removed from relationship (1)
$query->shouldReceive('whereIn')->once()->with('id', [1])-
>andReturn($query);
$query->shouldReceive('delete')->once()->andReturn($query);
…
// Check result
$this->assertEquals(['created' => ['x'], 'deleted' => [1],
'updated' => [2,3]], $relation->sync($list));
}
BUILDING AND
DEPLOYMENT
05
BUILDING AND DEPLOYMENT
THANK YOU!