Emacs php-mode and paredit - php

I would like to use paredit in combination with php-mode, but it doesn't add a closing curly bracket "}". Might this have something todo with the fact that an electric brace is bound to "{"? And how could I overwrite this?
Thanks.

Using paredit is php-mode is a bad idea - it's mostly suited for Lisp code editing. There is a very nice alternative for general purpose development though - autopair-mode. It's very easy to use and inserts braces, brackets and quotes in a manner similar to the one present in most IDEs.

Some time ago, I wrote such a thing for C, but you can easily use it for PHP as well:
(define-minor-mode c-helpers-minor-mode
"This mode contains little helpers for C developement"
nil
""
'(((kbd "{") . insert-c-block-parentheses))
)
(defun insert-c-block-parentheses ()
(interactive)
(insert "{")
(newline)
(newline)
(insert "}")
(indent-for-tab-command)
(previous-line)
(indent-for-tab-command)
)
(add-hook 'php-mode-hook 'c-helpers-minor-mode)

In my experience, autopair-mode felt extremely sluggish when a large number of buffers were open (plus, paredit-mode ensures that delimiters are never unbalanced, unlike autopair-mode). So if, like me, you absolutely want to use paredit-mode and nothing else will do, have a look at this answer. In the elisp snippet given there, just replace slime-repl-mode-map and slime-repl-mode-hook with the corresponding variables for php (most likely php-mode-map and php-mode-hook)

Related

Regex to match all top-level functions

I'd like to parse PHP code with a regex to find all the top-level functions declared in our codebase.
The simple:
^\s*function\s*([\w_-]+)\(
works pretty well, but catches the extra
class Foo {
function bar() {...}
}
Any ideas on how to skip non-top-level functions that don't have scope delcared?
Note: I know, I know, I should use a real parser but I want something quick and dirty that can run in grep -R -P over a very large codebase.
On a well-indented code base,
^function\s*([\w_-]+)\(
should catch only top-level functions. If you expect leading spaces, you could use a zero-width negative look-behind for a {, to avoid functions right at the beginning of a class declaration:
(?<!{)\s*function\s*([\w_-]+)\(
First of all, I have to say that this sort of stuffs depend largely on how disciplined you code is. For myself, I start all top-level functions immediately at the beginning of lines. So if I wanted to find non-top-level functions (in vim), I simply do
/^[[:space:]]\+function[[:space:]]\+\w\+\>
and
/^function[[:space:]]\+\w\+\>
for all top-level functions.
However, as I said, it depends on how well formatted your codebase is. Good luck!
If you're willing to use ruby (or basically anything with named capture groups), you could use something like this:
^\s*(?<type>\w+)\s*(?<name>[\w_-]+)(?<function>\([^()]*\))?\s*(?<body>{((?>[^{}]+)|(\g<body>))*})
The ones that are functions will have brackets in the function capturing group. The ones are classes won't.
http://rubular.com/r/3dXZts6OYF
Extremely brittle though.

PHP Switch Statement where the string is encapsulated in double quotes

I have an issue here, and I'm looking for experienced programmers to tell me which is the preferred solution.
I have values being returned that are surrounded in quotes. "TOTAL" and "VALUE" being two examples. These should not be confused with TOTAL and VALUE -- the string is actually surrounded by double quotes.
What I noticed is that the switch statement below doesn't work because it's looking for TOTAL not "TOTAL":
switch ($statTypeName) {
case "TOTAL":
echo "<br>TOTAL";
break;
case "VALUE":
echo "<br>VALUE";
break;
}
To get this working, I had to put a single quote around the case -- '"TOTAL"'.
In my text editor (Notepad++), it is difficult to see the single quote around the double quotes.
I know this isn't a common issue, but what would be the "professional" way of solving this? The way I did it, or should I be extracting the string from the quoted string and do away with the double quotes altogether..?
Thanks!
case "\"TOTAL\"":
Escape the inner double quotes. It will work the same way and might be a little more visible to the reader
What you're running into is indeed common, and you can go about it a couple different ways. There's nothing wrong with the way you're doing it, or #KyleBanks solution (escaping the double quotes). Given php provides single and double quote string definitions, I prefer the first. But its up to your preference, or your dev team.
As far as extracting the substring within the string quotes.. it depends on what they're there for in the first place.
I would suggest using a better font in Notepad++. I personally use Consolas however here you can find heaps of other good options:
Recommended Fonts for Programming?
Other then changing font escaping quotes as was suggested is another alternative:
case "\"TOTAL\"":
You can also try to strip quotes:
switch (substr($statTypeName, 1, -1)) {...}
but i consider it as a more dangerous approach unless you start using more complicated code to strip them with checks and everything in which case it clearly becomes an overkill.
Except if your given code is not part of some kind of StatType class and is dealing internally with the representation of stat type states my answer might be missing the point a bit, but in any case here it is.
In fact you are doing something wrong here and what you are asking is to find a way to workaround the essential problem you are having. Instead, you should fix the essential problem.
Essential problem is that you are missing one layer of abstraction which will sit between the way you are representing your statType and the way you are using it.
So, your program should not care if you call your statType:
"TOTAL" or '"TOTAL"' or "Total" or "total"
What you need to care is that your statType is in certain state in one moment of program execution. How that representation of the state is implemented ( a string with quotes or a number) is detail of implementation and your switch statement should not care about it.
What happens if you decide to change your statTypeName to be without quotes for example. Than you'll have to go to every line of code that depended on it having quotes and to change it. If you would hide the implementation details in some way you would not need to change more than one line of code.
Maybe one approach to setting abstraction around statTypes? (simplified for clarity)
class StatType
{
const TOTAL = 0;
const VALUE = 1;
// etc.
}
switch ($statType->type()) {
case StatType::TOTAL:
echo "<br>TOTAL";
break;
case StatType::VALUE:
echo "<br>VALUE";
break;
}

Hypothetical concatenation predicament

So I am working on a simple micro language/alternative syntax for PHP.
Its syntax takes a lot from JavaScript and CoffeeScript including a few of my own concepts. I have hand written the parser (no parser generator used) in PHP to convert the code into PHP then execute it. It is more of a proof of concept/learning tool rather than anything else but I'd be lying if I said I didn't want to see it used on an actual project one day.
Anyway here is a little problem I have come across that I thought I would impose on you great intellects:
As you know in PHP the period ( . ) is used for string concatenation. However in JavaScript it is used for method chaining.
Now one thing that annoys me in PHP is having to do use that bloody arrow (->) for my method chains, so I went the JavaScript way and implemented the period (.) for use with objects.
(I think you can see the problem already)
Because I'm currently only writing a 'dumb' parser that merely does a huge search and replace, there is no way to distinguish whether a period (.) is being used for concatenation or for method chaining.
"So if you are trying to be like JavaScript, just use the addition (+) operator Franky!", I hear you scream. Well I would but because the addition (+) operator is used for math in PHP I would merely be putting myself in the same situation.
Unless I can make my parser smart enough (with a crap load of work) to know that when the addition (+) operator is working with integers then don't convert it into a period (.) for concatenation I am pretty much screwed.
But here is the cool thing. Because this is pretty much a new language. I don't have to use the period or addition operator for concatenation.
So my question is: If I was to decide to introduce a new method of string concatenation, what character would make the most sense?
Does it have to be one character? .. could work!
Any myriad of combinations, like ~~ or >: even!
If you don't want to use + or ., then I would recommend ^ because that's used in some other languages for string concatenation and I don't believe that it's used for anything in PHP.
Edit: It's been pointed out that it's used for XOR. One option would be to use ^ anyway since bitwise XOR is not commonly used and then to map something else like ^^ to XOR. Another option would be to use .. for concatenation. The problem is that the single characters are mostly taken.
Another option would be to use +, but map it to a function which concatenates when one argument is a string and adds otherwise. In order to not break things which rely on strings which are numbers being treated as their values, we should probably treat numeric strings as numbers for these purposes. Here's the function that I would use.
function smart_add($arg1,$arg2) {
if ($arg1.is_numeric() && $arg2.is_numeric()) {
return $arg1 + $arg2;
} else {
return $arg1 . $arg2;
}
}
Then a + b + c + d just gets turned into smart_add(smart_add(smart_add(a,b),c),d)
This may not be perfect in all cases, but it should work pretty well most of the time and has clear rules for use.
So my question is: If I was to decide to introduce a new method of
string concatenation, what character would make the most sense?
As you're well aware of, you'll need to chose a character that is not being used as one of PHP's operators. Since string concatenation is a common technique, I would try to avoid using characters that you need to press SHIFT to type, as those characters will be a hindrance.
Instead of trying to assign one character for string concatenation (as most are already in use), perhaps you should define your own syntax for string concatenation (or any other operation you need to overwrite with a different operator), as a shorthand operator (sort of). Something like:
[$string, $string]
Should be easy to pick up by a parser and form the resulting concatenated string.
Edit: I should also note that whether you're using literal strings or variables, there's no way (as far as I know) to confuse this syntax with any other PHP functionality, since the comma in the middle is invalid for array manipulations. So, all of the following would still be recognized as string concatenation and not something else in PHP.
["stack", "overflow"]
["stack", $overflow]
[$stack, $overflow]
Edit: Since this conflicts to JSON notation, the following alternative variations exist:
Changing the delimiter
Omitting the delimiter
Example:
[$stack $overflow $string $concatenation] // Use nothing (but really need space)

Help with Regex in PHP

Let's assume I do preg_replace as follows:
preg_replace ("/<my_tag>(.*)<\/my_tag>/U", "<my_new_tag>$1</my_new_tag>", $sourse);
That works but I do also want to grab the attribute of the my_tag - how would I do it with this:
<my_tag my_attribute_that_know_the_name_of="some_value">tra-la-la</my_tag>
You don't use regex. You use a real parser, because this stuff cannot be parsed with regular expressions. You'll never know if you've got all the corner cases quite right and then your regex has turned into a giant bloated monster and you'll wish you'd just taken fredley's advice and used a real parser.
For a humourous take, see this famous post.
preg_replace('#<my_tag\b([^>]*)>(.*?)</my_tag>#',
'<my_new_tag$1>$2</my_new_tag>', $source)
The ([^>]*) captures anything after the tag name and before the closing >. Of course, > is legal inside HTML attribute values, so watch out for that (but I've never seen it in the wild). The \b prevents matches of tag names that happen to start with my_tag, preventing bogus matches like this:
<my_tag_xyz>ooga-booga</my_tag_xyz><my_tag>tra-la-la</my_tag>
But that will still break on <my_tag> elements wrapped in other <my_tag> elements, yielding results like this:
<my_tag><my_tag>tra-la-la</my_tag>
If you know you'll never need to match tags with other tags inside them, you can replace the (.*?) with ([^<>]++).
I get pretty tired of the glib "don't do that" answers too, but as you can see, there are good reasons behind them--I could come up with this many more without having to consult any references. When you ask "How do I do this?" with no background or qualification, we have no idea how much of this you already know.
Forget regex's, use this instead:
http://simplehtmldom.sourceforge.net/

How to make Zend IDE 5.5.1 to not bother about backslashes?

I use Zend IDE and quite often use Analyze code to quickly find undeclared or unused variables. As all PHP developers I also use regular expressions.
So main question is where to set a checkbox or tune config file to disable these warnings:
Bad escape sequence: \s (line NN)
Thanks for answers!
window->preferences->php->code analyzer->bug->bas escape sequence
Why don’t you just correct the mistyped string declarations. If you have the regular expression foo\sbar, write it as:
'foo\\sbar'
"foo\\sbar"
I followed the suggestion from #SMka and worked like a charm. However, for my version of Zend Studio (10.1), the option was:
Window->Preferences->Semantic Analysis Properties
From there, just set "Bad escape sequence in string" to Ignore.
Keep in mind that I'm not suggesting to change it in every case. This was what I wanted because was flagging all my regexp (reg exps. that have been working for years, so no reason to change them because of a warning).
Hope this helps...

Categories