Wenn unter Windows formatierte oder gelöschte Daten wiederherstellen will kann man die Freeware Version von EaseUS Data Recovery Wizard kostenlos verwenden (auch für MAC). Damit kann man bis zu 2GB an Daten wiederherstellen, mit der Pro Version unbegrenzt viele Daten. Allerdings gehen bei eine Formatierung generell die Ordnernamen unwiederruflich verloren, aber die Daten bleiben erhalten.
Autor: Sebastian Viereck
Mit PHP kann man über UDP auf dem eigenen Rechner sehr einfach Packete verschicken. Um dies zu testen, braucht man einen Sender und einen Empfänger. In dem Biepsiel kommunizieren beider über die lokale IP auf Port 20010. Die Beispiele müssen auf der Konsole ausgeführt werden.
Sender:
<?php $address = '127.0.0.1'; $port = 20010; $beat_period = 1; $fp = stream_socket_client("udp://$address:$port", $errno, $errstr); if (!$fp) { die("ERROR: $errno - $errstr"); } while (true) { $message = sprintf( '%s send: %s'. PHP_EOL, date('c'), rand(0, 1000000) ); fwrite($fp, $message); echo $message; sleep($beat_period); }
Empfänger:
<?php $address = '127.0.0.1'; $port = 20010; $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1); socket_bind($socket, $address, $port); if ($socket === false) { throw new \RuntimeException( sprintf( 'could not connect to socket address %s on port %s. Error: %s %s', $address, $port, socket_last_error(), socket_strerror(socket_last_error()) ) ); } while (true){ echo socket_read ($socket, 1024); }
Man kann in PHP sehr schwer parallel Operationen ausführen, aber für das lesen von mehreren Sockets gibt es die socket_select() Funktion. Damit lassen sich mehrere Socket Verbindungen parallel auslesen.
In dem Beispiel werden 2 UDP Socket Verbindungen erstellt und gleichzeitig ausgelesen:
function createSocket(string $ip, int $port) { $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); //set non blocking read socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1); socket_bind($socket, $ip, $port); if ($socket === false) { throw new \RuntimeException( sprintf( 'could not connect to socket address %s on port %s. Error: %s %s', $ip, $port, socket_last_error(), socket_strerror(socket_last_error()) ) ); } return $socket; }
function readSockets() { $waitTimeoutSeconds = 1; $socket1 = $this->createSocket('127.0.0.1', 20001); $socket2 = $this->createSocket('127.0.0.1', 20002); $sockets['socket1'] = $socket1; $sockets['socket2'] = $socket2; $read = $sockets; $write = null; $except = null; if (socket_select($read, $write , $except, $waitTimeoutSeconds)) { // loop through the sockets that showed activity if (isset($read['socket1'])) { // socket 1 got a message $content1 = socket_read ($socket1, 1024); } if (isset($read['socket2'])) { // socket 2 got a message $content2 = socket_read ($socket2, 1024); } } else { throw new \RuntimeException('could not read any socket'); } socket_close($socket1); socket_close($socket2); }
Bei Windows kommt die nervige Fehlermeldung:
Die Aktion kann nicht abgeschlossen werden, da der Ordner in einem anderen
Programm geöffnet ist. Schließen Sie den Ordner und wiederholen Sie den
Vorgang.
Auch in dem Fall, wenn man in der Konsole (cmd) in dem Ordner ist, man muss einfach aus dem Ordner rausgehen mit cd .. oder die Konsole schließen, dann kann man löschen.
Um mit PHP große XML Dateien auswerten zu können, muss man einen SAX Parser verwenden, der die XML Dateien von oben nach unten durchliest und nicht in ein Objekt umwandelt. Dafür ist der XMLReader von PHP vorgesehen.
Ein Beispiel:
$data = new Data(); $reader = new \XMLReader(); $reader->open($file); while ($reader->read()) { if ($reader->nodeType == \XMLReader::ELEMENT) { switch ($reader->name) { case "tagName1" : $node = new \SimpleXMLElement($reader->readOuterXML()); $attributes = $node->attributes(); $entity = new Entity(); $entity->setId($attributes['id']); $entity->setName($attributes['name']); $entity->setCode($attributes['code']); $data->addEntity($entity); break; case "tagName2": $node = new \SimpleXMLElement($reader->readOuterXML()); $attributes = $node->attributes(); $entity = new OtherEntity(); $entity->setId($attributes['id']); $entity->setName($attributes['name']); $entity->setCode($attributes['code']); $data->addOtherEntity($entity); break; } } }
Um beim IIS 7.5 alle HTTP Verben wie PUT, POST, DELETE und PATCH zu aktivieren, muss man in der web.config folgende Module und Handler deaktivieren:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <modules> <remove name="WebDAVModule" /> </modules> <handlers> <remove name="WebDAV" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> </handlers> </system.webServer> </configuration>
Um unter IIS ein Zertifikat für IIS zu erstellen, muss man selber ein SSL Zertifikat erstellen mit openssl (wird bei GIT mitgeliefert in C:\Program Files\Git\usr\bin).
Mit den beiden Befehlen kann man sich eine .pfx Datei erzeugen, die auch unter Chrome 60 läuft mit er Option chrome://flags/#allow-insecure-localhost.
openssl req -newkey rsa:2048 -x509 -nodes -keyout server.key -new -out server.crt -subj /CN=localhost -reqexts SAN -extensions SAN -config openssl.cnf -sha256 -days 36500
openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt
Man benötigt eine Konfigurations-Datei openssl.cnf:
Wenn man im Template eine Doctrine Collection sortieren will nach einem Zeitstempel (createdAt in dem Beispiel), sollte man dies eigentlich vorher machen.
Wenn dies nicht möglich ist, z.B. im Sonata Admin Bundle, dann kann man diese Twig Extension verwenden:
{% foo| sortByCreatedAt('asc') %}
Twig Extension Code:
<?php namespace App\Twig; use App\Entity\Tag; use Doctrine\ORM\PersistentCollection; use Twig\Extension\AbstractExtension; use Twig\TwigFilter; class AppExtension extends AbstractExtension { public function getFilters() { return array( new TwigFilter('sortByCreatedAt', array($this, 'sortByCreatedAt')), ); } /** * @param PersistentCollection $objects * @return mixed */ public function sortByCreatedAt($objects, $direction = 'asc') { $objects = $objects->toArray(); usort($objects, function ($a, $b) use($direction) { if ($direction === 'asc') { return $a->getCreatedAt() > $b->getCreatedAt(); } elseif ($direction === 'desc') { return $a->getCreatedAt() < $b->getCreatedAt(); } else { throw new \Exception('unknown sort direction'); } }); return $objects; } }
Bei einem Fehlgeschlagenen Request kann man sehr komfortabel nochmals anfragen mit der Methode retry():
import 'rxjs/add/operator/retry'; ... const result = this.http.get(url) .retry(2);
Die neue Javascript Methode console.table() ist sehr hilfgreich, um Objekte und Arrays auf der Konsole darzustellen.
Beispiel:
var data = [ {"id": "Open"}, {"id": "OpenNew", "label": "Open New"}, null, {"id": "ZoomIn", "label": "Zoom In"}, {"id": "ZoomOut", "label": "Zoom Out"}, {"id": "OriginalView", "label": "Original View"}, null, {"id": "Quality"}, {"id": "Pause"}, {"id": "Mute"}, null, {"id": "Find", "label": "Find..."}, {"id": "FindAgain", "label": "Find Again"}, {"id": "Copy"}, {"id": "CopyAgain", "label": "Copy Again"}, {"id": "CopySVG", "label": "Copy SVG"}, {"id": "ViewSVG", "label": "View SVG"}, {"id": "ViewSource", "label": "View Source"}, {"id": "SaveAs", "label": "Save As"}, null, {"id": "Help"}, {"id": "About", "label": "About Adobe CVG Viewer..."} ]; console.table(data);
Erzeugt im Chrome die folgende Ausgabe in den Developer Tools: