Crash early

A dead program normally does a lot less damage than a crippled one.

The Pragmatic Programmer, Tip #38, page 113

Have you ever thought about what can go wrong when the application’s logic is broken, but it continues to work? That might happen when the values are not the ones that you expect. For example, a method/function returns an integer, but a negative one, but you expect it to be positive. Another example is trying to access an unknown array key. The database returns an invalid value. You name it.

What if you won’t allow it and crash early? Yes, the client will see “an error occurred, our engineers are working on it”. The actual benefit is that the program will exit and not cause any harm. No corrupted data in the database nor missing files.

How to crash early in the PHP? There are two ways. Throwing a \LogicExpcetion or enabling assertions on production and using them.

Continue reading Crash early

Symfony & PSR-16 Simple Cache

This week I was working on the integration with the Optimizely Feature Toggles.

Its PHP SDK is mediocre.

It makes the HTTP request for the data file whenever the new PHP process is executed.

The data file is in our case larger than 2 MB, so it has to download a large file, but also validate it and parse it.

That makes around 700 ms overhead on each process.

Therefore I needed a cache mechanism.

But, as we try to write the software in a framework-agnostic way, I wanted to use the industry standard interface – the PSR-16 Simple Cache, to not be coupled to a specific cache implementation.

Continue reading Symfony & PSR-16 Simple Cache

Wpływ silence operatora na error reporting w PHP

Hej, w dzisiejszym krótkim wpisie bierzemy na tapet słynny i jakże często używany operator @ tzw. STFU. Czy wiesz że jego użycie ma wpływ na error_reporting w PHP? Weźmy pod lupę ten przykład:

<?php declare(strict_types=1);

error_reporting(E_ALL);

set_error_handler(
    function () {
        // int(0) [PHP <= 7.4]
        // int(4437) [PHP >= 8.0]
        var_dump(error_reporting());
    },
    E_ALL
);

// int(32767) [E_ALL]
var_dump(error_reporting());

@trigger_error('warning', E_USER_WARNING);
Continue reading Wpływ silence operatora na error reporting w PHP

PHP 7.3 – co nowego?

👋 Dzień dobry.

Nowa wersja PHP v7.3 jest już tuż tuż. 13 grudnia zostanie udostępniona wersja produkcyjna. Zmian jest naprawdę dużo co widać po spisie treści 🙂. Zmiany nie są rewolucyjne, większość z nich to są drobnostki, ale na pewno każdy znajdzie coś dla siebie 👍.

📝 Spis treści:

  1. 💡 Elastyczna składnia HEREDOC / NOWDOC
  2. 💡 Przecinek po ostatnim argumencie w wywołaniach funkcji / metod
  3. 💡 Wsparcie referencji w list()
  4. 💡 json_encode() i json_decode() – rzucanie wyjątków
  5. 💡 Nowa funkcja is_countable()
  6. 💡 Nowe funkcje array_key_first/last()
  7. 💡 Nowa funkcja do haszowania haseł – Argon2id
  8. 💡 Same site cookie
  9. 💡 hrtime() – monotoniczny timer
  10. 💡 Nowa metoda – DateTime::createFromImmutable()
  11. 💡 Nowa funkcja – fpm_get_status()
  12. 💡 Nowe funkcje w GMP
  13. 💡 CompileError – nowy typ błędu
  14. 💡 Aktualizacja PCRE do PCRE2
  15. 💡 MBString – wsparcie pełnego case-mapping i case-folding
  16. 🔧 compact() rzuci Notice gdy napotka niezdefiniowaną zmienną
  17. 🔧 instanceof – literał jako pierwszy operand – brak Fatal error
  18. 🔧 Przeprojektowane narzędzie ext_skel
  19. 🔧 Wyjątki nie wypełnią stanu error_get_last()
  20. 🔧 TypeError zgłosi błędne typy jako int oraz bool
  21. 🔧 Instrukcja continue rzuci Warning wewnątrz switch
  22. 🔧 ArrayAccess nie zrzutuje $offset typu string na int
  23. 🔧 Naprawiono referencje w statycznych własnościach klas
  24. 🔧 Naprawiono odpakowywanie argumentów z kluczami nie int
  25. 🔧 BCMath użyje obsługi błędów PHP
  26. ⚰️ Wsparcie dla BeOS porzucono
  27. ⚰️ Deprecated – image2wbmp()
  28. ⚰️ Deprecated – Stałe case-insensitive
  29. ⚰️ Deprecated – funkcje mb* bez dokumentacji
  30. ⚰️ Deprecated – funkcje szukania w string z argumentem nie string
  31. ⚰️ Deprecated – fgetss() oraz filter string.strip_tags
  32. ⚰️ Deprecated – definiowanie własnej funkcji assert()
  33. ⚰️ Deprecated – FILTER_FLAG_SCHEME_REQUIRED oraz FILTER_FLAG_HOST_REQUIRED
  34. ⚰️ Deprecated – pdo_odbc.db2_instance_name dyrektywa php.ini

Continue reading PHP 7.3 – co nowego?

Dependency Injection na prostym przykładzie w PHP

Cześć! Dzisiaj na tapecie wzór projektowy wstrzykiwanie zależności. Co znajdziesz w tym wpisie:

Continue reading Dependency Injection na prostym przykładzie w PHP

Kahlan – PHP test framework – dla wolności, prawdy i sprawiedliwości

TDD

Czyli coś co chyba każdy z nas robi – a przynajmniej powinien! Kto słyszał o PHPUnit? Albo o PHPSpec? A może Codeception? To dobre i sprawdzone narzędzia które mają jednak swoje minusy. Dzisiaj chcę wam zaprezentować całkiem świeże narzędzie – Kahlan.

Co to kurcze jest?

Jest to kolejny framework do pisania testów. Czym się różni od poprzednich? Na pewno składnią. Czy znacie RSpec albo jasmine? Tutaj mamy bardzo podobną implementację dla PHP, a więc używamy describe-it. Jest to cholernie wygodne i łatwe do zrozumienia. Chcecie przykład*?

Continue reading Kahlan – PHP test framework – dla wolności, prawdy i sprawiedliwości

PhpStorm Refactoring tutorial, part 3 – moving the class

Welcome in third part of my tutorial!

Today we are going to learn common thing while code refactor – class movement.

What I always did was to manually move the file in the Finder and then changed it’s namespace in the IDE. Finally I had to search whole project for class name etc. But PhpStorm can do all of that with one simple action.

I’m going to move the class \app\models\User to \common\models\User (Yii2 project).

Let me show you the beginning of my class:

<?php
namespace app\models;

use yii\base\Exception;
use yii\base\Model;
use yii\base\NotSupportedException;
use yii\web\IdentityInterface;

class User extends Model implements IdentityInterface
{

First thing what you need to do is to move the cursor into class name and open refactor menu (right click -> refactor, or press ctrl + t) and choose Move.

Fill the target namespace. I always check two checkboxes, Search in comments and string and Search for text occurrences. This will allows us to refactor the PHPDoccomments and other places where the class name exists.

Before pressing the Refactor button, I recommend to Preview the changes. All found places you will see on the list like this:

class move refactor

With second mouse button you can exclude results from refactoring. When you’re done, press Do Refactor. Now run your tests. Everything should work like as a charm!

Thank you for reading. Have a good day!

 

PhpStorm refactoring tutorial – part 2 – method extraction

Hello again.

This will be quick. Let’s take an example:

public function testAction($firstName, $lastName, $address)
{
    $data = ['firstName' => $firstName, 'lastName' => $lastName, 'address' => $address];
    $filteredData = [];
    foreach ($data as $key => $value) {
        $filteredData[$key] = str_replace('!@#$%^&*(', '', $value);
    }

    return $this->render('test', [
        'data' => $filteredData
    ]);
}

This method is doing too much. We want to extract new method which will filter the data and return the result. Please highlight the marek lines and press Refactor This button (ctrl + t). Choose Extract method. New window will appear. You can now customise your new method –  parameters order, visibility, PHPDoc and many many more. Im most cases you only need to add new method name and press enter – IDE fills all needed data for you. In this example I named new method filterData. Here’s the code after quick refactor:

public function testAction($firstName, $lastName, $address)
{
    $data = ['firstName' => $firstName, 'lastName' => $lastName, 'address' => $address];
    $filteredData = $this->filterData($data);

    return $this->render('test', [
        'data' => $filteredData
    ]);
}

/**
 * @param $data
 *
 * @return array
 */
private function filterData($data)
{
    $filteredData = [];
    foreach ($data as $key => $value) {
        $filteredData[$key] = str_replace('!@#$%^&*(', '', $value);
    }

    return $filteredData;
}

And that’s all :). Enjoy and tuned for next part. Cheers!