(Re)formatting PHP code in Vim - php

How do I format PHP code that looks like this
class SomeClass
{
function insideclass()
{
}
}
into this, using Vim without any external tool?
class SomeClass {
function insideclass() {
}
}
I am not arguing that this is the best way to format the code, but this is what we are following in the team.
Edit: Removed reference to the snippet addon, which caused some confusion about the question.

You have two unrelated problems and you won't find a unique solution to both.
You don't like the default class snippet.
No problem. If it's not already there, create ~/.vim/snippets/php.snippets and customize it to fit your team's rules by following the other answers. Snipmate is not smart enough to adapt itself to your coding style.
Some of your existing code doesn't conform to your coding rules.
Snipmate won't help at all since it only deals with insertion, not transformation. You are going to need either some external beautifier or a few macros.
EDIT
Here is a very simple command that does exactly what you want on your example. I offer no guarantee that it's going to work for everything everywhere. Take it as a naive starting point.
:g/^\s*{\s*$/normal kJ
:g/pattern acts on all lines containing pattern, see :h :global.
^\s*{\s*$ matches all single { whatever the amount of whitespace between them and the beginning of the line.
normal executes normal commands, see :h :normal.
kJ goes up one line and Joins this line with the matched line.
Done.
ENDEDIT

Why not modify the source code of that addon?
For example, change these:
snippet class
/**
* ${1}
*/
class ${2:ClassName}
{
${3}
function ${4:__construct}(${5:argument})
{
${6:// code...}
}
}
to
snippet class
/**
* ${1}
*/
class ${2:ClassName}{
${3}
function ${4:__construct}(${5:argument}){
${6:// code...}
}
}

Al the snipmate snippets are stored in a directory. Go to that directory and edit the file you want.
The direcorty is stored in the vim directory and called snippets. In there you see a php.snippets file. Go to that file and on line 70 you can edit the snippet for the class.

Related

Using proxy or shortcuts methods in PHP

I have classes with larges methods name that are called too many times.
Example:
/**
* This class do awesome things.
*/
class AwesomeClass {
/**
* Do something awesome.
*/
public function doSomethingAwesome()
{
//Do something awesome
}
}
Now, I call the method:
$awesomeInstance->doSomethingAwesome();
The method name is large and is typed to many times. For prevent misspelling, I created a shortcut method:
/**
* Shortcut of doSomethingAwesome()
*/
public function dsa()
{
return $this->doSomethingAwesome();
}
And calling method:
$awesomeInstance->dsa();
Is this a bad practice? How afect the performance?
It is a commonly stated rule of thumb that code is read more often than it is written. Even if writing code only for your own use, you will not remember everything about how it works when you read it back in 6 months time to make some amendment.
Your shortcut method names optimise your codebase for writing, because they make it quicker to type, and less error-prone.
However, they are actively harmful for reading, because they lead to less descriptive code, and require you to cross-reference the comment on the shortcut to check what it abbreviates.
Instead, you should aim to write the same code (thus retaining readability) but find tools to do so more easily and with fewer errors. A major helper in this case would be using a more powerful code editor or IDE, which will include auto-complete and code navigation facilities. You can also use standalone "code linting" / "static analysis" tools to pick up mistyped function names.
Performance shouldn't be an issue. But readability of your code suffers. You should use descriptive method names. If this function is called too many times it's a code smell and some refactoring may be needed.
I would not recommend creating shortcut methods. I am not sure why your methods do have such long names. Maybe your methods do more than one task?
for example:
$awesomeInstance->parseCheckAndSaveMyAwsomeObject();
in that case, you should write a dedicated method for each task.
Could you explain it in more detail?

Doxygen and PHP - how to parse code that is not run?

I have some PHP code that is documented with Doxygen. In this code, there are a number of hooks, which are functions that my code calls, but the functions themselves are defined by the users of this code.
I want to document the hooks, but because the functions don't exist in my code (the users define the functions, my code just calls them) there is nowhere for me to attach the Doxygen comments to - unless I define a fake function.
Is there some way I can avoid defining this fake function? If I were using C I could define the function but use #ifdefs to hide it from the compiler (but still have Doxygen see it), but I'm not sure what the equivalent is in PHP. Ideally I'd want something that wouldn't result in any additional effort on the part of the PHP parser.
Any suggestions? This is what I am trying to document, and how I have it now with the fake function:
/// This is an example hook.
/**
* Register it with $hooks['example'][] = 'your_function_name_here';
*
* #param string $dummy
* Dummy parameter.
*/
function hook_example($dummy) { }; // fake function for Doxygen
If you want other programmers to implement your hooks use OOP interfaces and abstract classes. This will sanitize your code.
As a side effect, Doxygen will be very happy to document the abstract methods.
Since PHP doesn't support #ifdef blocks, I think the only way this can be done is to take the comments and fake function declarations and put them in another .php file. Configure Doxygen to include this new file, but don't include() it anywhere in the rest of the code.
Then the fake functions will appear in the documentation, but the PHP parser will never know about them.

How to make sections of PHP code in eclipse

I've really only just discovered that you can use /** #blah */ comments to specify certain things, but is it possible to create sections in code?
Like:
/** Start Section "Blah" **/
$result = doSomething();
echo $result;
/** End Section "Blah" */
No PDT can't do that. Generally expandable code sections are identified by function and class method bodies.
If you think you need artificial sections identified by comments I recommend to rather think about reorganizing your code into more fine grained files, function, classes and methods that can be easily documented using PhpDoc (which is the standard PDT uses).
these sections
/**
* here goes your text
* #author Nanne
* /
Are based on javadoc: http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html
Look at this page where a documenter for PHP is described. I don't know what standard is used in Eclipse, but I'm guessing they're all rather alike:
http://www.phpdoc.org/
Is is mostly based on commenting certain parts of code, e.g. classes, functions and variables. As far as I know there is no special code for "sections". The reason I think this, is that you are 'supposed' to make a documentation from this, with classes, it's methods etc. There is no special way to represent "sections" in a documentation like that.
But do read above links, it'll clear up a lot!
In PHP you can use sections to separate pieces of code. Syntax is like this:
Blah:{
$result = doSomething();
echo $result;
}
These were used by goto style procedural programming before object oriented programming was used (classes and instances). Using these sections and goto statements is very bad practice and should be shunned by any developer.
https://www.php.net/manual/en/control-structures.goto.php

Extracting function declarations from a PHP file

I'm looking to create an on-site API reference for my framework and application.
Basically, say I have a class file model.class.php:
class Model extends Object {
... code here ...
// Separates results into pages.
// Returns Paginator object.
final public function paginate($perpage = 10) {
... more code here ...
}
}
and I want to be able to generate a reference that my developers can refer to quickly in order to know which functions are available to be called. They only need to see the comments directly above each function and the declaration line. Something like this (similar to a C++ header file):
// Separates results into pages.
// Returns Paginator object.
final public function paginate($perpage = 10);
I've done some research and this answer looked pretty good (using Reflection classes), however, I'm not sure how I can keep the comments in.
Any ideas?
I want to keep the current comment formatting. Myself and the people who are working on the code hate the verbosity associated with PHPDocumentor. Not to mention a comment-rewrite of the entire project would take years, so I want to preserve just the // comments in plaintext.
Why don't you just run PHPDocumenter on the code?
PHPDoc is identical to JavaDoc, and will retain all the parameters and comments in the docblock above the function.
EDIT: Since you don't want PHPDoc, I think it would probably be easiest to write a RegEx parser to do it, since Reflection won't provide you with any surrounding comments.
PHP code to get the comment:
if(preg_match("#//(.+)$#",$line,$match)>0)
{
echo "Comment is: ".$match[1];
}
this is what phpdoc is for. you comment your code a specific way, following certain rules, and when you're done you run your code through a parser. It outputs exactly what you're looking for.

Define a class dynamically?

Is there a way to dynamically and conditionally create a class definition in PHP, i.e.
if (condition matches)
include file containing class definition
else
class myclass extends ancestor_class { .................... }
without eval()?
My background is the accepted answer to this question. I am looking for the best way to build a untouchable core library, with user-defined empty classes extending the core library if necessary.
I want to create the final class definition "on the fly" if there is no user-defined empty class for a certain ancestor class.
Including another include file (containing the empty class definition) is out of the question, as there will be quite a number of classes.
Update: This seems to be possible in a normal condition block - didn't think of that. However, according to this article, it also seems to be regarded as bad practice and may be removed in the future. Hmm. Creative ideas welcome.
See the comments under the question for more information -- I'll try to summarize, as it might be useful to other :-)
First of all, I suppose the goal is not having users create almost empty files by themselves -- I remember another question, I think it was from you, where that popped up.
If so, why not just create those almost empty files dynamically ?
I mean, some idea like that :
if (condition matches) {
include file containing class definition
} else {
create another file containg the alternate class definition
include that other file
}
As #Gordon said in a comment, a possibility, to makes things a bit easier, would be to use Zend_CodeGenerator, to help with that task of code-generation.
As pointed out : the users will not likely have write-access on the library directory, but nothing prevents you from creating those files into another "cache" directory -- afterall, it's likely that your application has write-access to at least one directory :
For cache ^^
Or, at least, for logs
A solution would be to use eval:
build a string containing the class' definition
evaluate it
But I would really not do that, for at least two reasons :
Debugging will probably be harder -- even for an almost empty file/string
Using a file means there is a possibility for opcode caching (APC, or similar tools)
And, as a third, thinking about it : having a file means your IDE can parse it -- might help with code-completion, type-hinting, ...
Seeing your update, I tried conditional declaration :
if (false) {
class A {
public $a = 10;
}
} else {
class A {
public $a = 20;
}
}
$a = new A();
var_dump($a);
Changing the condition from false to true and vice-versa, I get two alternate output :
object(A)[1]
public 'a' => int 20
object(A)[1]
public 'a' => int 10
So... well, seems to be working!
(I'm surprised, I thought it was only possible for functions!)
But, still, I don't really like that idea... Not sure how it behaves in IDEs -- and I like having one class per file...
(Yeah, personnal opinion)

Categories