Christian WeiskeDependency injection: Because var_dump should be useless (9.12.2016, 16:44 UTC)

Do you remember the times when using var_dump() to inspect a variable did help? Not anymore! Thanks to frameworks and Dependency Injection those horrible times are over!

/var/www/vendor/dingo/api/src/Http/Response/Factory.php:156:
class Dingo\Api\Transformer\Binding#536 (5) {
  protected $container =>
  class Illuminate\Foundation\Application#3 (28) {
    protected $basePath =>
    string(8) "/var/www"
    protected $hasBeenBootstrapped =>
    bool(true)
    protected $booted =>
    bool(true)
    protected $bootingCallbacks =>
    array(4) {
      [0] =>
      class Closure#112 (1) {
        ...
      }
      [1] =>
      class Closure#204 (2) {
        ...
      }
      [2] =>
      class Closure#209 (2) {
        ...
      }
      [3] =>
      class Closure#226 (2) {
        ...
      }
    }
    protected $bootedCallbacks =>
    array(1) {
      [0] =>
      class Closure#240 (1) {
        ...
      }
    }
    protected $terminatingCallbacks =>
    array(0) {
    }
    protected $serviceProviders =>
    array(33) {
      [0] =>
      class Illuminate\Events\EventServiceProvider#2 (2) {
        ...
      }
      [1] =>
      class Illuminate\Routing\RoutingServiceProvider#7 (2) {
        ...
      }
      [2] =>
      class Illuminate\Auth\AuthServiceProvider#34 (2) {
        ...
      }
      [3] =>
      class Illuminate\Cookie\CookieServiceProvider#53 (2) {
        ...
      }
      [4] =>
      class Illuminate\Database\DatabaseServiceProvider#55 (2) {
        ...
      }
      [5] =>
      class Illuminate\Encryption\EncryptionServiceProvider#62 (2) {
        ...
      }
      [6] =>
      class Illuminate\Filesystem\FilesystemServiceProvider#64 (2) {
        ...
      }
      [7] =>
      class Illuminate\Foundation\Providers\FoundationServiceProvider#69 (2) {
        ...
      }
      [8] =>
      class Illuminate\Pagination\PaginationServiceProvider#70 (2) {
        ...
      }
      [9] =>
      class Illuminate\Session\SessionServiceProvider#74 (2) {
        ...
      }
      [10] =>
      class Illuminate\View\ViewServiceProvider#78 (2) {
        ...
      }
      [11] =>
      class Dingo\Api\Provider\RoutingServiceProvider#83 (3) {
        ...
      }
      [12] =>
      class Dingo\Api\Provider\HttpServiceProvider#87 (3) {
        ...
      }
      [13] =>
      class Dingo\Api\Provider\LaravelServiceProvider#82 (3) {
        ...
      }
      [14] =>
      class Immogic\Providers\CrateServiceProvider#107 (2) {
        ...
      }
      [15] =>
      class Chumper\Zipper\ZipperServiceProvider#109 (2) {
        ...
      }
      [16] =>
      class Torann\GeoIP\GeoIPServiceProvider#113 (2) {
        ...
      }
      [17] =>
      class Toin0u\Geocoder\GeocoderServiceProvider#119 (2) {
        ...
      }
      [18] =>
      class Jaybizzle\LaravelCrawlerDetect\LaravelCrawlerDetectServiceProvider#124 (2) {
        ...
      }
      [19] =>
      class Spatie\Activitylog\ActivitylogServiceProvider#127 (2) {
        ...
      }
      [20] =>
      class Immogic\Providers\ApiCacheServiceProvider#131 (2) {
        ...
      }
      [21] =>
      class Immogic\Providers\AppServiceProvider#132 (2) {
        ...
      }
      [22] =>
      class Immogic\Providers\AuthServiceProvider#133 (3) {
        ...
      }
      [23] =>
      class Immogic\Providers\BroadcastServiceProvider#134 (2) {
        ...
      }
      [24] =>
      class Immogic\Providers\EventServiceProvider#135 (4) {
        ...
      }
      [25] =>
      class Immogic\Providers\RouteServiceProvider#136 (3) {
        ...
      }
      [26] =>
      class Immogic\Providers\LocalDatabaseFilesystemAdapterServiceProvider#137 (2) {
        ...
      }
      [27] =>
      class Immogic\Providers\FtpUserServiceProvider#138 (2) {
        ...
      }
      [28] =>
      class Immogic\Providers\GeonamesServiceProvider#139 (2) {
        ...
      }
      [29] =>
      class Illuminate\Validation\ValidationServiceProvider#199 (2) {
        ...
      }
      [30] =>
      class Illuminate\Translation\TranslationServiceProvider#206 (2) {
        ...
      }
      [31] =>
      class Illuminate\Broadcasting\BroadcastServiceProvider#222 (2) {
        ...
      }
      [32] =>
      class Illuminate\Hashing\HashServiceProvider#514 (2) {
        ...
      }
    }
    protected $loadedProviders =>
    array(33) {
      'Illuminate\Events\EventServiceProvider' =>
      bool(true)
      'Illuminate\Routing\RoutingServiceProvider' =>
      bool(true)
      'Illuminate\Auth\AuthServiceProvider' =>
      bool(true)
      'Illuminate\Cookie\CookieServiceProvider' =>
      bool(true)
      'Illuminate\Database\DatabaseServiceProvider' =>
      bool(true)
      'Illuminate\Encryption\EncryptionServiceProvider' =>
      bool(true)
      'Illuminate\Filesystem\FilesystemServiceProvider' =>
      bool(true)
      'Illuminate\Foundation\Pr

Truncated by Planet PHP, read more at the original (another 29953 bytes)

Link
Christian WeiskeFrameworks: Because stack traces should be 60 lines long (9.12.2016, 16:38 UTC)
You don't call the framework, the framework calls you.

Other people can better explain why composing libraries is better than using a framework:

If you don't want to read much then I can still persuade you that working with (and thus debugging inside) a framework is no joy:

Call Stack:
 1. {main}()
 2. Illuminate\Foundation\Http\Kernel->handle()
 3. Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()
 4. Illuminate\Pipeline\Pipeline->then()
 5. Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}()
 6. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
 7. Dingo\Api\Http\Middleware\Request->handle()
 8. Dingo\Api\Http\Middleware\Request->sendRequestThroughRouter()
 9. Illuminate\Pipeline\Pipeline->then()
10. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
11. Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle()
12. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
13. Immogic\Http\Middleware\LogAfterRequest->handle()
14. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
15. Dingo\Api\Http\Middleware\Request->Dingo\Api\Http\Middleware\{closure}()
16. Dingo\Api\Routing\Router->dispatch()
17. Dingo\Api\Routing\Adapter\Laravel->dispatch()
18. Illuminate\Routing\Router->dispatch()
19. Illuminate\Routing\Router->dispatchToRoute()
20. Illuminate\Routing\Router->runRouteWithinStack()
21. Illuminate\Pipeline\Pipeline->then()
22. Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}()
23. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
24. Dingo\Api\Http\Middleware\PrepareController->handle()
25. Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}()
26. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
27. Immogic\Http\Middleware\Authenticate->handle()
28. Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}()
29. Illuminate\Routing\Router->Illuminate\Routing\{closure}()
30. Illuminate\Routing\Route->run()
31. Illuminate\Routing\Route->runController()
32. Illuminate\Routing\ControllerDispatcher->dispatch()
33. Illuminate\Routing\Controller->callAction()
34. call_user_func_array:{/var/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php:55}()
35. Immogic\Http\Controllers\Api\V1\BrokerController->index()
36. Dingo\Api\Http\Response\Factory->paginator()
37. Dingo\Api\Http\Response->__construct()
38. Symfony\Component\HttpFoundation\Response->__construct()
39. Dingo\Api\Http\Response->setContent()
40. Illuminate\Http\Response->setContent()
41. Illuminate\Http\Response->morphToJson()
42. Illuminate\Pagination\LengthAwarePaginator->toJson()
43. Illuminate\Pagination\LengthAwarePaginator->jsonSerialize()
44. Illuminate\Pagination\LengthAwarePaginator->toArray()
45. Illuminate\Support\Collection->toArray()
46. array_map()
47. Illuminate\Support\Collection->Illuminate\Support\{closure}()
48. Immogic\User->toArray()
49. Immogic\User->getFileSizeField()
50. Immogic\User->getFileUrl()
51. app()
52. Illuminate\Foundation\Application->make()
53. Illuminate\Container\Container->make()
54. Illuminate\Container\Container->build()
55. Dingo\Api\Provider\RoutingServiceProvider->Dingo\Api\Provider\{closure}()
56. Dingo\Api\Routing\Router->getRoutes()
57. Dingo\Api\Routing\Router->createRoute()
58. Dingo\Api\Routing\Route->__construct()
59. Dingo\Api\Routing\Route->setupRouteProperties()
60. Dingo\Api\Routing\Route->mergeControllerProperties()
61. Dingo\Api\Routing\Route->makeControllerInstance()
62. Illuminate\Foundation\Application->make()
63. Illuminate\Container\Container->make()
64. Illuminate\Container\Container->build()
65. ReflectionClass->newInstanceArgs()
66. Immogic\Http\Controllers\Api\ProducerDb\ProducersController->__construct()
67. Dingo\Api\Transformer\Factory->register()
68. xdebug_print_function_stack()

I've shortened the output for brevity. I'm sure you spotted the error.

Link
SitePoint PHPWhat’s New and Exciting in PHP 7.1? (8.12.2016, 17:00 UTC)

The PHP community has gone viral with the latest PHP 7 announcement and all the goodies it brings to the language. The PHP 7.1 release has more good news and features to offer. This article highlights the most important ones, and you should check PHP RFC for the full list.

Flying baloon-tied elephpant

ArgumentCountError Exception

Earlier versions of PHP allowed for function calls with fewer arguments than specified, emitting a warning when you have a missing argument.

// PHP 5.6

function sum($a, $b)
{
    return $a + $b;
}

sum();
// Warning: Missing argument 1 for sum()
// Warning: Missing argument 2 for sum()

sum(3);
// Warning: Missing argument 2 for sum()

sum(3, 4);

Warnings are not useful for this case, and the developer should check if all arguments are set correctly. In PHP 7.1, those warnings have been converted into an ArgumentCountError exception.

// PHP 7.1

function sum($a, $b)
{
    return $a + $b;
}

sum();
// Fatal error: Uncaught ArgumentCountError: Too few arguments to function sum(), 0 passed in /vagrant/index.php on line 18 and exactly 2 expected in /vagrant/index.php:13

sum(3); // skipped

sum(3, 4); // skipped

Nullable Types

PHP 7 added type declarations for parameters and return types, but it seemed that something was missing! Nullable types enable for the specified type to take either that type or null. Here's an example:

Continue reading %What’s New and Exciting in PHP 7.1?%

Link
Christian Weiskephinde, my self-hosted search engine (8.12.2016, 16:18 UTC)

I wrote a search engine to be able to search my blog, website and all linked pages. It's running at search.cweiske.de using PHP, Elasticsearch and Gearman.

When looking for a way to add search functionality to my blog, I found a few hosted search providers and some existing software but none that matched my taste. I had used regain before, but found too many problems.

So I had to do it all myself, again.

Features

My head already contained a list of must-have features:

Crawler

  • Crawl + index URLs like a "real" search engine (as opposed to knowing the Wordpress database structure and searching in that)
  • Support for multiple domains
  • Indexing of all URLs that are linked from my own pages
  • Author extraction (meta tags, microformats)
  • Image EXIF + PDF text parsing

Search interface

  • Must be fast
  • Rank matches in title higher than in headline, headline higher than text
  • Excerpt display with search term highlighting
  • Sort by relevance and date
  • Facets to drill down: File type, language, domain, tag/keyword
  • Time filter: Modification date before/after/at a given date

Implementation

I use PDO for SQL database access (subscriptions), Net_URL2 for URL parsing/resolving and HTTP_Request2 for doing HTTP requests. No frameworks, only libraries.

As of version 0.2.1, phinde consists of 1800 lines of PHP code and 400 lines of HTML/Twig.

Index storage

Because I wanted to rank headlines higher than normal text, MySQL full text search could not be used. From phorkie's development I knew that Elasticsearch supports field boosting and settled with that.

I made a schema that contained individual fields for title, each of the headline types (h1-h6), the text and tags/keywords. The fields each got a different boost that determines their priority in search result ranking.

My blog+website index contains 3.600 documents and takes 34 MiB (mostly "normal" HTML pages). The indieweb chat search instance indexes 900.000 documents, with a size of 550 MiB (tiny documents, each a single chat log line).

Elasticsearch works well except when there are schema changes, which often happens during development. I found it easier to throw away all data after making changes to the schema, because migrating a schema is too much work. This might be different when you have a couple of million documents in ES - but for me it's

Truncated by Planet PHP, read more at the original (another 6687 bytes)

Link
PHP: Hypertext PreprocessorPHP 5.6.29 Released (8.12.2016, 00:00 UTC)
The PHP development team announces the immediate availability of PHP 5.6.29. This is a security release. Several security bugs were fixed in this release. All PHP 5.6 users are encouraged to upgrade to this version.For source downloads of PHP 5.6.29 please visit our downloads page, Windows source and binaries can be found on windows.php.net/download/. The list of changes is recorded in the ChangeLog.
Link
Paul M. JonesPHP file_get_contents() HTTPS/SSL error on Mac OS (7.12.2016, 21:03 UTC)

Problem on Mac OS Sierra (10.12.x): Using file_get_contents() for an https resource fails with error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed.

This solution appears to be legit, although I am not primarily a security guy, so real security folks should chime in if they seem something untoward:

% sudo mkdir -p /usr/local/libressl/etc/ssl/certs
% sudo curl -o /usr/local/libressl/etc/ssl/cert.pem https://curl.haxx.se/ca/cacert.pem

This creates the default_cert_file directories and imports the latest certificate store from curl.haxx.se.

Source: PHP on macOS Sierra can’t access SSL data – andrewyager.com

Link
PHP ClassesPHP Performance Evolution 2016 from PHP 5, PHP 7.0, PHP 7.1 and PHP 8/Next (7.12.2016, 11:05 UTC)
By Christian Vigh
Since its creation in 1994 by Rasmus Lerdorf, the PHP language has gone through many improvements. Performance is one of the main criteria developers consider when they evaluate upgrading to a newer version.

Read this article to learn how performance improved across the latest PHP versions starting from PHP 5 up to the latest developments, including the recent version 7.1, as well as the experimental JIT branch that will be become part of PHP 8 or the next version.
Link
Paul M. JonesIndependent Packages and Subtree Splits (5.12.2016, 22:07 UTC)

You’ll sometimes see a PHP package hosted in a Github repository with the heading or subtitle “[READ ONLY] Subtree Split”. This indicates that the package is actually copied from another codebase (usually a framework) and is not intended to be worked on separately from that other codebase.

As such, a “subtree split” is not necessarily a sign of an independent package. Using a subtree split to publish a package says to me that the authors’ concentration is on the framework-as-a-whole, not on the package in-and-of- itself.

For example, Symfony does subtree splits for its components, as does Laravel for its Illuminate components. Those packages from the frameworks are not developed independently; they only move forward as part of the whole framework.

In these cases, you often end up with composer.json in the framework origin directories, which is not something I generally expect. Further, the framework subdirectories may have their own src/tests/docs/etc. directories. They are there so that the subtree split can have them available at their own top level, but in the origin framework, it is again something I find unexpected.

I say: if you’re going to advertise independent packages, actually write them independently. Let them be their own thing. Aura has done it that way since its beginning, and Zend Framework converted to that approach in version 3. Then you can compose the truly independent packages into a framework, instead of subtree-splitting your framework into pseudo-independent packages that are still bound to the origin framework development and release process.

Link
SitePoint PHPThe Delicious Evils of PHP (5.12.2016, 17:00 UTC)

I want to look at two PHP functions: eval and exec. They're so often thrown under the sensible-developers-never-use-these bus that I sometimes wonder how many awesome applications we miss out on.

Like every other function in the standard library, these have their uses. They can be abused. Their danger lies in the amount of flexibility and power they offer even the most novice of developers.

Let me show you some of the ways I've seen these used, and then we can talk about safety precautions and moderation.

Evil elephpant

Dynamic Class Creation

The first time I ever saw dynamic class creation was in the bowels of CodeIgniter. At the time, CodeIgniter was using it to create ORM classes. eval is still used to rewrite short open tags for systems that don't have the feature enabled...

More recently, though, my friend Adam Wathan tweeted about using it to dynamically create Laravel facades. Take a look at what the classes usually look like:

namespace Illuminate\Support\Facades;

class Artisan extends Facade
{
    protected static function getFacadeAccessor()
    {
        return "Illuminate\Contracts\Console\Kernel";
    }
}

This is from github.com/laravel/framework/blob/5.3/src/Illuminate/Support/Facades/Artisan.php

These facade classes aren't facades in the traditional sense, but they do act as static references to objects stored in Laravel's service locator class. They project an easy way to refer to objects defined and configured elsewhere, and have benefits over traditional static (or singleton) classes. One of these benefits is in testing:

public function testNotificationWasQueued()
{
    Artisan::shouldReceive("queue")
        ->once()
        ->with(
            "user:notify",
            Mockery::subset(["user" => 1])
        );

    $service = new App\Service\UserService();
    $service->notifyUser(1);
}

...and though these facades are simple to create, there are a lot of them. That's not the kind of code I find interesting to write. It seems Adam felt the same what when we wrote the tweet.

So, how could we create these facade classes dynamically? I haven't seen Adam's implementation code, but I'm guessing it looks something like:

function facade($name, $className) {
    if (class_exists($name)) {
        return;
    }

    eval("
        class $name extends Facade
        {
            protected static function getFacadeAccessor()
            {
                return $className::class;
            }
        }
    ");
}

That's a neat trick. Whether of not you use (or even like) Laravel facades, I'm guessing you can see the benefits of writing less code. Sure, this probably adds to the execution time of each request, but we'd have to profile performance to decide if it even matters much.

Continue reading %The Delicious Evils of PHP%

Link
Andrew EmblerBuilding Websites with concrete5 Express (3.12.2016, 01:32 UTC)

Express offers a data-first approach to concrete5 website development.
Link
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP