Schön, dass Sie Ihren Weg hierher gefunden haben.

Auf diesen Seiten schreibe ich hin und wieder Dinge, mit denen ich während meiner Arbeit in Berührung gekommen bin und von denen ich denke, dass sie für andere interessant sein könnten.

Enjoy!

MySQLDu in neuer Version 1.1

Meine kleine MySQL-Backup-Lösung MySQLDu gibt es in der neuen Version 1.1.

Neben zwei kleinen Änderungen ist die neu hinzugefügte FTP-Unterstützung interessant. Backups können jetzt automatisch auf einen FTP-Server hochgeladen werden.

MySQLDu 1.1 herunterladen

Geschrieben von Philip am 16.08.2010 | Kommentare weiterlesen...

Automatisches MySQL-Backup per Mail

Wem seine Daten lieb sind, der sichert sie häufig. Ob Wöchentlich, täglich oder stündlich hängt dabei von der Änderungsrate ebendieser ab, völlig unabhängig davon ist aber, dass die manuelle Erstellung von Backups kostbare Zeit kostet, die anderweitig besser investiert wäre.

Bei Internetprojekten ist die frei verfügbare MySQL-Datenbank mittlerweile ein Standard, administriert wird sie meistens mit phpMyAdmin, einem ebenso kostenlosem Web-Interface. Wer MySQL-Datenbanken normalerweise sichert, der erstellt in phpMyAdmin ein Datenbank-Dump und lässt es sich wahlweise als Textdatei oder in einem Archiv verpackt liefern. Doch aufgrund der nötigen Autorisierung am Server dauert die Erstellung schon einige Zeit, wieso da nicht einfacher? Mit einem automatischen Backup zum Beispiel.

Mithilfe eines Cronjobs, dem Tipp, wie man mit wget ein PHP-Script aufruft und MySQLDu lässt sich einfach eine Backup-Lösung erstellen. Wie das geht wird im Folgenden erklärt.

Laden wir zunächst die aktuelle Version von MySQLDu (1.0) herunter und entpacken das Archiv auf den Webserver, auf dem auch die MySQL-Datenbank liegt.

Als nächstes löschen wir die Dateien testoutput.php, testmail.php, testfile.php, msdu.sql und das Unterverzeichnis dump/, da diese entweder zu Testzwecken dienen oder für die Sicherung per Mail nicht erforderlich sind.

Ganz wichtig ist, dass das Unterverzeichnis tmp/ durch den Webserver-Benutzer schreibbar ist (am Besten setzen Sie die Rechte auf 0777).

Jetzt erstellen wir eine neue Datei cronbackup.php mit folgendem Inhalt:

<?php
	define("MYSQLDU_MODE","mail"); // legt den Mail-Modus fest

	// Datenbankzugangsdaten
	define("MYSQLDU_DB","");
	define("MYSQLDU_USER","");
	define("MYSQLDU_PASSWORD","");
	define("MYSQLDU_HOST","localhost");	

	// Mail-Optionen
	define("MYSQLDU_MAIL_FROM","noreply@philip-ehret.de");
	define("MYSQLDU_MAIL_FROMNAME","MySQLDu V!version");
	define("MYSQLDU_MAIL_TITLE","MySQL dump of !database on !d.!m.!Y (!H:!i:!s)");
	define("MYSQLDU_MAIL_TEXT","Hi there, this mail contains your dump of database !database created by MySQLDu V!version on !d.!m.!Y (!H:!i:!s).\n".
		"See attached file!\n\n".
		"Thanks for using MySQLDu (http://philip-ehret.de/projekte/mysqldu/)\n".
		"See also mysqldump.php from Huang Kai (http://atutility.com/software/mysqldumpphp/) on which MySQLDu is based on\n".
		"This mail was automatically generated and sent by PHPMailer(http://phpmailer.worxware.com/)");
	define("MYSQLDU_MAIL_SENDTO","mail@philip-ehret.de");
	define("MYSQLDU_MAIL_ATTACHMENT_NAME","!server.!database.!date.dump.sql");

	require_once("mysqldu-1.0.php");
?>

Wichtig ist, dass Sie die Konstanten MYSQLDU_USER, MYSQLDU_HOST, MYSQLDU_PASSWORD, MYSQLDU_DB an die Zugangsdaten Ihrer MySQL-Datenbank anpassen und MYSQLDU_MAIL_FROM und MYSQLDU_MAIL_SENDTO passend setzen (Das erste ist die E-Mail-Adresse, die später als Absender der Backup-Mail erscheint, das zweite die E-Mail-Adresse, an die das Backup gesandt werden soll).

Die Konstanten MYSQLDU_MAIL_TITLE und MYSQLDU_MAIL_TEXT können Sie nach belieben anpassen, mögliche Platzhalter finden Sie in der mysqldu-1.0.php in der Variablen $MYSQLDU_REPLACE_ARRAY.

Rufen Sie das Script jetzt einmal mit Ihrem Browser auf. Die Ausgabe sollte bei Erfolg die folgende sein. Eventuell öffnet Ihr Browser auch einen Download-Dialog, die heruntergeladene Datei enthält dann die Ausgabe.

{"status":"success","text":"Mail was successfully delivered"}

Es handelt sich hierbei um eine JSON-codierte Ausgabe. Das ist deswegen so, damit andere Scripte, die das Backup-Script aufrufen könnten, die Rückmeldungen einfach verarbeiten können.

Sollten Sie eine andere Ausgabe erhalten, so sehen Sie sich den JSON-codierten Fehlertext an. Dieser gibt Rückschlüsse darauf, was falsch läuft. Überprüfen Sie die Schreibrechte für das Unterverzeichnis tmp/ und stellen Sie sicher, dass Sie die Datenbankzugangsdaten korrekt eingegeben haben.

Wenn die Ausgabe stimmt, gehen Sie in das E-Mail-Postfach der für MYSQLDU_MAIL_SENDTO angegebenen E-Mail-Adresse. Dort sollte bereits eine E-Mail auf Sie warten, welche die Datenbanksicherung als Anhang enthält.

Um das E-Mail-Backup jetzt auch noch vollautomatisch zu erhalten, führen Sie sich den Artikel zur Ausführung eines PHP-Scriptes mithilfe eines Cronjobs zu Gemüte, welcher nicht nur für Plesk seine Gültigkeit hat.

Meine persönlichen Datenbanken sind zum Großteil in Unicode, da das etliche Vorteile bietet, welche den gegenüber anderen Datencodierungen höheren Speicherverbrauch meiner Meinung nach durchaus rechtfertigen.
Sollten Sie eine andere Codierung haben und die Dump-Datei fehlerhaft sein, versuchen Sie das Problem zu beheben, indem Sie an den Anfang der cronbackup.php folgenden Code einfügen:

define("MYSQLDU_UTF8",0);
Geschrieben von Philip am 13.08.2010 | Kommentare weiterlesen...

Mit Plesk einen PHP Cronjob einrichten

Wer mit Plesk einen Cronjob einrichten möchte, der ein PHP-Script aufruft, kann das ohne umständliche Aufrufe mit dem Befehl wget machen, welcher normalerweise ein Dokument von einer URL lädt und abspeichert. Der Trick hierfür ist die Verwendung der Option spider, welche die Abspeicherung unterdrückt:

wget http://anydomain.tld/script.php?action=dosomething --spider
Geschrieben von Philip am 13.08.2010 | Kommentare weiterlesen...

Smarty Rekursion in einem Template

Es kommt öfters vor, dass man ein Array ausgeben möchte, ohne die Tiefe zu kennen. Baumstrukturen oder Verzeichnislistings sind Beispiele dafür. Mit PHP und anderen Skriptsprachen lässt sich eine solche Struktur leicht mithilfe von Rekursion ausgeben.

Ich persönlich benutze seit geraumer Zeit die Smarty Template Engine, welche die Möglichkeit der Rekursion in Templates leider bisher vermissen lässt.
Wer jedoch zwischen den Zeilen liest, findet im Smarty-Forum eine Lösung, diese Funktionalität trotzdem implementieren zu können.

1) Aktuelle Version des Plugins compiler.defun herunterladen (Kompatibel mit PHP4+)

2) Die heruntergeladene Datei compiler.defun.php in das Plugins-Verzeichnis von Smarty kopieren (smarty/libs/plugins/)

3) Folgende Template-Datei als test.tpl in das Smarty-Template-Verzeichnis (normalerweise templates/) erstellen, welche ein verschachteltes Array ausgeben soll:

<ul>
{defun name="testrecursion" list=$tree}
{foreach from=$list item=node}
<li><span>{$node.caption} ({$node.access_string})</span>{if $node.children}<ul>
	{fun name="testrecursion" list=$node.children}</ul>{/if}</li>
{/foreach}
{/defun}
</ul>

4) Zuletzt mit folgendem Quellcode eine Datei test.php erzeugen, welche Smarty instanziert und ein verschachteltes Array zuweißt:

<?php
	require_once 'smarty/libs/Smarty.class.php';
	$smarty = new smarty();
	$smarty->assign("tree",array(
		0=>array(
			"caption"=>"Hallo",
			"access_string"=>"hallo.html",
			"children"=>array()
		),
		1=>array(
			"caption"=>"Huhu",
			"access_string"=>"huhu.html",
			"children"=>array(
				0=>array(
					"caption"=>"Wuhu",
					"access_string"=>"huhu/wuhu.html",
					"children"=>array()
				),
				1=>array(
					"caption"=>"Bla",
					"access_string"=>"huhu/bla.html",
					"children"=>array(
						0=>array(
							"caption"=>"Waha",
							"access_string"=>"huhu/bla/waha.html",
							"children"=>array(
								0=>array(
									"caption"=>"Ariba",
									"access_string"=>"huhu/bla/waha/ariba.html",
									"children"=>array(
										0=>array(
											"caption"=>"Wabadu",
											"access_string"=>"huhu/bla/waha/ariba/wabadu.html",
											"children"=>array()
										),
										1=>array(
											"caption"=>"Wabadi",
											"access_string"=>"huhu/bla/waha/ariba/wabadi.html",
											"children"=>array(
												0=>array(
													"caption"=>"Hallo",
													"access_string"=>"huhu/bla/waha/ariba/wabadi/hallo.html",
													"children"=>array()
												)
											)
										)
									)
								)
							)
						)
					)
				),
				2=>array(
					"caption"=>"Wau",
					"access_string"=>"huhu/wau.html",
					"children"=>array()
				)
			)
		),
		2=>array(
			"caption"=>"Maeh",
			"access_string"=>"maeh.html",
			"children"=>array(
				0=>array(
					"caption"=>"Muh",
					"access_string"=>"maeh/muh.html",
					"children"=>array()
				)
			)
		)
	));
	$smarty->display("test.tpl");
?>

Die Ausgabe von test.php sieht dann wie folgt aus:
Ausgabe test.php

Geschrieben von Philip am 10.08.2010 | Kommentare weiterlesen...

MySQL UPDATE unter Einbeziehung des aktuellen Feldwertes

Da in einer meiner Projektdatenbanken für Bilder relative Pfade verwendet werden und ich die lokale Version des Projekts in einem Verzeichnis pflege, dessen Name nicht dem der Online-Version entspricht, war es notwendig, alle Pfade in der lokalen Projektdatenbank anzupassen.

Während der Projektpfad online

/projectx/

lautete, hieß er lokal

/domainx/projectx/

Das Anpassungsscript sollte also den aktuellen Feldwert nehmen und davor ein /domainx einfügen.
Leider funktioniert das nicht ähnlich simpel wie mit Zahlen, bei denen der aktuelle Feldwert einfach mit einem mathematischen Operator wie z.B. einem + mit einer Zahl verknüpft werden kann, wie etwa hier:

UPDATE `tablex` SET `fieldx` = `fieldx` + 5

Es muss vielmehr auf die MySQL-Funktion CONCAT zurückgegriffen werden, welche alle Argumente zu einem String verknüpft.
Das sah in meinem Fall dann so aus:

UPDATE `tablex` SET `fieldx` = CONCAT('/domainx', `fieldx`)

Wichtig ist, dass die Argumente für CONCAT richtig angegeben werden: Auf Feldwerte wird mit dem Feldnamen bzw. dem durch gequoteten Feldnamen Bezug genommen, direkte Stringeingaben erfolgen durch einfache Hochkommas.

Geschrieben von Philip am 08.03.2010 | Kommentare weiterlesen...

Tastenkombination / Tastaturkombination / Keyboard Shortcut abfangen und benutzerdefinierte Aktion ermöglichen

Vielleicht möchte man irgendwann einmal Tastenkombinationen / Shortcuts des Benutzers selbst verwerten und die Standardaktion des Browsers verhindern. Zum Beispiel wenn der Benutzer ein Dokument bearbeiten können soll: Beim Drücken der Tastenkombination STRG + S soll dieses direkt gespeichert und nicht der Speichern-Dialog des Browsers (Im Firefox sieht der so aus) geöffnet werden.

Ganz easy geht das mit jQuery und dem Javascript jQuery Hotkeys Plugin

(Für kompletten Code bitte die DEMO ansehen: http://files.philip-ehret.de/dev/examples/jquery/hotkeys_bind.php)

<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jquery.hotkeys-0.7.9.min.js"></script>

Nach Einbinden der jQuery-Bibilothek und des Plugins fehlt nur noch wenig:

jQuery(document).ready(function($){
	$(this).bind('keydown', 'ctrl+s', function(e){
		e.preventDefault(); // Standardaktion verhindern
		$('#someform').submit();
	});
});

Eigentlich würde man jetzt wahrscheinlich noch erläuternde Worte erwarten, aber die gibt’s diesmal nicht, bei der Einfachheit sollte der Code des Beispiels selbsterklärend sein.

Geschrieben von Philip am 27.11.2009 | Kommentare weiterlesen...

Tabs in einer Textarea ermöglichen oder Howto: Zeichen an aktueller Cursorposition in eine Textarea einfügen

Vielleicht kommt man irgendwann zu einem Punkt, an dem man gerne in einem Textfeld die Möglichkeit hätte, an der aktuellen Cursorposition ein oder mehrere Zeichen einzufügen.
Ein konkretes Beispiel wäre, dass beim Betätigen der Tab-Taste in einem Formularfeld auch wirklich ein Tab im Feld eingefügt werden und nicht – wie sonst üblich – der Fokus auf das nächste Formularelement springen soll.

Alex King hat sich die Mühe gemacht, dafür eine Javascript-Funktion zu schreiben. Da ich gerne mit jQuery arbeite, habe ich eine Implementierung gesucht und auch gefunden:

jQuery.fn.insertAtCaret = function (myValue) {
        return this.each(function(){
                //IE support
                if (document.selection) {
                        this.focus();
                        sel = document.selection.createRange();
                        sel.text = myValue;
                        this.focus();
                }
                //MOZILLA/NETSCAPE support
                else if (this.selectionStart || this.selectionStart == '0') {
                        var startPos = this.selectionStart;
                        var endPos = this.selectionEnd;
                        var scrollTop = this.scrollTop;
                        this.value = this.value.substring(0, startPos) + myValue + this.value.substring(endPos, this.value.length);
                        this.focus();
                        this.selectionStart = startPos + myValue.length;
                        this.selectionEnd = startPos + myValue.length;
                        this.scrollTop = scrollTop;
                } else {
                        this.value += myValue;
                        this.focus();
                }
        });
};

In meinem Beispiel 1 wird – befindet sich der Fokus auf dem ersten Textfeld – beim Drücken der Backspace-Taste kein Inhalt gelöscht, sondern neuer hinzugefügt. Interessant für Menschen, denen der Konstruktivismus mehr liegt als der Destruktivismus ;-).

$('textarea#sometest').bind('keydown', function(e){
	if (e.keyCode == 8) { // Backspace
		e.preventDefault(); // Standard-Aktion verhindern
		$(this).insertAtCaret('Bitte nicht so destruktiv. Lieber ein paar mehr Zeichen!');
	}
});

Für den kompletten Code einfach den Quelltext der Beispiel-Seite betrachten.

Ein praktikableres Beispiel ist folgendes, wie oben angedeutet: Beim Drücken der Tab-Taste im zweiten Textfeld der Beispiel-Seite springt der Fokus nicht auf das nächste Textfeld, sondern ein Tab wird im Textfeld eingefügt. So etwas kann von Bedarf sein, möchte man dem Benutzer die Möglichkeit bieten, Quellcode / Text zu bearbeiten, dessen Formatierung von Bedeutung ist (in diesem Fall soll der CSS-Code möglichst lesbarsein).

$('textarea#someothertest').bind('keydown', function(e){
	if (e.keyCode == 9) { // Tab
		e.preventDefault(); // Standard-Aktion verhindern
		$(this).insertAtCaret('\t');
	}
});

Für den gesamten Code ebenfalls den Quelltext der Beispiel-Seite ansehen.

Geschrieben von Philip am 25.11.2009 | Kommentare weiterlesen...

Die Internetsite kann nicht geöffnet werden. Vorgang abgebrochen im Internet Explorer

Heute habe ich mich erneut dem Problem angenommen, dass im Internet Explorer die folgenden Fehlermeldungen erzeugt:

Die Internetsite http://<Web site>.com kann nicht geöffnet werden. Vorgang abgebrochen.
Internet Explorer cannot open the Internet site http://<Web site>.com. Operation aborted.

Dieses Problem tritt nur im Internet Explorer auf (mir persönlich bekannt in den Versionen IE6 und IE7).
Microsoft selbst empfiehlt das Update auf den Internet Explorer 8. Meiner Meinung nach sollten Sie das Surfen mit dem Internet Explorer allgemein sofort einstellen, da er Ihren Computer unsicher macht und Ihnen ausschließlich Probleme bereitet.

Microsoft selbst hat Workarounds publiziert. Diese sollten zu allererst angesehen werden. Sie werden teilweise in diesem Artikel behandelt, jedoch nicht in entsprechender Ausführung

Für die ungeduldigen Menschen ein Direktlink zu den möglichen Lösungen.

Beschreibung des Problems

Im Internet Explorer erhält man von Zeit zu Zeit die Fehlermeldung “Die Internetsite kann nicht geöffnet werden. Vorgang abgebrochen.”
Im Kontrast zu anderen Fehlermeldungen, mit denen der Internet Explorer ja allgemein gerner um sich schmeißt, als es andere Browser tun, ist diese Meldung jedoch keine, die als Hinweis dient und nach der die Webseite weiter aufgebaut wird, sondern sie zieht den kompletten Abbruch des Webseitenaufbaus nach sich. Insofern ein akuteres Problem, denn je nachdem, wann sie vorkommt, kann der Benutzer schon einmal überhaupt nichts zu Gesicht bekommen. Nicht unbedingt das, was man als Webdesigner wünscht, denn es vergrault Benutzer. Und diese geben die Schuld intuitiv der Webseite, nicht etwa dem Browser, von dem man seit Jahren weiß, dass er eigentlich längst vergessen in irgendeiner Ecke einer Mülldeponie entsorgt sein sollte.

Aber da immer noch sehr viele Benutzer mit dem Internet Explorer surfen – was sich hoffentlich in Zukunft rapide ändern wird, man betrachte die neusten Wendungen dank EU-Kommission -, macht man sich natürlich an die Lösung des Problems. Leider ist schnell zu merken, dass es sich um einen eher sporadisch auftretenden Fehler handelt, denn Google spuckt wenig aus und auf den ersten Blick scheinen viele Fehlerbeschreibungen nicht dem zu entsprechen, was man selbst auf dem Bildschirm sieht: Die ersten Ergebnisse enthalten den Wortlaut “Internetseite”, IE spricht aber von einer “Internetsite” (womöglich war Microsoft zu faul für eine Übersetzung ins Deutsche, schließlich kommt der Fehler ja kaum vor?!).

Mögliche Ursachen

Doch nach intensiveren Recherchen (heißt: auch mal die Suchergebnisse bis Seite 10 durcklicken) findet sich doch einiges an Material, das einem einen Eindruck über Ausmaß und mögliche Lösungen verschafft:

1. Javascript

Vorallem tritt der Fehler in Zusammenhang mit Javascript-Code auf:

2. Nicht aktuelle WordPress-Plugins (Lightbox, GoogleMaps)

Möglicherweise kann die Ursache auch ein WordPress-Plugin sein, das nicht auf dem aktuellsten Stand ist (Fehlerbericht WordPress Lightbox Plugin).

3. Internet Explorer Skype Addon

Das Skype-Addon für den Internet Explorer ist ein bestätigter Verursacher des Fehlers.

4. Sonstiges

  • Bei Seiten mit eingebunden YouTube Videos soll der Fehler auch schon aufgetreten sein.
  • Ein etwas abgewandelter Fehler, nämlich

    Die Internetsite konnte nicht geöffnet werden. Sie ist entweder nicht verfügbar oder konnte nicht gefunden werden. Versuchen Sie es später erneut

    soll mit einer IE-Einstellung zusammenhängen.

Mögliche Lösungen

  • Javascript: Den script-Tags das defer-Attribut hinzufügen:

    <script type="text/javascript" defer="defer">
    	<!--
    		tu dies und das;
    	//-->
    </script>
  • Javascript: Mit der DOM-Manipulation erst anfangen, wenn das Dokument vollständig geladen ist:

    <body>
    	<script type="text/javascript">
    		<!--
    			window.onload = function() {
    				tu dies und das;
    			}
    		//-->
    	</script>
    </body>
  • Javascript: Scripte im Body als direkte Kindelemente des body-Tags einfügen.
    Fehlerpotential hat:

    <body>
    	<p>
    		<span>
    			<script type="text/javascript">
    				<!--
    					tu dies und das;
    				//-->
    			</script>
    		</span>
    	</p>
    </body>

    Fehlerunanfälliger ist hingegen:

    <body>
    	<p>
    		<span>
    
    		</span>
    	</p>
    	<script type="text/javascript">
    		<!--
    			tu dies und das;
    		//-->
    	</script>
    </body>
  • WordPress: Vielleicht hilft die Aktualisierung der Plugins auf den neuesten Stand.
  • Internet Explorer Skype Plugin: Die simple Deinstallation schafft eventuell Abhilfe.
  • Youtube-Videos: Zum Test einfach einmal die Inhalte auskommentieren.

Allgemein gilt

Ursachen lassen sich am Einfachsten finden, indem man einzelne Komponenten testet. Dazu alle Seiteninhalte auskommentieren und Schritt für Schritt die Kommentarzeichen entfernen und die Seite erneut, nach Aktualisieren (F5), testen.

Geschrieben von Philip am 22.10.2009 | Kommentare weiterlesen...

MySQL Union: Mehrere Tabellen verbinden, erfahren aus welcher Tabelle Datensatz stammt

Das zugrunde liegende Problem war in diesem Fall, dass ein News-Bereich in mehrere Sektionen unterteilt sein sollte: Aktuelles, Presse, Events. Jede Sektion erhielt eine eigene Tabelle, weil die jeweiligen Datensätze sich geringfügig unterschieden (in der Presse-Sektion gab es immer eine Quelle, in der Events-Sektion eine URL für einen externen Link,..) und um bei den vielen Datensätzen die Lesezeiten so klein wie möglich zu halten (befindet sich ein Benutzer in der Pressesektion, ist es unnötig, auch die Aktuelles- und Events-Datensätze zu durchforsten).

Jedoch sollte auf der Startseite des Projekts eine Art Newsticker eingefügt werden, welcher die aktuellsten fünf Datensätze anzeigt. Das bedeutet, dass aus allen drei Tabellen gelesen und nach einem Zeitkriterium geordnet werden muss. In meinem Fall ist die Zeit in jeder Tabelle im Feld `time` als Timestamp gespeichert. Meine Abfrage, um alle drei Tabellen einzubeziehen, lautet unter Verwendung von MySQL UNION:

(SELECT `id`, `time`, `title` FROM `aktuelles`) UNION (SELECT `id`, `time`, `title` FROM `presse`) UNION (SELECT `id`, `time`, `title` FROM `events`) ORDER BY `time` DESC LIMIT 5

Um die Problematik zu verstehen, die jetzt kommt, ist ein Blick auf die Seitenstruktur des Projekts hilfreich:

  • Startseite (startseite.html)
  • News (news.html)
    • Aktuelles (news/aktuelles.html)
    • Presse (news/presse.html)
    • Events (news/events.html)

Klickt der Benutzer den “weiterlesen…”-Link im Newsticker auf der Startseite, soll er direkt in die entsprechende News-Sektion springen. Dazu muss aber bekannt sein, aus welcher Tabelle der entsprechende Datensatz stammt. Das lässt sich wie folgt umsetzen:

(SELECT 'aktuelles' AS `tbl`, `id`, `time`, `title` FROM `aktuelles`) UNION (SELECT 'presse' AS `tbl`, `id`, `time`, `title` FROM `presse`) UNION (SELECT 'events' AS `tbl`, `id`, `time`, `title` FROM `events`) ORDER BY `time` DESC LIMIT 5

So einfach lässt sich die Herkunft der Datensätze unterscheiden: In den Ergebnissen der Abfrage erscheint nun ein Feld `tbl`, das den Namen der Herkunftstabelle enthält.

Geschrieben von Philip am 02.10.2009 | Kommentare weiterlesen...

WinSCP: Entferntes Verzeichnis auf aktuellem Stand halten und dabei temporäre Dateien ausschließen

Mich plagte schon längere Zeit beim Verwenden von WinSCP die Frage, ob sich beim Verwenden der WinSCP-Funktion “Entferntes Verzeichnis auf aktuellem Stand halten” temporäre Dateien leicht ausschließen lassen.

Und zwar entwickle ich mit dem Aptana Studio, einer sehr fortschrittlichen IDE, welche – was für mich der Grund gewesen ist, von Dreamweaver zu wechseln – unter anderem Code-Vervollständigung für PHP, CSS und alle gängigen Javascript-Bibiliotheken, wie zum Beispiel jQuery, anbietet. Diese auf Eclipse basierende Entwicklungsumgebung erstellt beim Bearbeiten von Dateien temporäre Kopien, welche im Verzeichnis der Quelldateien abgelegt werden.

Durch die Verwendung der WinSCP-Funktion “Entferntes Verzeichnis auf aktuellem Stand halten” werden lokale Änderungen in einem Ordner überwacht und auf dem entfernten Server gespiegelt. Das hat in meinem Fall zur Folge, dass auch alle temporären Dateien kopiert werden. Im Endeffekt mag das zwar nicht schlimm sein, weil sie wieder vom entfernten Server gelöscht werden, sobald sie für meine IDE nicht mehr von Bedeutung sind, jedoch steigt vor allem bei langsamer Verbindung die Zeit, die verstreicht, bis die Spiegelung vollständig ist.

WinSCP bietet für diese Problematik eine Lösung, die um einiges leichter ist, als man vielleicht erwartet.. Im untersten Bereich des Fensters für die Übertragung findet sich auch ein Button “Übertragungseinstellungen”:
Screenshot 1

Übertragungseinstellungen

Nach Klicken öffnet sich eine Auswahlliste, die unter anderem den Eintrag “temporäre Dateien ausschliessen” enthält:
Screenshot 2

temporäre Dateien ausschliessen

Nach Auswahl wird eine Ausschlußmaske angezeigt:
Screenshot 3

Ausschlußmaske: *.bak; *.tmp; ~$*; *.wbk; *~; #*; .#*

Für mich ist das bereits ausreichend, weil Aptana temporäre Dateien mit *~ benennt. Sollte die Ausschlußmaske die Dateiendung jedoch nicht abdecken, so lässt sich im Auswahlmenü aus Screenshot 2 auch “Benutzerdefiniert” auswählen und eine eigene Ausschlußmaske definieren:
Screenshot 4

Geschrieben von Philip am 29.09.2009 | Kommentare weiterlesen...