Symfony 5 Exception “The annotation was never imported.”

Ein Grund der Fehlermeldung kann sein, dass es tatsächlich eine Annotation ist, die ungültig ist, sich aber im vendor Code befindet. Dann sollte man diese ignorieren.

Fehlermeldung:

Doctrine\Common\Annotations\AnnotationException : [Semantical Error] The annotation "@suppress" in method Monolog\Formatter\LineFormatter::normalizeException() was never imported. Did you maybe forget to add a "use" statement for this annotation?

Sollte man die Annotation ignorieren mit dem statischen Aufruf von in der config/bootstrap.php:

AnnotationReader::addGlobalIgnoredName('suppress');

 

PHP eigene Metriken in AWS Cloudwatch erstellen

Um in CloudWatch eigene Metriken anzulegen, um z.B. Alarm auszulösen und Monitoring zu betreiben mit den Daten der Applikation, kann man mit dem aws-php-sdk den folgenden Code verwenden:

 $client = new CloudWatchClient([
        'region' => 'eu-central-1',
        'version' => '2010-08-01',
        'credentials' => [
            'key'    => 'xxx',
            'secret' => 'xxx
        ],
    ]);
}
$result = $this->client->putMetricData(array(

    'Namespace' => 'MyProject',
    'MetricData' => array(
        array(
            'MetricName' => 'MyMetric,
            'Timestamp' => time(),
            'Value' => 1,
            'Unit' => 'Count',
            'Dimensions' => array(
                array(
                    'Name' => 'Environment',
                    'Value' => 'test',
                ),
            ),
        )
    )
));

DockerFile PHP mit XDebug und Amazon Linux 2

Ein DockerFile für eine PHP 7.2. Umgebung mit XDebug für eine Symfony 4 Umgebung unter Amazon Linux 2:

FROM amazonlinux:2.0.20190823.1

RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

# install php
RUN amazon-linux-extras install -y php7.2
RUN yum install -y php-devel.x86_64 php-xml.x86_64 php-pecl-zip.x86_64  php-intl.x86_64

#install xdebug
RUN yum install -y gcc make
RUN yum install -y php-pear.noarch
RUN pecl install xdebug
RUN echo 'zend_extension=/usr/lib64/php/modules/xdebug.so' >> /etc/php.ini

PHP csv Datei mit Umlauten erstellen für Excel

Um eine csv-Datei zu erstellen, in der die Umlaute richtig kodiert sind, muss man in seinem Projekt, welches im Normalfall UTF-8 kodiert ist, die Umlaute nach UTF-16LE kodieren. Diese Kodierung kann von Windows und Mac angezeigt werden.

$file = fopen('file.csv', 'w');
foreach ($rows as $row) {
 $row = array_map(function($cell){
 return mb_convert_encoding($cell, 'UTF-16LE', 'UTF-8');
 }, $row);
 fputcsv($file, $row, ';');
}
fclose($file);

Monolog Logging für AWS Cloudwatch Logs konfigurieren

Damit die Logs schön formatiert aus einer Symfony 4 Anwendung in AWS Cloudwatch ankommen, muss man Monolog folgendermaßen konfigurieren:

# config/services.yaml
Monolog\Formatter\JsonFormatter:
    calls:
        - [includeStacktraces]

und

# config/packages/prod/monolog.yaml
monolog:
  handlers:
    main:
      type:  stream
      level: error
      path:  '%kernel.logs_dir%/error.log'
      formatter: Monolog\Formatter\JsonFormatter

Danach muss man der Cloudwatch Daemon konfigurieren:

# /etc/awslogs/awslogs.conf
[general]
# Path to the CloudWatch Logs agent's state file. The agent uses this file to maintain
# client side state across its executions.
state_file = /var/lib/awslogs/agent-state

[/var/www/html/var/log/error.prod.log]
datetime_format = [%Y-%m-%d H:%M:%S]
file = /var/www/html/var/log/error.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = test_group_name/error_log

und man erhält wunderbare (aggregierte) ErrorLog Informationen in Cloudwatch Logs Insight:

 

 

Symfony Switftmailer Mail wird nicht gesendet

Mit dem folgende Befehl kann eine Testmail versendet werden mit Swiftmailer. Falls die Email nicht ankommt, sind die Switftmailer Parameter in config/packages/swiftmailer.yaml wahrscheinlich falsch:

php bin/console swiftmailer:email:send --help

Da die Email mit eine Queue versendet werden, sollte trotzdem in das error_log untersucht werden unter var/log/, darin fand sich bei mir der Grund für mein Versand Problem:

app.ERROR: Exception occurred while flushing email queue: Expected response code 250 but got code "554", with message "554 Message rejected: 
Email address is not verified. The following identities failed the check in region EU-WEST-1: email1, email2

 

Tutorial: Symfony Administrations-Backend erstellen

In diesem Beitrag werde ich mit Symfony 4 eine Administartionsoberfläche mit Hilfe von Sonata erstellen und die einzelnen Schritte beschreiben.

1. Anlegen eines neuen Symfony Projektes

Mit composer kann man schnell ein neues Symfony Skeleton Projekt anlegen lassen:

composer create-project symfony/website-skeleton my-admin-demo

Das Skeleton Projekt enthält die wichtigsten Symfony Komponenten für eine Webapplikation sowie Doctrine.

Jetzt ist ein guter Zeitpunkt das Porjket in ein Versionierungsystem wie GIT einzuchecken und zum ersten mal zu committen.

Optional kann jetzt Symfony PHPUnit Bridge installiert werden, wenn Tests geschrieben werden sollen:

composer require phpunit --dev

Die Datenbank kann jetzt konfiguriert werden in der .env Datei:

DATABASE_URL=mysql://db_user:%MINIFYHTML2b78d582bac9e7e9512688d9af84e68a6%:3306/db_name

Und mit folgendem Befehl angelegt werden:

php bin/console doctrine:database:create

2. Installation des SonataAdmin Bundles weiterlesen…

Gaufrette FTP Adapter rekursiv Verzeichnisse löschen

Um mit dem FTP Adapter von Gaufrette rekursiv Dateien und Unterverzeichnisse zu löschen kann man folgenden Trick anwenden um nicht in die Fehlermeldung zu geraten:

ftp_rmdir(): Directory not empty.

1. erst alle Dateien löschen

2. dann die tiefsten Verzeichnisse bis hin zu den obersten löschen:

/**
 * @param Filesystem $fileSystem
 */
function deleteAllFilesInDirectory(Filesystem $fileSystem)
{
    // delete files first, than directories
    foreach ($fileSystem->keys() as $key) {
        if (!$fileSystem->isDirectory($key)) {
            $fileSystem->delete($key);
        }
    }
    $keys = $fileSystem->keys();
    usort($keys, function (string $a, string $b){
        $aCount = substr_count($a, '/');
        $bCount = substr_count($b, '/');
        return $bCount <=> $aCount;
    });
    foreach ($keys as $key) {
        $fileSystem->delete($key);
    }
}