PHP Code Generation with Elispby Zachary Kessin
Larry Wall, the creator of Perl, has stated that the three virtues of a programmer are laziness, impudence, and hubris. I think he's right. Most programming seems to consist of writing a small amount of interesting logic to implement business rules or a user interface, and then a lot of glue to hold it all together.
Calling SQL in a PHP function is a pretty simple operation, requiring several steps. Example 1, a generic PHP function: first, take in any parameters to the function. Initialize MySQL or get an existing handle. Clean the inputs to guard against SQL insertion attacks or cross-site scripting. Run the SQL via the MySQL interface. Then process the result. In the case of a
SELECT statement the code must loop over the returned rows. In the case of an
INSERT, returning the
insert_id would make sense; otherwise, return a
true value to the calling function. The code should also throw an exception in case of a problem.
This is a little too complex to copy and paste for different SQL statements. First of all, the code to escape strings must be customized for each instance, as the parameter names will change. However, it is not hard to write code to parse a SQL statement and output a PHP function to meet these needs. You could write this function in any number of languages; for example, writing it in PHP seems obvious. As I do my programming in GNU Emacs, it seems sensible to write it in Emacs Lisp so that I can run it directly in my Emacs buffer without having to call an external program.
Emacs Lisp is an excellent language for this type of application, as it combines the power of Lisp with integration into Emacs, one of the most powerful text editors around.
This Lisp code is pretty simple. Grab the SQL text, parse out the PHP variables from a SQL statement using a regular expression, and then use that information to write the full PHP function to insert into the original Emacs buffer.
A Short Introduction to Emacs Lisp
For programmers who grew up with languages in the C family tree (which also includes, C++, C#, Java, Perl, and PHP), Lisp just looks strange. There are lots of parentheses and not much else. The secret to Lisp's grammar is that it really doesn't have any. Everything in Lisp is data, including the code. A Lisp expression starts with a parenthesis, the first word is the command, and everything following that is a parameter to that command. In Lisp, all expressions return a value and the compiler evaluates and substitutes nested expressions as needed.
Emacs Lisp defines a function with the
defun keyword, which takes a function name and a list of parameters. You can also define an unnamed function with the
lambda keyword, which just takes a list of parameters. A function defined by
lambda has no name, but you can use it where you need to pass a function. This can be quite powerful, as you can create functions that return other functions. As in Perl, Lisp can treat functions as data.
Lisp stands for "List Processing," and of course it handles lists very well. The
list is the basic data structure in Lisp. The basic ways to access the elements of the list are with
(car list) and
(cdr list). The
(car list) statement returns the first element of the list, and the
(cdr list) statement returns the rest of the list. It is, of course, also possible to access the nth element of a list directly.
To build a list, if you know all of the items in advance, use the
(list args) command. If you don't know all of the items, put it together one item at a time with
cons. A list in Lisp is a sequential access data structure. Each element of the list consists of a pointer for data and a pointer for the next element in the list. A normal list has an empty list (equivalent of a null) as its last element. Lists can also be recursive or contain other data structures.
This application generally needs to apply a function to each element of the list and then concatenate the results together. To do that, use the
mapconcat function. This function takes a list and a function, in the form of a
mapconcat applies the function to each of the elements in the list, and then puts all the strings together into one big string.
Lisp comments start with a semicolon (
;) and continue to the end of the line, similar to the way the hash (
#) works in PHP.
To evaluate a Lisp expression in Emacs, you must be in a buffer in "Emacs-Lisp" mode. The Emacs command
C-x C-e evaluates the last Lisp expression and returns the result in the mini-buffer at the bottom of the Emacs window.
Pages: 1, 2