Although you can create an UDF named 'regexp()', I think it won't be registered as REGEXP operator..
<?php
//registering REGEXP
function my_sqlite_regexp($x,$y){
return (int)preg_match("`$y`i",$x);
}
echo $db->createFunction('regexp','my_sqlite_regexp',2);
//testing regexp as function, working
$res = $db->query("SELECT * FROM x WHERE regexp(c,'h')", SQLITE_ASSOC , $err) ;
//testing regexp as operator, not working, near "REGEXP": syntax error
$res = $db->query("SELECT * FROM x WHERE c REGEXP 'h'", SQLITE_ASSOC , $err);
?>
I'd also swapped the function parameters $x and $y, but also not works..
-----
From SQLite documentation:
"The REGEXP operator is a special syntax for the regexp() user function. No regexp() user function is defined by default and so use of the REGEXP operator will normally result in an error message. If a application-defined SQL function named "regexp" is added at run-time, that function will be called in order to implement the REGEXP operator."
sqlite_create_function
SQLiteDatabase->createFunction
(PHP 5 < 5.4.0, sqlite >= 1.0.0)
sqlite_create_function -- SQLiteDatabase->createFunction — Registriert eine "reguläre" nutzerdefinierte Funktion für den Gebrauch in SQL-Befehlen
Beschreibung
$dbhandle
, string $function_name
, callback $callback
[, int $num_args = -1
] )Objektorientierter Stil (Methode):
sqlite_create_function() erlaubt Ihnen, eine PHP-Funktion in SQLite als UDF (User Defined Function = Nutzerdefinierte Funktion) zu erzeugen, so dass diese direkt in SQL-Befehlen genutzt werden kann.
UDF sind in jedem SQL-Befehl nutzbar, der Funktionsaufrufe wie SELECT, UPDATE oder auch Trigger beinhalten kann.
Parameter-Liste
-
dbhandle -
Die Ressource des SQLite-Ergebnisses, erzeugt von sqlite_open() wenn in prozeduralem Kontext genutzt. Dieser Parameter wird nicht benötigt, wenn die objektorientierte Notation genutzt wird.
-
function_name -
Name der Funktion, wie er in den SQL-Befehlen genutzt werden soll.
-
callback -
Eine beliebige gültige PHP-Funktion oder Methode, die aufgerufen werden soll, um die SQL-Funktion abzuarbeiten.
Hinweis: "Callback"-Funktionen sollten einen Variablentyp zurückgeben, der von SQLite erkannt wird (z.B. Skalare).
-
num_args -
Hinweis für den SQLite-Parser auf die Parameterzahl der "Callback"-Funktion. Es wird empfohlen, diesen Wert zu definieren, wenn Ihre Funktion immer mit der gleichen Parameterzahl arbeitet.
Hinweis: Zwei alternative Syntaxen werden für die Kompatibilität mit anderen Datenbank-Erweiterungen (wie z.B. MySQL) unterstützt. Die bevorzugte Form ist die erste, bei der der Parameter
dbhandleder erste Parameter der Funktion ist.
Rückgabewerte
Es wird kein Wert zurückgegeben.
Beispiele
Beispiel #1 sqlite_create_function()-Beispiel
<?php
function md5_and_reverse($string)
{
return strrev(md5($string));
}
if ($dbhandle = sqlite_open('mysqlitedb', 0666, $sqliteerror)) {
sqlite_create_function($dbhandle, 'md5rev', 'md5_and_reverse', 1);
$sql = 'SELECT md5rev(filename) FROM files';
$rows = sqlite_array_query($dbhandle, $sql);
} else {
echo 'Fehler beim Öffnen der Datenbankverbindung: ' . $sqliteerror;
exit;
}
?>
In diesem Beispiel haben wir eine Funktion, die die md5-Summe eines
Strings berechnet und dann rückwärts ausliefert. Wenn der SQL-Befehl
durchgeführt wird, liefert er den Wert der Spalte "filename" durch unsere
Funktion transformiert zurück. Die Daten, die in $rows
stehen, enhalten also die bereits gewandelten Daten.
Die Eleganz dieser Technik ist das Vermeiden des Durchfahrens des kompletten Abfrageergebnisses mit einer foreach-Schleife.
PHP registriert außerdem automatisch eine spezielle Funktion
mit dem Namen php, wenn die Datenbank
dbhandle zum ersten Mal geöffnet wird.
Diese Funktion kann genutzt werden, um eine beliebige PHP-Funktion
aufzurufen, ohne dass sie zunächst für SQLite erzeugt werden muss.
Beispiel #2 Beispiel zur Nutzung einer beliebigen PHP-Funktion
<?php
$rows = sqlite_array_query($dbhandle, "SELECT php('md5', filename) from files");
?>
In diesem Beispiel wird die Funktion md5() für
jeden Eintrag der Spalte filename in der Datenbank
aufgerufen und das Ergebnis in $rows geschrieben.
Hinweis:
Aus Performanzgründen kodiert/dekodiert PHP nicht automatisch die Binärdaten der Spalten, die in die UDF/aus der UDF geliefert werden. Daher müssen Sie die Parameter und Rückgabewerte der Funktion jeweils selbst wandeln. Die Funktionen sqlite_udf_encode_binary() und sqlite_udf_decode_binary() sind dabei behilflich.
Es wird empfohlen, die UDFs nicht für Binärdaten zu nutzen, wenn Ihre Anwendung eine hohe Geschwindigkeit aufweisen soll.
sqlite_create_function() und sqlite_create_aggregate() können dazu genutzt werden, native SQlite-Funktionen zu überschreiben.
Siehe auch
- sqlite_create_aggregate() - Registriert eine benutzerdefinierte Funktion, um SQL-Abfragen zu aggregieren
In my previous comment, there was an error in the code which was causing the issue.
Removing the surrounding quotes from from_unixtime()'s return value solved the issue, and so UDFs _do work_ from within DELETEs and INSERTs! Yay!
<?php
// SQLite UDF
// Mimic MySQL FROM_UNIXTIME
function from_unixtime($unixtime)
{
return date('Y-m-d H:i:s', $unixtime); // no surrouding quotes
}
?>
It appears that UDFs created by sqlite_create_function() do not work properly within INSERT or DELETE statements.
A simplified INSERT example:
<?php
// SQLite UDF
// Mimic MySQL FROM_UNIXTIME function
function from_unixtime($unixtime)
{
return "'".date('Y-m-d H:i:s', $unixtime)."'";
}
// -----------------------------------------------------------
// Open the database and create the UDF
$handle = sqlite_open('db.sqlite', 0666);
sqlite_create_function($handle, 'FROM_UNIXTIME', 'from_unixtime', 1);
// Insert a row
$sql = "
INSERT INTO table (name, timestamp)
VALUES ('Foo', FROM_UNIXTIME(".time().");
";
$result = sqlite_exec($handle, $sql);
// Retrieve the row
$sql = "SELECT * FROM table";
$result = sqlite_unbuffered_query($handle, $sql)
$row = sqlite_fetch_all($result, SQLITE_ASSOC);
// Dump
print_r($row);
?>
This will show:
Array
(
[0] => Array
(
[name] => 'Foo'
[timestamp] => -1
)
)
The expected result for timestamp would be something like '2005-05-20 10:00:00'
The function can be a method of a class:
<?php
class sqlite_function {
function md5($value)
{
return md5($value);
}
}
$dbhandle = sqlite_open('SQLiteDB');
sqlite_create_function($dbhandle, 'md5', array('sqlite_function', 'md5'), 1);
// From now on, you can use md5 function inside your SQL statements
?>
It works fine :)
