View Full Version : PHP loops?
darkspark
04-05-2012, 06:55 PM
Hiya guys, I need some help with the following script.... I'm trying to get a code which will tell you the right word to represent each letter of a variable entered into a text box... look at the code below. I've managed to get it to display the first letter, but need some assistance to get the code to loop, onto the second letter and so forth... can anyone help?
<form method="post">
<tr align="left">
<td><label for="text">Enter text: </label></td>
<td><input name="text" type="text" class="widebox" id="text" /></td>
</tr>
</tr>
<input type="submit" name="Select" title="Phonetify" value="Phonetify"/>
</form>
<br /><br />
<?php
$var =$_POST['text'];
echo '<strong>'.$var.'</strong> will become the following phonetically. <br /><br /> ';
if ($var[0]=='a')
echo "Alpha<br />";
elseif ($var[0]=='b')
echo "Bravo <br />";
elseif ($var[0]=='C')
echo "Charlie <br />";
elseif ($var[0]=='D')
echo "Delta <br />";
elseif ($var[0]=='E')
echo "Echo <br />";
elseif ($var[0]=='F')
echo "Foxtrot <br />";
elseif ($var[0]=='G')
echo "Golf <br />";
elseif ($var[0]=='H')
echo "Hotel <br />";
elseif ($var[0]=='I')
echo "India <br />";
elseif ($var[0]=='J')
echo "Juliet <br />";
elseif ($var[0]=='K')
echo "Kilo <br />";
elseif ($var[0]=='L')
echo "Lima <br />";
elseif ($var[0]=='M')
echo "Mike <br />";
elseif ($var[0]=='N')
echo "November <br />";
elseif ($var[0]=='O')
echo "October <br />";
elseif ($var[0]=='P')
echo "Papa <br />";
elseif ($var[0]=='Q')
echo "Quebec <br />";
elseif ($var[0]=='R')
echo "Romeo <br />";
elseif ($var[0]=='S')
echo "Sierra <br />";
elseif ($var[0]=='T')
echo "Tango <br />";
elseif ($var[0]=='U')
echo "Uniform <br />";
elseif ($var[0]=='V')
echo "Victor <br />";
elseif ($var[0]=='W')
echo "Whisky <br />";
elseif ($var[0]=='X')
echo "Xray <br />";
elseif ($var[0]=='Y')
echo "Yankee <br />";
elseif ($var[0]=='Z')
echo "Zulu <br />";
?>
weegillis
04-06-2012, 07:53 PM
First, create an array containing all your data, using the letters as keys:
$STACK = array(
'A' => 'Alpha',
'B' => 'Bravo',
'C' => 'Charlie',
'D' => 'Delta',
'E' => 'Echo',
'F' => 'Foxtrot',
'G' => 'Golf',
'H' => 'Hotel',
'I' => 'India',
'J' => 'Juliet',
'K' => 'Kilo',
'L' => 'Lima',
'M' => 'Mike',
'N' => 'November',
'O' => 'October',
'P' => 'Papa',
'Q' => 'Quebec',
'R' => 'Romeo',
'S' => 'Sierra',
'T' => 'Tango',
'U' => 'Uniform',
'V' => 'Victor',
'W' => 'Whiskey',
'X' => 'X-ray',
'Y' => 'Yankee',
'Z' => 'Zulu',
);
function something() {
global $STACK;
$result = "";
// some form of input controlled loop to gather all characters, maybe?
// Truncate the POST string to only the first alpha character, case insensitive.
// regex and replace leading spaces and non-alpha characters with ""
$var = preg_replace("/[^a-z]/i", "", $var);
// first character and force it into uppercase
$var = strtoupper(substr($var, 0, 1));
// Now traverse your index for a match and return the callout:
$result .= alphaToCallout($var) . ", ";
// get another character, keeping $result alive
.
.
.
};
function alphaToCallout($post) {
global $STACK;
foreach ($STACK as $alpha => $callout) {
if ($post == $key) return $callout;
};
};
Not tested, so might need tweaking. Let us know if this helps.
darkspark
04-07-2012, 11:54 AM
I have to be honest with you Gillis, I don't have a clue about what you just typed there, beyond your notes. That being said, here's the challenging part... it doesn't work if I replace what i have with the code you wrote... I get the following
( ! ) Parse error: syntax error, unexpected '.' in C:\wamp\www\Phonetify\Copy of index.php on line 117
The error is appearing in the following section that you've wrote ..
// get another character, keeping $result alive
.
.
.
};
weegillis
04-07-2012, 02:49 PM
The 'function something()' part is not run-able code, but 'thought balloons'. That's why it won't parse. It's not syntactically correct. The big hints would be the open dots representing a vertical ellipses, which are not commented out, and would throw an error in the PHP parser. Also note that the foreach() above is incorrect, I have $key instead of $alpha in the code. Apologies...
Let's break it down to what is syntactically correct:
1) the array.
2) the function, alphaToCallout() (once the correct variables are applied)
The function, something() is one you would have to sort out depending upon how the input is to be handled:
a. One character at a time; or,
b. One word at a time; or,
c. A complete phrase, including spaces, in which case the filter would need to be modified to include spaces (that are not leading or trailing).
For situation a., the $_POST['text'] will be truncated to the first alpha character, as above. In this example, we need to assume that the user may send more than one character; ergo, taking the time to pare it down and pound it into the right form:
// submitted POST comes in and is sampled, 'text' being the attribute value in the input form control, name="text".
$var = $_POST['text']
$var = truncSubmit($var);
if ($var) {
echo alphaToCallout($var);
} else {
echo "No alpha character found.";
}
// end
function truncSubmit($post) {
$post = preg_replace("/[^a-z]/i", "", $post);
if (!$post) return;
return strtoupper(substr($post, 0, 1));
};
function alphaToCallout($post) {
global $STACK;
foreach ($STACK as $alpha => $callout) {
if ($post == $alpha) return $callout;
};
};
If the user submits, " .* abcde ", the above renders it as "A". We test for NULL in two places, before calling truncSubmit(), and before calling alphaToCallout(). No point running the procedures if there is nothing to work with. This is obviously the simplest and most straight forward.
It would be a pain for the user to have to submit one letter at a time, and real pain to set up the loop to return to the form, over and over, so if you wish to allow the user to enter a word, or phrase, then some tweaks on the filter will be needed, and you will need a PHP callback function for your AJAX to communicate with if you want real time response as the user types. This is above the scope of this discussion, at present, so we'll stick to one Submit, one word, or one Submit, one phrase and operate on the returned 'text'.
For a single word, the preg_replace() will need to, a) remove leading spaces; and b) find the first word separator (space) in the event the user submitted a phrase.
You would then set up a loop, after first distributing all the word letters in an array, parsing through the array one element at a time, and passing the content to alphaToCallout(). This is where the $result variable comes in. We will concatenate each returned callout word to the string, and echo the final $result upon completion of the loop.
For a phrase, the preg_replace will need to, a) remove leading and trailing spaces; and b) breakout the individual words and store them in an array (perhaps), or simply do as above, pushing the results into an array with one character per element, including the spaces between the words.
We would need a loop again, minding that "" or " " will return nothing, so we need to catch the spaces, add them to the $result, and jump to the next element.
Each of these last two conditions makes things a bit more complicated, so I would get the spit and polish on the single character method, first, then move on to making your method smarter (by adding new functions, not modifying the ones you have that work for their scenario).
weegillis
04-07-2012, 04:31 PM
The array is not correct... there should not be a comma after 'Zulu'. This will throw an error.
weegillis
04-07-2012, 05:38 PM
Since I opened this up, it might be best to offer a prototype for you to work from. This is a working example in its simplest form.
<?php
$STACK = array( 'A' => 'Alpha','B' => 'Bravo','C' => 'Charlie','D' => 'Delta','E' => 'Echo','F' => 'Foxtrot','G' => 'Golf','H' => 'Hotel','I' => 'India','J' => 'Juliet','K' => 'Kilo','L' => 'Lima','M' => 'Mike','N' => 'November','O' => 'October','P' => 'Papa','Q' => 'Quebec','R' => 'Romeo','S' => 'Sierra','T' => 'Tango','U' => 'Uniform','V' => 'Victor','W' => 'Whiskey','X' => 'X-ray','Y' => 'Yankee','Z' => 'Zulu' );
function truncSubmit($post) {
$post = preg_replace("/[^a-z]/i", "", $post);
if (!$post) { return NULL; } else { return strtoupper(substr($post, 0, 1)); };
};
function alphaToCallout($post) {
global $STACK;
foreach ($STACK as $alpha => $callout) {if ($post == $alpha) return $callout; };
};
$var = ($_POST['text']) ? $_POST['text'] : NULL;
if ($var) {
$sent = truncSubmit($var);
if ($sent) { $result = alphaToCallout($sent); } else { $result = "No POST data"; };
} else { $sent = "No POST data"; };
?>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>A to Alpha .. Z to Zulu</title>
<meta name="description" content="a method to generate callouts from alpha characters">
<style>textarea{display:block}</style>
</head><body>
<form method="post" action="index.php">
<input type="text" name="text" autofocus="autofocus">
<input type="submit" value="Send">
<textarea disabled="disabled"><?php echo "Sent: $sent\nResult: $result\n"; ?></textarea>
</form></body></html>
weegillis
04-08-2012, 08:23 PM
As is often the case, I learn more than anyone from these exercises, or am often left to assume as much due to lack of discussion afterward. However, it does give me pleasure to spend a holiday weekend 'not working' but 'working' on something fun and interesting, as this little project turned out to be.
I hope the OP is able to gain some insight from this, and that he has no intention of repeating this in an assignment (the prof will find it here) without being able to fully explain and document it, if asked. Copy and paste is no way to learn programming of any sort, least of all, PHP scripting. We get the most gains when we dirty our own hands.
That said, here is the Multi-word Phrase version of the above, single character NATO Phonetic Converter.
<?php /* Multiword Phrase NATO Phonetic Converter by RC Pierce 2012-04-08 */
$STACK=array('A'=>'Alpha','B'=>'Bravo','C'=>'Charlie','D'=>'Delta','E'=>'Echo','F'=>'Foxtrot','G'=>'Golf','H'=>'Hotel','I'=>'India','J'=>'Juliet','K'=>'Kilo','L'=>'Lima','M'=>'Mike','N'=>'November','O'=>'October','P'=>'Papa','Q'=>'Quebec','R'=>'Romeo','S'=>'Sierra','T'=>'Tango','U'=>'Uniform','V'=>'Victor','W'=>'Whiskey','X'=>'X-ray','Y'=>'Yankee','Z'=>'Zulu');
$NPD = "No POST data";
function postFilter($post) {
$post = preg_replace("/^[ ]+|[^a-z ]|^[ ]+$/i", "", $post);
if (!$post) return NULL;
return strtoupper($post);
};
function postSplit($post) {
$postChars = array();
$postChars = preg_split('//', $post, -1, PREG_SPLIT_NO_EMPTY);
return $postChars;
};
function alphaToPhonetic($post) {
global $STACK;
foreach ($STACK as $alpha => $phonetic) { if ($post == $alpha) return $phonetic; };
};
function wordToPhonetic($posts) {
$result = "";
foreach ($posts as $index => $letter) { $result .= "\n" . alphaToPhonetic($letter); };
return $result;
};
$var = ($_POST['text']) ? $_POST['text'] : NULL;
if ($var) {
$sent = postFilter($var);
if ($sent) {
$sentChar = substr($sent, 0, 1);
if ($sentChar) { $charResult = alphaToPhonetic($sentChar); } else { $charResult = $NPD; };
if (strlen($sent) > 1) { $charResults = wordToPhonetic(postSplit($sent)); } else { $charResults = $charResult; };
} else { $sent = $sentChar = $NPD; };
} else { $sent = $sentChar = $NPD; };
?>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Multiword Phrase NATO Phonetic Alphabet converter</title>
<style>textarea{width:400px;height:300px}</style></head><body>
<form method="post" action="index.php">
<input type="text" name="text" autofocus="autofocus" size="50">
<input type="submit" value="Send"><br>
<textarea disabled="disabled"><?php echo "Sent: $sentChar\nResult: $charResult\n"; ?></textarea>
<textarea disabled="disabled"><?php echo "Sent: $sent\n>> $charResults\n"; ?></textarea>
</form></body></html>
weegillis
04-09-2012, 07:18 AM
@darkspark, one hopes that you have seen that your original question was answered in this loop, the $STACK array notwithstanding:
function alphaToPhonetic($post) { global $STACK; foreach ($STACK as $alpha => $phonetic) { if ($post == $alpha) return $phonetic; }; };
Every one of the stack of if()'s you asked in the OP is answered here, in this loop. The part that may be difficult to grasp is that we are cycling through an associative array, not an indexed one and we are not working from the post response array, but a sample of the one variable in it that we care to take note of ($_POST['text']).
We have constructed our array as one of KEY associated with VALUE, and use FOREACH() to break out the cells. This is an IMPLICIT loop which does not need an upper bound pre-declared. When it runs out of keys, it terminates itself. The method is a little bit abstracted from the normal FOR loop, and requires us to place our mind at the abstract level. Get used to doing this and you'll never have trouble with associative arrays, or the loops we use to cycle through them.
In our example, we only loop through the array as far as we must, and our software has already pre-qualified the input as an uppercase letter so we know there WILL BE a return. The letter 'z' will require 26 loops but 'f' only 6 whereupon the phonetic from the array is returned. As loops go, this is known as a logical breaking point. Luckily for us, there is a RETURN, else this 'point' would require an arbitrary BREAK to terminate the loop.
As mentioned in my earlier theorizing and preamble, the word version would be more complicated. As it turns out, only another FOREACH() loop. Now we get to see the power in our first loop. We call it over and over again in our second. Notice that as mentioned earlier, we have constructed an array of letter cells so that both loops when carried out, yield a conglomerate of single letter results.
darkspark
04-09-2012, 12:52 PM
Seriously weegillis, thank you for the time that you've invested in this. Like I said you did lose me, and I'm gathering my thoughts about the text that you have given within explaining the code that you've put forth, but I feel as though you've over estimated my php programming abilities...
Any advice on which php book/s I should have a good read through for learning and developing any future skills I hope to possess in PHP?
Thank you again.
weegillis
04-09-2012, 04:56 PM
It can get that way, lots, where I'm thinking a method is straight forward and transparent and the next person is scratching their head as if trying to look through a mirror, nothing transparent about it. My apologies if this is throwing you for a loop (pun intended).
I just now realized that you have a page up already. Is the code in your OP the same as what's behind that page? I would be interested to see what you have at present. As you can see, our version above has a lot more horsepower than what I imagine is running on your page. If you happen to use this, please leave in the attribution so it doesn't look like you wrote it yourself.
The OP approach of traversing a tree of if/then may work, but it is incredibly CPU intensive, since it contains so many iterations of 'echo', which is a resource hog. It is also not very compact owing that all the string constants are embedded in the code. You can see for yourself how compact our version above is, and there are virtually no limits on the input phrase, though one might want to impose one within reason.
Two of many ways to skin a cat. Both work, but we can see how different they are in their approaches. Everybody will take a different angle of approach, depending upon, a) their skill set, b) how well they understand the problem needing to be solved, and c) their ability to visualize and reason before pen hits paper. There is very little that is rote about any programming or scripting language. We need all three above to a certain degree in solving even the simplest problem.
I learned, and am still learning basic PHP one problem at a time. My biggest resource has always been the PHP manual on their site. W3 Schools also has a lookup guide for basic syntax and usage. You could turn to SitePoint, who have through the years published a handful of PHP related books:
PHP related products (http://products.sitepoint.com/?tag=&filters%5Btag%5D%5B%5D=php&filters%5Bdifficulty%5D=&simpleform_submit_marker=showme).
There are others that have been mentioned in threads in the past. @kgun has mentioned some, so if you don't mind a little digging, you may track down some of his posts relating to PHP. As books go, they can only tell you so much. It's all rote until we start getting our hands dirty. That's when the practical learning starts to set in.
The toughest part I find for most people is the 'sticking to it' part. They find a solution, see that it works, and accept it as is and move on. This is not how we learn programming, even if it does work. Every solution can be made more compact, more efficient, more elegant, more powerful, more... IF we stay with it and come round and round again, each time approaching from a slightly different angle. Eventually, in time, we build up our own understanding and resource kit of ideas and methodologies.
Even to an experienced programmer (that's not me by the way, I'm a hobbyist) the solution seldom just falls out onto the page. We think about the problem, propose a solution, write something and try it, tweak it, try another method, think on it some more, each time gaining more intimacy with the problem, and each step along the way refining our solution until we hammer it into a solid piece of software. Our example above is about as solid as one can get it, but I bet there are even still some improvements that can be made.
As you will have noted, in the early discussion on this thread all we did was look at the problem, and visualize the steps that would be involved to arrive at our desired solution. The method falls out from there, and depending on how well the problem has been thought through, our first attempt might work just fine. Going for a finished product off the bat is just not practical. We first need something that works, then we need to make it smarter by setting up error traps that prevent errant data from slipping in, or being returned in our results. The finished product seldom looks like what we first come up with, and nothing gets improved if we don't always challenge ourselves to seek ways to improve it.
weegillis
04-10-2012, 12:08 AM
Found this by searching, examples of program loops (https://www.google.ca/search?q=examples+of+program+loops), where the top result, though probably very old, is exactly what I wanted: Loop Examples (http://www.cs.utexas.edu/~porter/cs304p/Practice/loops.html).
Notice right off the top the two main categories: Count controlled, and Event controlled. The language is not PHP, but a close look will reveal the salient information on how each type of loop within these categories works, and how it is controlled.
In old BASIC speak, the simplest loop was, 10 GOTO 10. This one is the best example of an uncontrolled loop. A common use of this line was a listening post. Event listeners would trap events on the screen, the keyboard or the mouse and execute their toolbox code, but in the meantime, the program would just hang out at line 10, to which it would return after every event is handled.
More elaborate examples can be drummed up, like a non-terminating slide show, or a repeating sequence of sampled music. Uncontrolled loops are also called 'infinite' in that they have no predefined end. They stop when the program stops. We definitely don't want any of these in a our PHP scripts or the page will never load, and the hosting provider will get mighty upset if it crashes their server.
This is where controlled loops come in. We set strict limits, sometimes referred to as lower and upper bounds, when counting, or structure our data so that an end of file event occurs (such as above in the FOREACH() that PHP provides us) and forces an exit from the loop. We can also set exit conditions within a loop, which lets us minimize the clock ticks consumed by the server while executing it. We do that above, as well. Remember Z and F?
Just so we're clear, there is no one loop that is best for all purposes. With time and practice and experimentation/invention you will set upon a choice of loop method best suited to the task at hand and the type of data being crunched.
A simple counting loop (without employing actual loop functions within the given language) is, again in BASIC speak,
10 A=0
20 B=100
30 A=A+1
40 IF B-A=0 THEN END
50 GOTO 10
Here is a simple PHP counting loop
$a = 0;
$b = 100;
do { $a++; } while ( $a < $b );
echo $a . ", " . $b;
One loop function built into most languages that keep all the controls in one place is the FOR() loop. In BASIC, this used to be a FOR TO STEP NEXT loop but languages evolved that led to C which led to PHP, which give us a more elegant, FOR(). Here is one that loops through what we have above:
for ( $i = 0, $n = 100; $i < $n; $i++) { // do something }
We can already see a difference in these two loops. In the former, the increment was the action within the loop, whereas in the latter, the increment is handled by the control expressions defined by the for() arguments, leaving the 'workspace' completely free of control variables, save a possible event trap that causes an exit. The code within the workspace will execute once for every increment of the control variable, just as above and will terminate when it reaches the upper bound.
When working with one dimension arrays in PHP, the for() loop works great. It cannot equal the power of the foreach() loop when it comes to more sophisticated array structures (keyed indexes and arrays within array cells), though. While examining this language function, it will be good to immerse oneself in ASSOCIATIVE ARRAYS. They can be very confusing at first, and a clear understanding is necessary in order to properly understand and implement these loops with success. If you are familiar with JavaScript basic objects--Property : Value, then you will catch on quickly to, $key => $value.
It gets hairy when $value is an array, also. But as a single dimension, this one can be parsed using for() or foreach() again, either one nested in the main foreach(). But now I'm getting ahead of things. You will not find the code in our example above very difficult to grasp once you envision the workings of the two main loops. The only other abstracts in the code are the REGEX used in the PREG_REPACE() function, and the construction of our letter array with PREG_SPLIT(). Both of these functions require thorough reading, which you will benefit from immensely.
The string functions are pretty self explanatory, but they deserve a good reading up on, too. They are an important part of the engine, after all. Just as a fuel filter removes unwanted particles from gasoline before it reaches the injection system, our filter removes unwanted characters and forces the remainder into uppercase. The substr() function grabs the first character of the string, regardless of length. Just studying the basic PHP functions in our example enough to understand it, will open up on dozens of ways to use just these functions in powerful ways. Just remember, your PHP is not a program, it is a script, and must terminate at some point or the page will never be returned to the client.
As loops go, you'll notice that our example is an infinite loop. It keeps requesting the same page, which is both form control and handler rolled into one, just as yours is. Let me know how you're making out, and if you wish to continue this discussion about loops, bring it back here. Other PHP topics will need to be in a new thread, though, since this one is about PHP loops.
darkspark
04-11-2012, 05:35 PM
Awesome work weegillis, I'm reading through things and the explanations are helpful but I have to admit that it's the examples you're giving which I like the most. I do have to admit that I am little lost from time to time with this information, but if you want to continue this, you can by all means keep posting in this thread or if you want to add me on Skype/msn I'd love to keep learning from you.
As for the code I have running on the website, well I got it running before you posted your original reply, with a terribly heavy piece of code which is a repetition of the original if statement. No loop involved so the code it self is about 600 lines long.... like I said terrible but it works. I can see that your code works, but will not use it because it is your code in the end, and you have full rights to that. I honestly think I need to read up on arrays and loops across a few resources and perform a few examples so I can gain a good foot in the knowledge that is required.. effectively the reason I'm trying to learn this information is because I'm trying to create a bigger project, but I don't as of yet have the skillset to complete the project and require some learning to be done.
Like you did say though, and I completely agree with you, if I understand correctly. You start from point A, and then with what you have developer or are developing, you should continue to progress as there is always another way to tackle the coding issue at hand, and by taking a new point of view you're able to discover more efficient ways to progress and innovate.
PM me if you want to discuss some further subjects on Skype or MSN, I could use a few coders/hobbyiest coders in my contacts as it will allow for me to have further discussions and bounce ideas off. Also how long have you been learning php for?
weegillis
04-11-2012, 10:07 PM
In my opinion, you should use the code in post #7, with attribution in an HTML comment so it shows in the page source. If you want to include a URL in the comment, just point it tenfingers dot net/tools/atoalpha/. This is my working version. The one in post #7, is wpwversion.php at the same URL.
Assuming you are going to be expanding the site to include other widgets (which this example could be known as) then keeping the PHP resources separate from HTML pages and templates so they can be re-used by all the documents on your site, not just the one page... would be good idea.
The PHP above, would fall into the category, 'methods and modules' as there is no page generation involved, only data crunching or retrieval. The 'methods' (script procedures) include the functions along with the procedure starting with $var=. The 'modules' (what I call them) are the predefined array, $STACK, and, $NPD, defined as the string constant, "No POST data". Both of these are known as 'statements' in PHP. Since they have no closure (they are not contained within a function) their scope is global, meaning any function or method can call upon them. In our example, we can see that the main method is also without closure, so it too executes within the same scope as our global CONSTANTS and the statements that defined them. Anyway, this is getting away from things...
index.php
<?php require_once "library.inc"; ?>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Multiword Phrase NATO Phonetic Alphabet converter</title>
<meta name="description" content="A PHP method to convert alphabet letters to their NATO phonetic callout">
<style>textarea{width:400px;height:300px}</style></head><body>
<form method="post" action="index.php">
<input type="text" name="text" autofocus="autofocus" size="50">
<input type="submit" value="Send"><br>
<textarea disabled="disabled"><?php echo "Sent: $sentChar\nResult: $charResult\n"; ?></textarea>
<textarea disabled="disabled"><?php echo "Sent: $sent\n>> $charResults\n"; ?></textarea>
</form></body></html>
library.inc
<?php /* Multiword Phrase NATO Phonetic Converter by RC Pierce 2012-04-08 */
$STACK=array('A'=>'Alpha','B'=>'Bravo','C'=>'Charlie','D'=>'Delta','E'=>'Echo','F'=>'Foxtrot','G'=>'Golf','H'=>'Hotel','I'=>'India','J'=>'Juliet','K'=>'Kilo','L'=>'Lima','M'=>'Mike','N'=>'November','O'=>'October','P'=>'Papa','Q'=>'Quebec','R'=>'Romeo','S'=>'Sierra','T'=>'Tango','U'=>'Uniform','V'=>'Victor','W'=>'Whiskey','X'=>'X-ray','Y'=>'Yankee','Z'=>'Zulu');
$NPD = "No POST data";
function postFilter($post) {
$post = preg_replace("/^[ ]+|[^a-z ]|^[ ]+$/i", "", $post);
if (!$post) return NULL;
return strtoupper($post);
};
function postSplit($post) {
$postChars = array();
$postChars = preg_split('//', $post, -1, PREG_SPLIT_NO_EMPTY);
return $postChars;
};
function alphaToPhonetic($post) {
global $STACK;
foreach ($STACK as $alpha => $phonetic) { if ($post == $alpha) return $phonetic; };
};
function wordToPhonetic($posts) {
$result = "";
foreach ($posts as $index => $letter) { $result .= "\n" . alphaToPhonetic($letter); };
return $result;
};
$var = ($_POST['text']) ? $_POST['text'] : NULL;
if ($var) {
$sent = postFilter($var);
if ($sent) {
$sentChar = substr($sent, 0, 1);
if ($sentChar) { $charResult = alphaToPhonetic($sentChar); } else { $charResult = $NPD; };
if (strlen($sent) > 1) { $charResults = wordToPhonetic(postSplit($sent)); } else { $charResults = $charResult; };
} else { $sent = $sentChar = $NPD; };
} else { $sent = $sentChar = $NPD; };
?>
Be sure to remember that the main method is without closure, and will execute every time this resource is called. To control 'when' it runs requires giving it closure within a function, or only including the resource when it is needed. For now, we are fine, but if you begin adding modules to this library, things might have to change.
Why .inc? Again, arbitrary. I use .inc to signify m&m's. They are includes, so .inc works fine for me. The truth is it doesn't matter what you use for an extension on a PHP include file, as long as it's not an already defined extension or MIME type that the server has built in methods for handling. Unless configured, .htm, .html, among others, will not be parsed for PHP by the server.
Notice the 'require_once' statement, above? This is how we attach the PHP to the HTML document. Now you may wish to keep your library out of the way, where it's safe. You can do this by creating a folder called 'includes' (again, arbitrary) and store the file in there. Your statement would then read, 'require_once "includes/library.inc";'
I won't get into now, but you should know there are some real gotchas when traversing directories in PHP. Everything is happening in real time on the server, and if includes contain references to other resources, the location of the include file is focal to how the path is constructed pointing to those resources. Read up on getcwd() and other topics relating to Current Working Directory. Our example will work if you store it away in a folder, so not to worry. This would be the recommended approach.
Last thing of note to this post... The markup is HTML5. As you can see, it is still HTML, just slimmer, and a lot more semantic. In our example there is nothing really that sets it apart from a normal HTML page, so I'll list the few things that are different: No type attribute on STYLE or SCRIPT; No long doctype; no Content-type or Language. I use HTML 4 markup, not XHTML, but both are valid, so pick one and stick with it or your pages will look in disarray.
weegillis
04-11-2012, 11:34 PM
Note: PHP is compatible with all versions of HTML. You can import the library into your existing page, no real changes required. Our example populates a TEXTAREA, but needn't be confined to that form of display. Just set the echo statements where they belong in your page. Give the output some style with CSS and you're done like dinner. Cheap and dirty! Just like that.
Which is why I love PHP, even the elementary level that I'm at. Same goes for CSS. Every piece of code I have ever written was a solution to something--ultimately taking the leg work out of, or adding horsepower to repetitive tasks, aka., TAGGING and LOOKUPS. We have a web server that will do all the heavy lifting for us if we just give it a working set of instructions.
We feed in data and PHP outputs it how we like, tagged up and ready to go. New data? No problem. The page handles whatever is thrown at it. Want to add an ALPHA BETA list, or one with xylophone instead of x-ray, just add a set of buttons or a SELECT control to the page. The action value could be a hash (if AJAX request) or a query string (page request) with the name of the alternate data set. Park the array data in a database (CSV, even) and load any number of different data sets into the one declared array. At the click of a button. And no core procedures ever need to be changed. We just add methods and modules to our library.
You do realize that I am not a programmer, so you will of course take everything with a grain of salt. I am sharing amateur experience. Different from expert knowledge, but no less useful. One in our position will do best when we never allow ourselves to be so impressed that we don't question. This is where the learning is. Peer into a thing and make sure that it does what YOU want it to, and understand HOW it is doing it so you can CONTROL it.
Without control, a script is an easy thing to exploit, and so becomes a security risk. We both have a lot to learn about security, and if I'm saying that to you now, after four years of hobby time spent on PHP solutions, then you know YOU don't know enough, because I presumably know more than you and I don't know very much at all.
What I know is that valid input yields valid output (just saying) so making sure that all input is filtered and no wrenches get drawn in, is the first step in making sure that exploit code never gets through. All I know is it is first up to me to check for all errant data (form variables) coming from all form controls, especially TEXT.
Our procedure above is fairly secure because it filters, then funnels the results through an inducer. The actual data never gets through, only the induced (stored) data. The postSplit() function pretty much destroys the original data, only to force its output through the inducer. But, hey! I could still be very disillusioned. Like I said. We both have a lot to learn about security.
See what you can come up with by way of storing the data on disk, and retrieving it by data set into a page request. Most of the clues are already there, or discussed partially in my last post and this one.
weegillis
04-13-2012, 04:18 AM
I can't think of a more perfect example of raw lookup and tagging in one method. This is a page that can be dropped into any folder containing images (careful not to overwrite the index.php page, if there is one, otherwise use a different name) and the page displays all images tagged with width, height, alt and title attributes, scaled to fit the current viewport, along with links to view the full size image.
There are two loops, one to query the folder, and one to generate the image links. We first store the results of the folder query in an array, then we parse through the array, full knowing that only images are listed, and create our HTML from the data in each record.
Very powerful, and all it takes is dropping the index.php into a folder and there you have it.
Your next assignment will be to make this a portable file, so individual pages can call upon it, and you only have one copy of it in the includes folder.
Give it a whirl...
<?php
$img_handle = array();
if ($handle = opendir('.') ) {
while (false !== ($file = readdir($handle) )) {
if (stristr($file, '.jpg') || stristr($file, '.png') || stristr($file, '.gif')) {
$img_handle[] = $file;
};
};
closedir($handle);
};
sort($img_handle);
$str = " <table>\n";
$count = 1;
foreach ($img_handle as $key => $v) {
$i= stristr($v, ".");
$j = $i - 4;
$k = substr($v, 0, $j);
$f = filesize($v);
$m = date ("F d Y", filemtime($v));
list($w,$h) = getimagesize($v);
if ($w>0) {
$xw = (512 / $w < 1) ? 512 : $w;
$yh = ($xw==$w) ? $h : (512 / $w) * $h;
};
$img = "<img src=\"" . $v;
$img .= "\" width=\"" . $xw . "\" height=\"" . $yh;
$img .= "\" alt=\"" . $k . "\" title=\"" . $m . " : " . $w . "x" . $h . " : " . ((int)($f/1024) + 1) . "KB\">\n";
$hrf = "<a href=\"$v\" title=\"View $k in this window\">$v</a>";
/* in lightbox
$hrf = "<a href=\"$v\" title=\"Open $k in Lightbox\" rel=\"lightbox1\">$v</a>";
*/
$str .= " <tr><td>$count</td><td>$img</td><td>$hrf</td><td>$m</td></tr>\n";
$count = $count + 1;
};
$str .= " </table>\n";
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<tile>image inspector</title>
<meta name="robots" content="noindex,nofollow">
<style>
table#dir{width:100%;border:none;}
table#dir td{width:25%;text-align:left;border:none;}
table#dir td:nth-child(1){width:5%;}
table#dir td:nth-child(2){width:50%;}
table#dir td:nth-child(3){width:10%;}
table#dir td:nth-child(4){width:35%;}
</style>
</head>
<body>
<div>
<h1 style="font-size:smaller;"><?php echo getcwd(); ?></h1>
<?php echo $str; ?>
</div>
</body>
</html>
weegillis
04-13-2012, 04:52 AM
We can use str_replace() to shorten the current directory printout to just site path and folder:
<h1><?php echo str_replace('/this/that/public_html/','',getcwd()); ?></h1>
Of course the this and that, and maybe even public_html are just placeholders for what you're seeing from your server. You get the idea. This is another string function to acquaint yourself with.
In time you might begin to notice performance issues if your code gets CPU intensive. There are a gazillion ways to do things, but many clock up a lot of ticks. Optimizing your PHP to the task at hand is the way to keep these clock ticks down. The str_replace() function is one example of conserving energy. Read up some more on this, for sure.
weegillis
04-13-2012, 06:04 AM
Oh, yeah, the assignment thing was a gag, but if you wanted a hint..., break up the PHP from the HTML and require the PHP include. After that, style the heck out of your HTML output and you have a page, anywhere.
<edit>
Remember we spoke about 'portable'? The above T&L can be dropped into any layout, not just directly as a stand alone page. The salient parts can be inserted into any predefined page. Then again, portable layouts and php loops are a bit far aflung. Just worth noting.
</edit>