Script to modify php array elements in hundreds of files - php

I have some severely deprecated PHP code that I'm sifting through. One of the problems that I have is hundreds of errors like this:
[Mon Dec 09 07:00:33 2013] [error] [client 127.0.0.1] PHP Notice: Use of undefined constant id - assumed 'id' in /home/srv/site.local/content/online.php on line 171, referer: http://site.local/index.php
These result in the practice of a previous coder of calling arrays like this:
$array[some_element]
instead of:
$array['some_element']
So I know how to fix that by going through each file and adding the quotes, over, and over, and over again. My question is how to write script for this. I imagine this might be a sed or awk script, but I'm not sure. I'm going to start working on a sed as soon as I'm done posting this, but any suggestions?

I don't know anything about php, so I'm not sure whether this solution is a particularly good one:
sed "s|\[[ ]*|\[\'|g;s|[ ]*\]|\'\]|g" test.in
example of use:
[fixarraysubscript $] cat test.in
$array[some_element]
$name1[index]
$name2[index]
$name3[ id ]
$name4[ id2 ]
[fixarraysubscript $]
[fixarraysubscript $] sed "s|\[[ ]*|\[\'|g;s|[ ]*\]|\'\]|g" test.in
$array['some_element']
$name1['index']
$name2['index']
$name3['id']
$name4['id2']
[fixarraysubscript $]
obviously my input file is somewhat contrived. If this doesn't work for you, please feel free to post some real input.

This may work with gnu awk
echo '$array[some_element]' | awk '{print gensub(/\$([^[]+)\[([^]]+)]/,"$\\1["q"\\2"q"]","g")}' q="'"
$array['some_element']
For your file
awk '{print gensub(/\$([^[]+)\[([^]]+)]/,"$\\1["q"\\2"q"]","g")}' q="'" file
or
awk '{print gensub(/\$([^[]+)\[([^]]+)]/,"$\\1[\x27\\2\x27]","g")}' file
EDIT: Changed regex to reflect variable array name.

Related

Extract ZIP's contents on screen but avoid extra information except of the file names

I am looking for a command that will print all the contents of an archive (including sub-folders and it's files) without extracting the actual archive on the disk, but only on screen.
I achieve something using some other questions and answers from this site, and here is my command:
unzip -l test.zip | awk '/-----/ {p = ++p % 2; next} p {print $NF}'
The output:
0 04-11-2009 13:43 jodconverter-webapp-2.2.2/ 1815 04-11-2009 13:43 jodconverter-webapp-2.2.2/README.txt 0 04-11-2009 13:43 jodconverter-webapp-2.2.2/src/ 5349 04-11-2009 13:42 jodconverter-webapp-2.2.2/src/jodconverter-webapp-2.2.2-sources.jar 26436 04-11-2009 13:43 jodconverter-webapp-2.2.2/LICENSE.txt 3819 04-11-2009 13:43 jodconverter-webapp-2.2.2/ChangeLog.txt 3314202 04-11-2009 13:42 jodconverter-webapp-2.2.2/jodconverter-webapp-2.2.2.war
As you can see the output is one line, and includes some extra information that I don't really need.
I want an output of this kind:
jodconverter-webapp-2.2.2/
jodconverter-webapp-2.2.2/README.txt
jodconverter-webapp-2.2.2/src/
jodconverter-webapp-2.2.2/src/jodconverter-webapp-2.2.2-sources.jar
.
.
.
So not only I want to output the file names only (and their full path) and avoid any extra other information like time permissions and so on, but also I want to use something like break-line to distinguish different files.
Keep in mind that this command will run on a PHP file to get the contents of the file, so I don't know if this can help us to use the <br> to do the break lines.
Is that possible with a single command?
Well, I can't think a command that will return you back the output you need, but may someone else can know something more.
What I would do in your case is to split the line into array and play with it until you get what you want.
You actually have to find a pattern that will work for all cases.
With a brief look on the command's output I came with the following decisions:
You splitting the line using as separator the space (i.e explode() )
The pattern I can see is that there exist a time of the form xx:xx exactly before the actual file/directory ! So you can check if the current line is a valid 24-based time using a regular expression then that means if that is the case and you are in the $i position of the array the $i+1 is what you are looking for, and therefore you can copy that to a new array.
Repeat
I think that is a bit pain, but at least is a solution.

PHP exec very slow processing simple 3-pipe grep

I've read here and cannot really understand how to speed up my simple exec() which basically looks like this:
zcat access_log.201312011745.gz | grep 'id=6' | grep 'id2=10' | head -n10
I've added ini_set('memory_limit', 256); to the top of the PHP document, but the script still takes about 1 minute to run (contrasted with about near instant completion in Penguinet). What can I do to improve it?
I would try some of the following:
Change your exec to just run somethig simple, like
echo Hello
and see if it still takes so long - if it does, the problem is in the process creation and exec()ing area.
If that runs quickly, try changing the exec to something like:
zcat access_log.201312011745.gz > /dev/null
to see if it is the "zcat" slowing you down
Think about replacing the greps with a "sed" that quits (using "q") as soon as it finds what you are looking for rather than continuing all the way to end of file - since it seems (by your "head") you are only interested in the first few, not all occurrences of your strings. For example, you seem to be looking for lines that contain "id=6" and also "id2=10", so if you used "sed" like below, it may be faster because "sed" will print it and stop immediately the moment it finds a line with "id=6" followed by "id2=10"
zcat access_log.201312011745.gz | sed -n '/id=2.*id2=10/p;q'
The "-n" says "don't print, in general" and then it looks for "id=2" followed by any characters then "id2=10". If it finds that, it prints the line and the "q" makes it quit immediately without looking through to end of file. Note that I am assuming "id=2" comes before "id2=10" on the line. If that is not true, the "sed" will need additional work.

Return ranges of lines from text file PHP or LINUX

I have a small issue here, I need to be able to read a file of unknown size it could be a a few hundred lines or many more the log files change all the time and depending on when i check. I would like to have a method that is in php or in linux that i can read a range of lines from a file. I dont want to have to read the entire file in to php memory then remove the lines because the file may be larger then the allowed memory of php.
I also want it to be using default php modules or default linux tools dont want to need to install anything because it needs to be portable.
Edit:
For the linux based options I would like to be able to supply more then one range, i may need to get a few different ranges of lines I know how to do it in php by not in linux and to avoid reading past lines i have already read?
With awk:
awk 'NR>=10 && NR<=15' FILE
With awk (two ranges):
awk 'NR>=10 && NR<=15 || NR>=26 && NR<=28' FILE
With ed:
echo 2,5p | ed -s FILE
With ed and two ranges :
echo -e "2,5p\n7,8p" | ed -s FILE
Last but not least, a sed solution with two ranges (fastest solution, tested with time):
sed -n '2,5p;7,8p' FILE
What about something like
head -100 | tail -15
gives you lines 86-100
$ cat input.txt
q
w
e
r
t
y
u
i
$ sed -n 2,5p input.txt
w
e
r
t
while ($lines_read < last_line_desired) {
while ($line = fgets($filehandle, $buffersize) !== false)
if (line >= first_desired_line) {
push($interesting_lines, $line)
}
}
$lines_read++
}
Opening the file handle, selecting the appropriately large enough buffer size to cover any expected line lengths, etc. is up to you.
If you're reading files that are regularly appended to, you should look into the ftell and fseek functions to note where you are in your data and skip past all the old stuff before reading more.

Software to document code?

I need to document and create a list of variables in my code as part of my A Level computing coursework, however my PHP script is over 6,000 lines in total.
Does anyone know of any software that will display a list of variables within my code? I really don't feel like going through all of my code and hand-picking out about a thousand variables :(
Thanks in advance.
PHP's tokenizer allows you to parse the script and could be used to pick out all the variables defined/used
In PowerShell this would be quite trivial:
Select-String '\$[\w_]+' foo.php -AllMatches |
Select-Object -ExpandProperty Matches |
Select-Object -Unique -ExpandProperty Value
or shorter:
sls -a '\$[\w_]+' foo.php|%{$_.Matches}|select -u -exp Value
Adapt accordingly for Perl, sed, or whatever you like to use. The basic idea would be the same.
Depending on how detailed you need to be, Xdebug might be useful here.
You should also look into the Reflection classes: http://php.net/manual/en/book.reflection.php Writing something up using Reflection would give you control over the output.
$ grep -oh "\$[a-zA-Z_]*" file.php | sort | uniq
or
$ grep -R -oh "\$[a-zA-Z_]*" src_dir | sort | uniq

How to make the linux/macOS command " .ls >> files.txt " run at php using exec()?

I Just wanna to list all files and subdirectories and store this list in file ...
in MS-DOS, Linux and MAC OS, the command line -- .ls( or .dir) >> files.txt -- would give me what I want ...
But, how to make a php script run it ?
if I use (on php)
exec ('ls >> files.txt');
I will get a error like this:
Warning: Unexpected character in input: '' (ASCII=28) state=0 in /Applications/XAMPP/xamppfiles/htdocs/DjUtilities/makeLabels.php on line 29
...
please, any idea ???
The use of this will be to set labels with the musics in a cd, here, divided by directories...
I wanna to get any cd's (subdirectories) and list the files (the tracks) to make a label with the track list....
So, The initial idea was to create a file with these data and then, process the data to make the labels... any better way to do that will be very welcome !!
You can use 'opendir' and 'readdir' to do that, both native php commands...
It's not up to your 'exec(...)' code. Same code runs well in my environment.
<?php
exec('ls >> filelist.txt');
?>
And It's result.
$ cat filelist.txt
a.html
a.out
...(omitted)
So, It looks like your php file may has some weird syntax/characters on line 29. ( like wrong usage of backslashes )

Categories