Saturday, August 13, 2016

Deploy Your PHP Application With Rocketeer_part 1


There used to be a time when PHP developers had to use deployment tools that were aimed at general web applications. You can see this in Johannes Schickling's tutorial on deploying Laravel applications with Capistrano, for example. It's a Ruby tool, and you need to write Ruby code. These tools get the job done but have limited integration with PHP applications. This can result in hacky solutions for certain scenarios.

But nowadays, we're blessed with a few deployment tools written in our language that enable deeper integration. One of these tools is Rocketeer, a tool that takes inspiration from Capistrano and the Laravel framework.

Rocketeer is a modern tool that brings a great approach for your deployment needs. That is to run tasks and manage your application across different environments and servers. On top of that, it also has some magic in it, like installing Composer dependencies if it detects a composer.json file. You get sane defaults and automation of common tasks for a modern PHP application. And you have the ability to customise and extend everything.

You could describe it as an SSH task runner that runs client-side. The commands execute on servers through an SSH connection. If you use a shared hosting provider with only FTP access, you're out of luck, unfortunately. What you also need is a remote repository where the tool can fetch your code from. There is support for Git and SVN by default. Need support for another version control system? Write your own implementation with the provided interfaces.

Installation

You can install Rocketeer in two different ways. Either you download the phar file and make it executable or you install it through Composer. I'm a supporter of the latter. Having it as a dependency allows for easy installation when cloning the repository. This can benefit anyone cloning the repository to get them up and running.

Installing with Composer:
  1. $ composer require anahkiasen/rocketeer --dev
I don't recommend that you install it globally. Keeping it on the repository level will ensure that each person deploying is running the same version. What I do recommend is that you add vendor/bin to your PATH. Then you can use the binary by typing rocketeer in your project root.

Ignition

Let's get started! First you bootstrap the directories and files for configuration. You do this by running rocketeer ignite in the root of your project.

When your application ignites, the tool creates a .rocketeer folder in your project. The contents of the directory will look like this:
  1. | .rocketeer
  2. | -- config.php
  3. | -- hooks.php
  4. | -- paths.php
  5. | -- remote.php
  6. | -- scm.php
  7. | -- stages.php
  8. | -- strategies.php
These are all the configuration files you need to start setting up your deployments. Whenever I refer to a configuration file from here on out, it exists in the .rocketeer/ directory.

Remote Folder Structure
It's important to understand how Rocketeer manages its folder structure on the server side, since it's a bit different to a regular setup. It uses a few directories for managing certain aspects of the deployment, so it can be effective at what it does. You specify a path to where you want to deploy your application on your server, and the tool will take care of the rest. That folder will look like this, if you have /var/www/app as your application directory.
  1. | /var/www/app
  2. |  | -- current => /var/www/app/releases/20160103183754
  3. |  | -- releases
  4. |  |  | -- 20160101161243
  5. |  |  |  |-- uploads => /var/www/app/shared/uploads
  6. |  |  | -- 20160103183754
  7. |  |  |  |-- uploads => /var/www/app/shared/uploads
  8. |  | -- shared
  9. |  |  | -- uploads
The most important folder is current, which points to your latest release. That is where your web server's document root should be set to. So what happens when you deploy?
  • The tool creates a time-stamped folder in the releases directory.
  • Completes all tasks to make a ready release.
  • Updates the symbolic link current to the new release.
This process makes your deployment transparent to the user. The switch between releases is almost instant, usually referred to as atomic deployments.

Some data should be persistent between your deployments. This can be file uploads, user sessions and logs, for example. Those files or folders go into the shared directory. The tool creates symbolic links inside each release for the ones you've configured.

Events

Events drive the tool, and all strategies and tasks fire a before and after event when they run. They also provide a special halt event when a task fails. This could be for example dependencies.halt, or deploy.halt for general failure. This allows us to hook into the process where we need to.

The default events that happen during a deployment are:
  • deploy.before: before anything happens.
  • create-release.before: before it creates a new release directory.
  • create-release.after: after creating a new release directory.
  • dependencies.before: before installing or updating dependencies.
  • dependencies.after: after installing or updating dependencies. Perhaps make sure that binaries in your vendor folder are executable.
  • test.before: before running tests.
  • test.after: after running tests.
  • migrate.before: before running database migrations. Maybe you want to do a backup of your database?
  • migrate.after: after running database migrations.
  • deploy.before-symlink: before symlinking the release as our current release.
  • deploy.after: completed. You could notify people that everything was smooth sailing or otherwise.
We can also create our own events that we can fire and listen to. For now, we'll stick with these events provided for us. They will be enough for us right now.

Tasks

At the heart of Rocketeer, we find a concept called tasks. Most of what is happening under the hood are core tasks. The definition of a task could be a set of instructions to perform as a step in a deployment. If we look at some of the classes that the tool provides, we can get a general feel of what tasks are: classes such as DeploySetupMigrateRollback, and Dependencies. When you deploy, the deploy command itself is a task with sub-tasks.

Types of Tasks
This is where you'll start to see how integrated the tool is with PHP, since you'll write tasks in the language. You can create your own tasks in three different ways:

Arbitrary terminal commands. These are one-liners that you want to run on your server. Can be useful for a lot of things, like running gulp build  ---production for example.

Closures. If you need a bit more flexibility or complexity, you can write a task as a closure (anonymous function). Say you'd like to generate documentation for an API during your deployment.
  1. function($task) {
  2.     return $task->runForCurrentRelease('apigen generate  source src  destination api');
  3. }
Classes. For more complex tasks, you should utilise the option to create classes for tasks. You create a class and extend Rocketeer\Abstracts\AbstractTask. Then you must provide at least a description and an execute() method. Here's a completely useless example just to show the structure of a task class:
  1. namespace MyDeployableApp\Deploy\Tasks;
  2.  
  3. class HelloWorld extends \Rocketeer\Abstracts\AbstractTask
  4. {
  5.     /**
  6.      * Description of the Task
  7.      *
  8.      * @var string
  9.      */
  10.     protected $description = 'Says hello to the world';
  11.  
  12.     /**
  13.      * Executes the Task
  14.      *
  15.      * @return void
  16.      */
  17.     public function execute() {
  18.         $this->explainer->line('Hello world!');
  19.  
  20.         return true;
  21.     }
  22. }
Note that you have to register task classes yourself. Either you do this through the hooks.php file and add it to the custom array...
  1. 'custom' => array('MyDeployableApp\Deploy\Tasks\HelloWorld',),
... or you can do this through the facade:
  1. Rocketeer::add('MyDeployableApp\Deploy\Tasks\HelloWorld');
Once you register it, you can execute it:
  1. $ rocketeer hello:world
  2. staging/0 | HelloWorld (Says hello to the world)
  3. staging/0 |=> Hello world!
  4. Execution time: 0.004s
Defining Tasks

We discussed events first because we hook tasks in where we need them in the process. You can do this in a few ways. Go with the one you like and that meets requirements for your level of complexity.

The easiest way of defining your tasks is in the hooks.php file. It provides two arrays for this, specifying task execution before or after certain events.
  1. 'before' => [
  2.     'setup' => [],
  3.     'deploy' => ['hello:world'],
  4.     'cleanup' => [],
  5. ],
Strategies

You might be able to tell already that the tasks provided are quite generic. Take Dependencies, for example. What kind of dependencies are we talking about and which package manager?

This is where strategies come into play. A strategy is a specific implementation of a task, such as running tests with Behat or using Gulp for building your front-end. Tasks have a default strategy with the option of running the other strategies through the CLI. We can list the strategies available like this:


Creating Your Own Strategies

Say you're doing BDD With Behat for your application instead of TDD. Then you want to run your tests with Behat instead of PHPUnit. Since it is a test runner, there is already a strategy namespace for that, but no implementation. Create the directory .rocketeer/strategies/ and place your new BehatStrategy.php in there.
  1. namespace MyDeployableApp\Deploy\Strategies;
  2.  
  3. use Rocketeer\Abstracts\Strategies\AbstractStrategy;use Rocketeer\Interfaces\Strategies\TestStrategyInterface;
  4.  
  5. class BehatStrategy extends AbstractStrategy implements TestStrategyInterface
  6. {
  7.     public function test() {
  8.         return $this->binary('vendor/bin/behat')->runForCurrentRelease();
  9.     }
  10. }
You can now switch out your test strategy to the new implementation in strategies.php.
  1. 'test' => 'Behat',
Connections & Stages

It doesn't matter if you have an infrastructure in place or have one in mind. It doesn't matter if your application deploys to many environments across many servers. Rocketeer will be there for you. You can even have many varying locations on the same server. This is where the terms connections and stages enter.

A connection is a server where you deploy your application to. This is often called an environment, and production and staging are examples of this. Configuring these connections is a breeze in the tool. Either you do it through a nested array or by keeping separate files for each connection. Each connection can also have multiple servers in it.

Stages are like connections inside connections, a kind of "connectionception". You could set up a staging and a production environment on a single server with the use of stages. So instead of having two separate connections, you have one connection with two stages in it.

Plugins

A great feature is that we can extend our process using plugins. There are a few official ones for integration with Laravel, Slack, HipChat and Campfire. Then there are a few, but not that many, on Packagist. Installing plugins is an easy task through the CLI:
  1. $ rocketeer plugin:install rocketeers/rocketeer-slack
Even though there's a limited number of plugins, it leaves room for developing plugins in the future. It tells of a good philosophy. And why not develop one of your own?
Written by Niklas Modess

If you found this post interesting, follow and support us.
Suggest for you:

Learn PHP 7 This Way to Rise Above & Beyond Competion!

PHP MySQL Database Connections

The Complete PHP with MySQL Developer Course (New)

Learn what's new in PHP 7

Modern Programming with PHP

Friday, August 12, 2016

How to Become a Web Developer: Learn PHP

In a recent course, I took you through the process of learning PHP from scratch. In this short video from the course, you’ll learn to write your first line of PHP code. I’ll show you how to mix HTML and PHP in a .php file. I’ll also teach you about HTTP server default documents.

Write Your First Line of PHP Code


 Make Sure the Servers Are Running
In the previous lesson of the course, we installed a utility called MAMP which makes it easier to get started with PHP development on Windows and macOS. So the first thing we want to do is ensure that MAMP is running, and you also want to make sure that the servers are running.

Now we don't care about MySQL Server, but Apache server is vital because that is how we are going to access our files through HTTP. To ensure that it's running, there is an indicator there to show you that it is running.

Add Your First File
From that same MAMP screen, go to the Preferences > Web Server tab and make note of the path you see there.


This is the document root. This is where we put all of our documents so that we can access them through HTTP. Now minimize this screen, and then let's go to that path and we will see what's there.

You should find that there's nothing there. So we are going to add the first file. Fire up your code editor—I'm going to use Visual Studio Code, and I've already pointed it to that folder. Add a new file and call it index.php.

The Default Document
The default document is the document that the web server is going to serve if you don't specify one. For example, if you open up the browser and go to local host without an index.php file listed, you'll just see "Index of" and then a slash. This means that we are at the root of our website, and right now we don't have any default document.

So when you go ahead and add index.php, you can type anything in there and it will display in the browser. You can just type text, for example, or HTML. But, of course, we're interested in PHP, so let's see how you add your first line of PHP code.

How to Build a Line of PHP Code
Whenever we want to switch into PHP code, we have to have a delimiter—something that says that this block of text is special and we want to treat it as PHP. We do that with an opening angle bracket followed by a question mark. And really that's good enough but the best practice is to add php:
<?php

This says that anything after this delimiter is going to be PHP. So if we just type some dummy text here and go back to the browser and refresh, then you'll see an error message with a response code of 500.

That means that something on the server went wrong, and that's because what we typed was just dummy text, not valid PHP code.

To create valid PHP code, first we need to end our code block with ?>. Then we can go back to the browser and refresh, and we're not going to get that error 500 any more. (Note that some scripts that will be included in other scripts omit this closing ?> tag. See this discussion on Stack Overflow.)

Now let's write some PHP. Our first line of PHP code is going to use something called echo. This is a function that we can execute that writes whatever it is that we want to write to the browser.

Actually, that's not technically correct. We are actually outputting data to the response stream but, practically, it's being written to the browser. So here we say echo, this is a function that we are calling, and then we want to echo some text. So we begin with a string. Strings in PHP can start and end with a pair of double quotes, but the standard practice is to use single quotes.

So we will have echo, and then a single quote. This is inside PHP that we have the closing single quotes. And then we type some text, and end the line with a semi-colon. The whole thing should look like this:
  1. <?php
  2. echo 'this is inside php'; 
  3. ?>
So let's save that and go back to the browser, and you should see the text displayed.

Note that whenever you echo something, you can also include HTML. So let's put this text inside an opening and closing p tag:
  1. <?php
  2. echo '<p>this is inside php</p>'; 
  3. ?>
When you go back to the browser and refresh, you'll see that HTML was rendered.

And so now you've written your first line of PHP code. It was very simple, but we all have to start somewhere.
Written by Jeremy McPeak

If you found this post interesting, follow and support us.
Suggest for you:

Learn PHP 7 This Way to Rise Above & Beyond Competion!

PHP MySQL Database Connections

The Complete PHP with MySQL Developer Course (New)

Thursday, August 11, 2016

Best Practices for Modern PHP Development_part2(end)


3.1.3 I - Interface Segregation Principle

This principle says to favor many small, fine grained interfaces vs. one large one. Interfaces should be based on behavior rather than "it's one of these classes". Think of interfaces that come with PHP. Traversable, Countable, Serializable, things like that. They advertise capabilities that the object possesses, not what it inherits from. So keep your interfaces small. You don't want an interface to have 30 methods on it, 3 is a much better goal.

3.1.4 D - Dependency Inversion Principle

You've probably heard about this in other places that talked about Dependency Injection, but Dependency Inversion and Dependency Injection aren't quite the same thing. Dependency inversion is really just a way of saying that you should depend on abstractions in your system and not on its details. Now what does that mean to you on a day to day basis?

Don't directly use mysqli_query() all over your code, use something like DataStore->query() instead.

The core of this principle is actually about abstractions. It's more about saying "use a database adapter" instead of depending on direct calls to things like mysqli_query. If you're directly using mysqli_query in half your classes then you're tying everything directly to your database. Nothing for or against MySQL here, but if you are using mysqli_query, that type of low level detail should be hidden away in only one place and then that functionality should be exposed via a generic wrapper.

Now I know this is kind of a hackneyed example if you think about it, because the number of times you're going to actually completely change your database engine after your product is in production are very, very low. I picked it because I figured people would be familiar with the idea from their own code. Also, even if you have a database that you know you're sticking with, that abstract wrapper object allows you to fix bugs, change behavior, or implement features that you wish your chosen database had. It also makes unit testing possible where low level calls wouldn't.

4 Object calisthenics

This isn't a full dive into these principles, but the first two are easy to remember, provide good value, and can be immediately applied to just about any codebase.

4.1 No more than one level of indentation per method

This is a helpful way to think about decomposing methods into smaller chunks, leaving you with code that's clearer and more self-documenting. The more levels of indentation you have, the more the method is doing and the more state you have to keep track of in your head while you're working with it.

Right away I know people will object to this, but this is just a guideline/heuristic, not a hard and fast rule. I'm not expecting anyone to enforce PHP_CodeSniffer rules for this (although people have).

Let's run through a quick sample of what this might look like:
  1. public function transformToCsv($data)
  2. {
  3.     $csvLines = array();
  4.     $csvLines[] = implode(',', array_keys($data[0]));
  5.     foreach ($data as $row) {
  6.         if (!$row) {
  7.             continue;
  8.         }
  9.         $csvLines[] = implode(',', $row);
  10.     }
  11.     return $csvLines;
  12. }
While this isn't terrible code (it's technically correct, testable, etc...) we can do a lot more to make this clear. How would we reduce the levels of nesting here?
We know we need to vastly simplify the contents of the foreach loop (or remove it entirely) so let's start there.
  1. if (!$row) {
  2.     continue;
  3. }
  4. This first bit is easy. All this is doing is ignoring empty rows. We can shortcut this entire process by using a built-in PHP function before we even get to the loop.
  5. $data = array_filter($data);
  6. foreach ($data as $row) {
  7.     $csvLines[] = implode(',', $row);
  8. }
We now have our single level of nesting. But looking at this, all we are doing is applying a function to each item in an array. We don't even need the foreach loop to do that.
  1. $data = array_filter($data);
  2. $csvLines =+ array_map('implode', $data, array_fill(0, count($data), ',');
Now we have no nesting at all, and the code will likely be faster since we're doing all the looping with native C functions instead of PHP. We do have to engage in a bit of trickery to pass the comma to implode though, so you could make the argument that stopping at the previous step is much more understandable.

4.2 Try not to use else

This really deals with two main ideas. The first one is multiple return statements from a method. If you have enough information do make a decision about the method's result, go ahead make that decision and return. The second is an idea known as Guard Clauses. These are basically validation checks combined with early returns, usually near the top of a method. Let me show you what I mean.
  1. public function addThreeInts($first, $second, $third) {
  2.     if (is_int($first)) {
  3.         if (is_int($second)) {
  4.             if (is_int($third)) {
  5.                 $sum = $first + $second + $third;
  6.             } else {
  7.                 return null;
  8.             }
  9.         } else {
  10.             return null;
  11.         }
  12.     } else {
  13.         return null;
  14.     }
  15.     return $sum;
  16. }
So this is pretty straightforward again, it adds 3 ints together and returns the result, or null if any of the parameters are not an integer. Ignoring the fact that we could combine all those checks onto a single line with AND operators, I think you can see how the nested if/else structure makes the code harder to follow. Now look at this example instead.
  1. public function addThreeInts($first, $second, $third) {
  2.     if (!is_int($first)) {
  3.         return null;
  4.     }
  5.     if (!is_int($second)) {
  6.         return null;
  7.     }
  8.     if (!is_int($third)) {
  9.         return null;
  10.     }
  11.     return $first + $second + $third;
  12. }
To me this example is much easier to follow. Here we're using guard clauses to verify our initial assertions about the parameters we're passing and immediately exiting the method if they don't pass. We also no longer have the intermediate variable to track the sum all the way through the method. In this case we've verified that we're already on the happy path and we can just do what we came here to do. Again we could just do all those checks in one if but the principle should be clear.

5 Unit testing

Unit testing is the practice of writing small tests that verify behavior in your code. They are almost always written in the same language as the code (in this case PHP) and are intended to be fast enough to run at any time. They are extremely valuable as a tool to improve your code. Other than the obvious benefits of ensuring that your code is doing what you think it is, unit testing can provide very useful design feedback as well. If a piece of code is difficult to test, it often showcases design problems. They also give you a safety net against regressions, and that allows you to refactor much more often and evolve your code to a cleaner design.

5.1 Tools

There are several unit testing tools out there in PHP, but far and away the most common is PHPUnit. You can install it by downloading a PHAR file directly, or install it with composer. Since we are using composer for everything else, we'll show that method. Also, since PHPUnit is not likely going to be deployed to production, we can install it as a dev dependency with the following command:
composer require --dev phpunit/phpunit

5.2 Tests are a specification

The most important role of unit tests in your code is to provide an executable specification of what the code is supposed to do. Even if the test code is wrong, or the code has bugs, the knowledge of what the system is supposed to do is priceless.

5.3 Write your tests first

If you've had the chance to see a set of tests written before the code and one written after the code was finished, they're strikingly different. The "after" tests are much more concerned with the implementation details of the class and making sure they have good line coverage, whereas the "before" tests are more about verifying the desired external behavior. That's really what we care about with unit tests anyway, is making sure the class exhibits the right behavior. Implementation-focused tests actually make refactoring harder because they break if the internals of the classes change, and you've just cost yourself the information hiding benefits of OOP.

5.4 What makes a good unit test

Good unit tests share a lot of the following characteristics:
  • Fast - should run in milliseconds.
  • No network access - should be able to turn off wireless/unplug and all the tests still pass.
  • Limited file system access - this adds to speed and flexibility if deploying code to other environments.
  • No database access - avoids costly setup and teardown activities.
  • Test only one thing at a time - a unit test should have only one reason to fail.
  • Well-named - see 5.2 above.
  • Mostly fake objects - the only "real" objects in unit tests should be the object we're testing and simple value objects. The rest should be some form of test double
There are reasons to go against some of these but as general guidelines they will serve you well.

5.5 When testing is painful
Unit testing forces you to feel the pain of bad design up front - Michael Feathers
When you're writing unit tests, you're forcing yourself to actually use the class to accomplish things. If you write tests at the end, or worse yet, just chuck the code over the wall for QA or whoever to write tests, you don't get any feedback about how the class actually behaves. If we're writing tests, and the class is a real pain to use, we'll find out while we're writing it, which is nearly the cheapest time to fix it.

If a class is hard to test, it's a design flaw. Different flaws manifest themselves in different ways, though. If you have to do a ton of mocking, your class probably has too many dependencies, or your methods are doing too much. The more setup you have to do for each test, the more likely it is that your methods are doing too much. If you have to write really convoluted test scenarios in order to exercise behavior, the class's methods are probably doing too much. If you have to dig inside a bunch of private methods and state to test things, maybe there's another class trying to get out. Unit testing is very good at exposing "iceberg classes" where 80% of what the class does is hidden away in protected or private code. I used to be a big fan of making as much as possible protected, but now I realized I was just making my individual classes responsible for too much, and the real solution was to break the class up into smaller pieces.
Written by Brian Fenton

If you found this post interesting, follow and support us.
Suggest for you:

Learning PHP 7: From the Basics to Application Development

The Complete PHP 7 Guide for Web Developers

Up to Speed with PHP 7

Learn PHP 7 This Way to Rise Above & Beyond Competion!

PHP MySQL Database Connections

The Complete PHP with MySQL Developer Course (New)



Tuesday, August 9, 2016

Best Practices for Modern PHP Development_part1


1 Setup and configuration

1.1 Keep Current

Let's call this out from the very beginning - a depressingly small number of PHP installs in the wild are current, or kept current. Whether that is due to shared hosting restrictions, defaults that no one thinks to change, or no time/budget for upgrade testing, the humble PHP binaries tend to get left behind. So one clear best practice that needs more emphasis is to always use a current version of PHP (5.6.x as of this article). Furthermore, it's also important to schedule regular upgrades of both PHP itself and any extensions or vendor libraries you may be using. Upgrades get you new language features, improved speed, lower memory usage, and security updates. The more frequently you upgrade, the less painful the process becomes.

1.2 Set sensible defaults

PHP does a decent job of setting good defaults out of the box with its php.ini.development and php.ini.production files, but we can do better. For one, they don't set a date/timezone for us. That makes sense from a distribution perspective, but without one, PHP will throw an E_WARNING error any time we call a date/time related function. Here are some recommended settings:
  • date.timezone - pick from the list of supported timezones
  • session.save_path - if we're using files for sessions and not some other save handler, set this to something outside of /tmp. Leaving this as /tmp can be risky on a shared hosting environment since /tmp is typically wide open permissions-wise. Even with the sticky-bit set, anyone with access to list the contents of this directory can learn all of your active session IDs.
  • session.cookie_secure - no brainer, turn this on if you are serving your PHP code over HTTPS.
  • session.cookie_httponly - set this to prevent PHP session cookies from being accessible via JavaScript
  • More... use a tool like iniscan to test your configuration for common vulnerabilities
1.3 Extensions

It's also a good idea to disable (or at least not enable) extensions that you won't use, like database drivers. To see what's enabled, run the phpinfo() command or go to a command line and run this.
  1. $ php -i
The information is the same, but phpinfo() has HTML formatting added. The CLI version is easier to pipe to grep to find specific information though. Ex.
  1. $ php -i | grep error_log
One caveat of this method though: it's possible to have different PHP settings apply to the web-facing version and the CLI version.

2 Use Composer

This may come as a surprise but one of the best practices for writing modern PHP is to write less of it. While it is true that one of the best ways to get good at programming is to do it, there are a large number of problems that have already been solved in the PHP space, like routing, basic input validation libraries, unit conversion, database abstraction layers, etc... Just go to Packagist and browse around. You'll likely find that significant portions of the problem you're trying to solve have already been written and tested.

While it's tempting to write all the code yourself (and there's nothing wrong with writing your own framework or library as a learning experience) you should fight against those feelings of Not Invented Here and save yourself a lot of time and headache. Follow the doctrine of PIE instead - Proudly Invented Elsewhere. Also, if you do choose to write your own whatever, don't release it unless it does something significantly different or better than existing offerings.

Composer is a package manager for PHP, similar to pip in Python, gem in Ruby, and npm in Node. It lets you define a JSON file that lists your code's dependencies, and it will attempt to resolve those requirements for you by downloading and installing the necessary code bundles.

2.1 Installing Composer

We're assuming that this is a local project, so let's install an instance of Composer just for the current project. Navigate to your project directory and run this:
  1. $ curl -sS https://getcomposer.org/installer | php
Keep in mind that piping any download directly to a script interpreter (sh, ruby, php, etc...) is a security risk, so do read the install code and ensure you're comfortable with it before running any command like this.

For convenience sake (if you prefer typing composer install over php composer.phar install, you can use this command to install a single copy of composer globally:
  1. $ mv composer.phar /usr/local/bin/composer
  2. $ chmod +x composer
You may need to run those with sudo depending on your file permissions.

2.2 Using Composer

Composer has two main categories of dependencies that it can manage: "require" and "require-dev". Dependencies listed as "require" are installed everywhere, but "require-dev" dependencies are only installed when specifically requested. Usually these are tools for when the code is under active development, such as PHP_CodeSniffer. The line below shows an example of how to install Guzzle, a popular HTTP library.
  1. $ php composer.phar require guzzle/guzzle
To install a tool just for development purposes, add the --dev flag:
  1. $ php composer.phar require --dev 'sebastian/phpcpd'
This installs PHP Copy-Paste Detector, another code quality tool as a development-only dependency.

2.3 Install vs update

When we first run composer install it will install any libraries and their dependencies we need, based on the composer.json file. When that is done, composer creates a lock file, predictably called composer.lock. This file contains a list of the dependencies composer found for us and their exact versions, with hashes. Then any future time we run composer install, it will look in the lock file and install those exact versions.

composer update is a bit of a different beast. It will ignore the composer.lock file (if present) and try to find the most up to date versions of each of the dependencies that still satisfies the constraints in composer.json. It then writes a new composer.lock file when it's finished.

2.4 Autoloading

Both composer install and composer update will generate an autoloader for us that tells PHP where to find all the necessary files to use the libraries we've just installed. To use it, just add this line (usually to a bootstrap file that gets executed on every request):
  1. require 'vendor/autoload.php';
3 Follow good design principles

3.1 SOLID

SOLID is a mnemonic to remind us of five key principles in good object-oriented software design.

3.1.1 S - Single Responsibility Principle

This states that classes should only have one responsibility, or put another way, they should only have a single reason to change. This fits nicely with the Unix philosophy of lots of small tools, doing one thing well. Classes that only do one thing are much easier to test and debug, and they are less likely to surprise you. You don't want a method call to a Validator class updating db records. Here's an example of an SRP violation, the likes of which you'd commonly see in an application based on the ActiveRecord pattern.
  1. class Person extends Model
  2. {
  3.     public $name;
  4.     public $birthDate;
  5.     protected $preferences;
  6.     public function getPreferences() {}
  7.     public function save() {}
  8. }
So this is a pretty basic entity model. One of these things doesn't belong here though. An entity model's only responsibility should be behavior related to the entity it's representing, it shouldn't be responsible for persisting itself.
  1. class Person extends Model
  2. {
  3.     public $name;
  4.     public $birthDate;
  5.     protected $preferences;
  6.     public function getPreferences() {}
  7. }
  8. class DataStore
  9. {
  10.     public function save(Model $model) {}
  11. }
This is better. The Person model is back to only doing one thing, and the save behavior has been moved to a persistence object instead. Note also that I only type hinted on Model, not Person. We'll come back to that when we get to the L and D parts of SOLID.

3.1.2 O - Open Closed Principle

There's an awesome test for this that pretty well sums up what this principle is about: think of a feature to implement, probably the most recent one you worked on or are working on. Can you implement that feature in your existing codebase SOLELY by adding new classes and not changing any existing classes in your system? Your configuration and wiring code gets a bit of a pass, but in most systems this is surprisingly difficult. You have to rely a lot on polymorphic dispatch and most codebases just aren't set up for that. If you're interested in that there's a good Google talk up on YouTube about polymorphism and writing code without Ifs that digs into it further. As a bonus, the talk is given by Miško Hevery, whom many may know as the creator of AngularJs.

3.1.3 L - Liskov Substitution Principle

This principle is named for Barbara Liskov, and is printed below:
"Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program."
That all sounds well and good, but it's more clearly illustrated with an example.
abstract class Shape
  1. {
  2.     public function getHeight();
  3.     public function setHeight($height);
  4.     public function getLength();
  5.     public function setLength($length);
  6. }
This is going to represent our basic four-sided shape. Nothing fancy here.
  1. class Square extends Shape
  2. {
  3.     protected $size;
  4.     public function getHeight() {
  5.         return $this->size;
  6.     }
  7.     public function setHeight($height) {
  8.         $this->size = $height;
  9.     }
  10.     public function getLength() {
  11.         return $this->size;
  12.     }
  13.     public function setLength($length) {
  14.         $this->size = $length;
  15.     }
  16. }
Here's our first shape, the Square. Pretty straightforward shape, right? You can assume that there's a constructor where we set the dimensions, but you see here from this implementation that the length and height are always going to be the same. Squares are just like that.
  1. class Rectangle extends Shape
  2. {
  3.     protected $height;
  4.     protected $length;
  5.     public function getHeight() {
  6.         return $this->height;
  7.     }
  8.     public function setHeight($height) {
  9.         $this->height = $height;
  10.     }
  11.     public function getLength() {
  12.         return $this->length;
  13.     }
  14.     public function setLength($length) {
  15.         $this->length = $length;
  16.     }
  17. }
So here we have a different shape. Still has the same method signatures, it's still a four sided shape, but what if we start trying to use them in place of one another? Now all of a sudden if we change the height of our Shape, we can no longer assume that the length of our shape will match. We've violated the contract that we had with the user when we gave them our Square shape.
This is a textbook example of a violation of the LSP and we need this type of a principle in place to make the best use of a type system. Even duck typing won't tell us if the underlying behavior is different, and since we can't know that without seeing it break, it's best to make sure that it isn't different in the first place.
Written by Brian Fenton

If you found this post interesting, follow and support us.
Suggest for you:

Learning PHP 7: From the Basics to Application Development

The Complete PHP 7 Guide for Web Developers

Up to Speed with PHP 7

Learn PHP 7 This Way to Rise Above & Beyond Competion!

The Complete PHP with MySQL Developer Course (New)

Friday, August 5, 2016

How to Start a Telegram Bot With PHP_part2 (end)

Create a Stopwatch Class

Finally we are ready to start coding. Let's create a class to work with the database in a file called stopwatch.php and start with a constructor that will set two private variables, where we will store the chat ID and the current MySQL connection:
  1. class Stopwatch
  2. {
  3.     /** @var mysqli */
  4.     private $mysqli;
  5.     /** @var int */
  6.     private $stopwatch_id;
  7.     /**
  8.      * Stopwatch constructor
  9.      * @param mysqli $mysqli
  10.      * @param $stopwatch_id
  11.      */
  12.     public function __construct(\mysqli $mysqli, $stopwatch_id)
  13.     {
  14.         $this->mysqli = $mysqli;
  15.         $this->stopwatch_id = intval($stopwatch_id);
  16.     }
  17. }
When the user starts the timer, we will get the current Unix time and save it in a row with the chat ID, so here is the start() method:
  1. public function start()
  2. {
  3.     $timestamp = time();
  4.     $query = "
  5.         INSERT INTO  `stopwatch` (`chat_id`, `timestamp`)
  6.         VALUES ('$this->stopwatch_id', '$timestamp')
  7.         ON DUPLICATE KEY UPDATE timestamp = '$timestamp'       
  8.     ";
  9.     return $this->mysqli->query($query);
  10. }
If the timer stops, we need to delete a row from the database:
  1. /**
  2.  * Delete row with stopwatch id
  3.  * @return bool|mysqli_result
  4.  */
  5. public function stop()
  6. {
  7. $query = "
  8.     DELETE FROM `stopwatch`
  9.     WHERE `chat_id` = $this->stopwatch_id
  10.     ";
  11.     return $this->mysqli->query($query);
  12. }
And now for the main part of the class. When the user requests the status of the timer, we need to find the row with the stopwatch from the current conversation and calculate the difference in seconds between the saved Unix time and the current time. Fortunately, Unix time is an integer, so we can just subtract one value from another. To format the resulting value as a time, we will use the gmdate  function.
  1. /**
  2.  * Find row with stopwatch id and return difference in seconds from saved Unix time and current time
  3.  * @return string
  4.  */
  5. public function status()
  6. {
  7.     $query = "
  8.         SELECT `timestamp` FROM  `stopwatch`
  9.         WHERE `chat_id` = $this->stopwatch_id        
  10.     ";
  11.     $timestamp = $this->mysqli->query($query)->fetch_row();
  12.     if (!empty($timestamp)) {
  13.         return gmdate("H:i:s", time() - reset($timestamp));
  14.     }
  15. }
As you can see, if there is no value in the database, the method status() will return nothing, and we will process a null value like a stopped timer.

Choosing a PHP Library

There are many PHP libraries that exist to work with the Telegram API, but, at least at the moment of writing this article, there's only one that supports both the Telegram Bot API wrapper and Botan tracking. And it's called PHP Telegram Bot API.

Use Composer to install this library:
  1. composer require telegram-bot/api
If you're not interested in using analytics, try Telegram Bot API PHP SDK with Lavarel integration or PHP Telegram Bot.

Start the Webhook Script
And now the main part begins—we will create a script to process callbacks from the Telegram Bot API. Start a file called index.php and include Composer autoload and a new Stopwatch class. Open a MySQL connection, create a new Telegram API client, and run it:
  1. require_once 'vendor/autoload.php';
  2. require_once 'stopwatch.php';
  3.  
  4. // connect to database
  5. $mysqli = new mysqli('database_host', 'database_user', 'database_password', 'database_name');
  6. if (!empty($mysqli->connect_errno)) {
  7.     throw new \Exception($mysqli->connect_error, $mysqli->connect_errno);
  8. }
  9.  
  10. // create a bot
  11. $bot = new \TelegramBot\Api\Client('bot_token', 'botanio_token');
  12. // run, bot, run!
  13. $bot->run();
Create Commands
Now we need to set up a bot to answer on command /start. This command is used to start all Telegram bots, and users will be shown our welcome message when the first chat begins.
  1. $bot->command('start', function ($message) use ($bot) {
  2.     $answer = 'Howdy! Welcome to the stopwatch. Use bot commands or keyboard to control your time.';
  3.     $bot->sendMessage($message->getChat()->getId(), $answer);
  4. });
Here, in the command() method, we defined a closure for receiving a command. This closure gets the ID of the current chat and sends a welcome message. Also, all registered commands are automatically tracked as the command name.

To start the stopwatch, we will define the /go command:
  1. $bot->command('go', function ($message) use ($bot, $mysqli) {
  2.     $stopwatch = new Stopwatch($mysqli, $message->getChat()->getId());
  3.     $stopwatch->start();
  4.     $bot->sendMessage($message->getChat()->getId(), 'Stopwatch started. Go!');
  5. });
This will create an instance of the Stopwatch class and start a timer calling the start() method that we have defined already.

To define the /status command, we need to do the same thing. Just call the status() method and return the result. If the method returned null, tell the user that the timer is not started.
  1. $bot->command('status', function ($message) use ($bot, $mysqli) {
  2.     $stopwatch = new Stopwatch($mysqli, $message->getChat()->getId());
  3.     $answer = $stopwatch->status();
  4.     if (empty($answer)) {
  5.         $answer = 'Timer is not started.';
  6.     }
  7.     $bot->sendMessage($message->getChat()->getId(), $answer);
  8. });
And if the user stops the timer, we need to get the status first, show the resulting time, and stop the timer using the stop() method.
  1. $bot->command('stop', function ($message) use ($bot, $mysqli) {
  2.     $stopwatch = new Stopwatch($mysqli, $message->getChat()->getId());
  3.     $answer = $stopwatch->status();
  4.     if (!empty($answer)) {
  5.         $answer = 'Your time is ' . $answer . PHP_EOL;
  6.     }
  7.     $stopwatch->stop();
  8.     $bot->sendMessage($message->getChat()->getId(), $answer . 'Stopwatch stopped. Enjoy your time!');
  9. });
That's it! Now you can upload all the files to the webhook directory and test your bot.

Adding a Keyboard
To suggest to the user which commands he or she can run, we can add a keyboard to a message. Our stopwatch can be running or stopped, and there will be two ones for each state. To show a keyboard to the user, we just need to extend the sendMessage() method:
  1. $keyboard = new \TelegramBot\Api\Types\ReplyKeyboardMarkup([['/go', '/status']], null, true);
  2. $bot->sendMessage($message->getChat()->getId(), $answer, false, null, null, $keyboards);
  3. });
Now you can add keyboards to every command of your bot. I will not include a full example here, but you can see it in the repository pages.

Adding Your Bot to a Store

Okay, so now we have working bot, and we want to show it to the world. The best way is to register the bot in a bot catalogue. For now, Telegram doesn't have an official catalogue like this, but there are a few unofficial ones, and the biggest is Storebot.me, where thousands of bots are already registered.

And there is a... bot to register your bot in a bot store! Add @storebot to your contact list, type the /add command, and follow the instructions. You will be asked to enter the bot's username, name, and description, choose one of the standard categories, and confirm the bot's ownership by sending its token.

After a while, your bot will pass the submission process and appear in the Storebot charts. Now you and your users can vote, find and rate your bot in the bot store to help it rise to the top of the chart.

Conclusion
We've come a long way, from creating a baby bot to registering it in a store to be available to real users. As you can see, there are many tools that exist to make your life easier with creating and spreading your bot, and you don't need much code to start an easy bot. Now you are ready to make your own!
Written by Anton Bagaiev

If you found this post interesting, please follow and support us.
Suggest for you:

Learning PHP 7: From the Basics to Application Development

The Complete PHP 7 Guide for Web Developers

Up to Speed with PHP 7

Learn PHP 7 This Way to Rise Above & Beyond Competion!

The Complete PHP with MySQL Developer Course (New)


Thursday, August 4, 2016

How to Start a Telegram Bot With PHP_part1

If you are reading this, you know that chat bots are one of the biggest tech trends of 2016.

The bot revolution is not only about artificial intelligence. A bot can be a tool in your messenger with a simple chat interface that can be used to extend the functionality of sites or services or can even be a standalone application. Bots are cheaper to develop and easier to install, and another great feature is that messengers can be used on every type of device—laptops, smartphones, and tablets. That's why everybody is crazy about bots now.

And the biggest messenger with an open bot API is Telegram.

What We Are Going to Do

In this article we will create a simple stopwatch Telegram bot. I will show you how to create your bot, connect with analytics, write some code, and finally add your bot to a bot store.

By the way, I've already prepared a demo, so you can test it just by adding @stopwatchbot to your Telegram contact list.

Create a Bot With BotFather

The first step to creating a bot is to register the account of your bot in Telegram. And there is a bot for that, called the BotFather. Just add it to your contact list and you'll be able to create and set up Telegram bots, just by typing the /newbot command and following the instructions of BotFather.


After registering your new bot, you will receive a congratulations message with an authorization token. We will use this token soon to authorize a bot and send requests to the Bot API.

Later you can use BotFather to add descriptions or photos to the profiles of your bots, regenerate tokens, set lists of commands to use, delete accounts, and so on. To get a full list of commands, just type /help in a chat to get a list of BotFather's commands.

Connect to Botan Analytics

There is no built-in analytics in the Telegram Bots API, but it's important to know how many users you have, how they act, and which commands they trigger more. Of course, we can collect this information using our own engine, but if we want to focus on bot functionality, not metrics, we just need to use an out-of-the-box solution.

And there is a simple tool to connect your bot to analytics, called Botan. It's based on Yandex AppMetric and completely free. Using Botan, you can segment your audience, get information about user profiles, get the most used command, and get beautiful graphs right in your messenger, like this:


To get started, you need to register your bot in Botan and get a token. And again, you can do it with a bot, BotanioBot:


Just click the “Add bot” key on the dialog keyboard, type the nick of your bot, and you will get your bot track token. Now Botanio is ready to track your bot events, and you can get statistics by users, sessions, retention and events right in your messenger.

Create and Register an SSL Webhook

In Telegram there are two ways to get messages from your users: long polling and webhooks.


Basically, with long polling, you need to request new messages from the API, and with webhooks you are setting a callback that the Telegram API will call if a new message arrives from a user. I prefer to use webhooks because it looks like real-time communication, so in this article we will use this method too. Now we need to choose a callback URL for our webhook, which needs to be reached under the HTTPS protocol, and we need to set it really secure, so hide your script in a secret path, as the manual says:
If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the URL, e.g. https://www.example.com/<token>. Since nobody else knows your bot‘s token, you can be pretty sure it’s us.
If your SSL certificate is trusted, all you need to do is open this URL in your browser:
  1. https://api.telegram.org:443/bot[token]/setwebhook?url=[webhook]
Otherwise you have to generate a self-signed certificate. Here is an example of the command on Linux for it:
  1. openssl req -newkey rsa:2048 -sha256 -nodes -keyout /path/to/certificate.key -x509 -days 365  -out /path/to/certificate.crt -subj "/C=IT/ST=state/L=location/O=description/CN=yourdomain.com"
And don't forget to open the SSL port:
  1. sudo ufw allow 443/tcp
To get the certificate checked and set your webhook domain to trusted, you need to upload your public key certificate:
  1. curl \
  2.   -F "url=https://yourdomain.com/path/to/script.php" \
  3.   -F "certificate=/path/to/certificate.key" \
  4.   "https://api.telegram.org/bot[token]/setwebhook"
Finally you will get a JSON reply like this:
  1. {"ok":true,"result":true,"description":"Webhook was set"}
It says that the webhook was set and we are ready to start the engine of the bot.

Build a Database

Now we need to build a database for our timers. What do we need to store in it? When a user commands the stopwatch to start, we will take the ID of the chat and save a row with the chat ID and current Unix time, which is the number of seconds between now and the start of Unix Epoch, which is 1 January 1970 at UTC. Consequently, we will save a row with the chat ID and integer timestamp of the current Unix time.

To show the current stopwatch time, we will get the saved timestamp and compare it with the current timestamp. The difference will be the current time in seconds. If the user stops the timer, we will simply delete the row with the current chat ID.

So let's create a database and table to store the stopwatch information:
  1. CREATE TABLE IF NOT EXISTS `stopwatch` (
  2.   `chat_id` int(10) unsigned NOT NULL,
  3.   `timestamp` int(10) unsigned NOT NULL,
  4.   PRIMARY KEY (`chat_id`)
  5. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Written by Anton Bagaiev (countinue)

If you found this post interesting, please follow and support us.
Suggest for you:

Learning PHP 7: From the Basics to Application Development

The Complete PHP 7 Guide for Web Developers

Up to Speed with PHP 7

Learn PHP 7 This Way to Rise Above & Beyond Competion!

The Complete PHP with MySQL Developer Course (New)