I did a really stupid mistake after reading about var
in PHP7 and I mistakenly thought that I don't need neither var
nor public
to declare variables inside of a class (outside of it's methods). So I removed it from 400+ files and did some refactoring on pretty much all of them. So I can't just revert back, because that would leave me with even more work.
Now I get a fatal error and I need to add either private
or public
to all variables declared that way. I'm not sure if any of these classes actually need public variables, probably private
should be enough.
But I can't figure out if it's even possible to do in Sublime Text 3. I tried many different combinations of regex, but none of them worked. I'm guessing that I might need a script to run though all files instead, but maybe I'm overlooking something...
So I have something like this:
class MyClass {
$myvar1;
$myvar2;
function __construct($myvar1 = NULL, $myvar2 = array()) {
$this->myvar1 = $myvar1;
$this->myvar2 = $myvar2;
}
}
And I want to turn it into this:
class MyClass {
private $myvar1;
private $myvar2;
function __construct($myvar1 = NULL, $myvar2 = array()) {
$this->myvar1 = $myvar1;
$this->myvar2 = $myvar2;
}
}
EDIT: Please note that there are no comments (neither C/C++ nor # style) between the class declaration and its first function. Also string notation should not be considered. The solution should solve specifically this issue, because it seems to be impossible to make it universal for all possible cases. It seems that using \G
modifier is the key to solve this particular issue the way I wanted to. So use the answer with caution.
I think I need to replace all occurrences of $
with private $
in between class
and the first occurrence of function
. Could it be possible just with Sublime Text 3?
So far I fail at even finding all occurences of a pattern that starts with class
and ends with the first function
. Currently I'm trying to improve the following regex: (?s)class (.*?){.+function
. For some reason the selection ends at the last function, not the first one and I can't figure out how to fix that. As the worst option I could use this pattern to search through all 400+ files and then edit them manually, but that would be a pain, of course...
PS: is it even a good practice to declare them there if I assign them in the __construct
method anyway?
The following regex will only match variables after the class's opening and will not work after a comment or constant declaration. See regex in use here
(?:\bclass \w+\s*{\s*|\G(?!\A)\s*)\K(\$\w+\s*(?:;|=.*;))
For a regex that works around comments and constants as well you can use the following (see regex in use here). Note that this, once again, only works for variables at the top of a class:
(?:\bclass \w+\s*{\s*|\G(?!\A)\s*(?:(?://|#).*$|/\*[\s\S]*?\*/|\bconst[^;]*;)\s*)\K(\$\w+\s*(?:;|=.*;))
If variables are declared after the top of the class, your best bet for a quick and dirty solution is to use the whitespace as an indicator of what belongs to the class and what doesn't. Assuming you use proper indentation of either 1 tab character or 4 space characters, you can use ^(?:\t| {4})\K(\$\w+)
Replacement: private $1
(?:\bclass \w+\s*{\s*|\G(?!\A)\s*)
Matches either of the following:\bclass \w+\s*{\s*
\b
Assert position as a word boundaryclass
Match this literally\w+
Match one or more word characters\s*{\s*
Match any number of whitespace, followed by {
, followed by any number of whitespace\G(?!\A)\s*
Assert position at the end of the previous match and match any number of whitespace\K
Resets the starting point of the reported match. Any previously consumed characters are no longer included in the final match(\$\w+\s*(?:;|=.*;))
Capture the following into capture group 1\$\w+\s*
Match $
literally, followed by one or more word characters then any number of whitespace(?:;|=.*;)
Match either ;
or =
followed by any character any number of times and then ;
Although accepted answer may fit OP needs, it has much pitfalls. It doesn't work if properties have comments, or class extends another class or implements an interface or constants are defined between properties or comma separated declarations do exist.
You may find this regex more accurate (not bulletproof though):
(?m)function(*COMMIT)(*F)|^\s*\K\$\S+\s*[=;,]
Put private $0
as replacement string.