I'm trying to learn some PHP and have something I've got quite stuck on.
I'm using SOAP. Is it possible for me to match a word to what's in the array and then output a the number of times that word was displayed in the array?
I currently have this which outputs what I want to match to, but I can't seem to find a way to show how many times a word appears.
$facilities = $message->Facilities->FacilityInfo;
foreach ($facilities as $data) {
echo $data->Name."<br>";
}
Any help would be great!
As Niranjan pointed out, you can use an if statement in the loop and count specific words.
$cnt = array();
foreach ($facilities as $data) {
if ($data->Name == "Jan") $cnt++; // the best given name ever ;-)
echo $data->Name."<br>";
}
echo "Count of Jan: " . $cnt;
As an alternative, if the whole $facilities array consists of words only, you could do a more abstract approach:
$cnt = array();
$facilities = ['Jan', 'Ben', 'Jan', 'Agathe', 'Christine', 'Jan'];
foreach ($facilities as $name) {
$cnt[$name]++;
echo $name."<br>";
}
print_r($cnt);
// array("Jan" => 3, "Ben" => 1, "Agathe" => 1, "Christine" => 1);
Besides my narcisstic personality disorder (counting me a couple of times, that is ;-)), this might be a good starting point.
You can use:
<?php
$searchWord = 'search';
$message = "search search no yes maybe works";
$words = explode(" ", $message);
if (in_array($searchWord,$words)) {
$cntArray = array_count_values($words);
echo $cntArray[$searchWord] . " $searchWord word count";
}
?>
Related
I'm making a website with wordpress for my company and i have a question for you
I have an url like this
http://mysuperwebsite/?_sft_category=cx+ms+lol
And i would like to grab the argument of this, so i tried
$motsclefs = $_GET['_sft_category'] ;
and a basic echo
echo'<div>'.$motsclefs.'</div>';
This is cool but now this return me something like this in a single div
cx ms lol
My desire is to cut those words, to have as much div as my words
To be more specific i would like to have something like this
<div class="1">cx</div>
<div class="2">ms</div>
<div class="3">lol</div>
So, i understood that i have to consider those "+" in the url to separate my words ?
Thanks ;)
You can try this.
$tempArr=explode(' ',$motsclefs);
for($i=0;$i < count($tempArr);$i++)
{
echo '<div>'.$tempArr[$i].'</div>';
}
As mentioned by Jon Stirling use explode and foreach.
<?php
$motsclefs = 'cx ms lol';
$divs = '';
foreach(explode(' ', $motsclefs) as $key => $element) {
$divs .= sprintf ('<div class="%s">%s</div>' . PHP_EOL, $key + 1, $element);
}
You can split the string by a space, if $motsclefs is a string with spaces separating the arguments, which is how it looks from your question:
$arguments = explode(" ", $motsclefs);
Then iterate through them:
foreach ($arguments as $argument) {
echo "<div>$argument</div>";
}
For different classes;
$i = 1;
foreach ($arguments as $argument) {
echo "<div class='class$i'>$argument</div>";
$i++;
}
$i increases for each loop round which will give you a new number with every iteration.
The code below is a simple version of what I am trying to do. The code will read in two files, see if there is a matching entry and, if there is, display the difference in the numbers for that item. But it isn't working. The first echo displays the word but the second echo is never reached. Would someone please explain what I am missing?
$mainArry = array('Albert,8');
$arry = array('Albert,12');
foreach ($arry as $line) {
$kword = explode(',', $line);
echo 'kword '.$kword[0];
if (in_array($kword[0], $mainArry)) {
echo 'line '.$line. ' has count of '.$kword[1] . '<br>';
}
}
Your $mainArry contains a single element: the string 'Albert,8'. It looks like you want to use it as an array (elements 'Albert' and '8') instead of a string.
You mention the code will read from two files, so you can 'explode' it to a real array, as you do with $arry. A simpler approach would be using str_getcsv() to parse the CSV string into $mainArry.
$inputString = 'Albert,8';
$mainArry = str_getcsv($inputString); // now $mainArry is ['Albert','8']
$arry = array('Albert,12');
foreach ($arry as $line) {
$kword = explode(',', $line);
echo 'kword '.$kword[0];
if (in_array($kword[0], $mainArry)) {
echo 'line '.$line. ' has count of '.$kword[1] . '<br>';
}
}
Test it here.
You are attempting to compare the string Albert with Albert,8, so they won't match. If you want to check if the string contains the keyword, assuming your array has more than one element, you could use:
$mainArry = array('Albert,8');
$arry = array('Albert,12');
foreach ($arry as $line) {
$kword = explode(',', $line);
echo 'kword '.$kword[0];
foreach ($mainArry as $comp) {
if (strstr($comp, $kword[0])) {
echo 'line '.$line. ' has count of '.$kword[1] . '<br>';
}
}
}
example: https://eval.in/728566
I don't recommend your way of working, but this is a solution, basically the process you apply to the $arry should also apply to the $mainArry you're trying to compare it to.
$mainArry = array('Albert,8');
$arry = array('Albert,12');
/***
NEW function below takes the valus out of the main array.
and sets them in their own array so they can be properly compared.
***/
foreach ($mainArry as $arrr){
$ma = explode(",",$arrr);
$names[] = $ma[0];
$values[] = $ma[1];
}
unset($arrr,$ma);
foreach ($arry as $line) {
$kword = explode(',', $line);
echo 'kword '.$kword[0];
/// note var reference here is updated.
if (in_array($kword[0], $names)) {
echo '<br>line '.$kword[0]. ' has count of '.$kword[1] . '<br>';
}
}
Yeah, MarcM's answer above does the same thing in a neat single line, but I wanted to illustrate a little more under the hood operations of the value setting. :-/
I did not want to ask, but I am still quite new to PHP and I am stuck.
I have a comma separated list stored in MySQL; Blue, 12, Red, 15 etc.
I can bring it out and do most of what I want, but I am confused on how to proceed.
Ultimately, I would like to change the output of the data from
Blue, 12, Red, 15,
to
Blue => 12, Red => 15 (without the last comma) So I can use the data in a program I am attempting to build.
Currently, I am able to achieve:
Blue, => 12, => Red, => 15,
Code:
$result = $con->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$id = $row['id'];
$type = $row["dataname"];
$datas = $type;
eval( "\$test = array (" . $datas . ");") ;
foreach($test as $test)
{
echo "<option name='$test'>$test , =></option>";
}
}
}
Using the desired output, I will be able to input data from a form to create an SVGGraph.
Thank you in advance for any assistance.
Ok so first off, I would try storing this information in separate rows in the future, comma separated lists are for when we do not have databases (simple text files for example).
But to answer your question (assuming result is the string of separated values):
$result = explode(',', $result);
$output = [];
for($i = 0;$i < count($result);$i=$i+2){
array_push($output, $result[i] => $result[i+1]);
}
//output:
$str = ""
foreach($output as $key => $value){
str .= $key . ' => ' . $value . ' ,';
}
$str = rtrim($str, ',');
echo $str //this will be your output
using eval is just the worst.
Here is how I would do it while keeping to your code as much as possible:
$result = $con->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$id = $row['id'];
$type = $row["dataname"];
$datas = $type;
$res = array();
$arr = explode(",", str_replace(" ","",$datas));
for ($i = 0; $i < count($arr); $i+=2) {
$res[$arr[$i]] = $arr[$i + 1];
}
foreach($res as $key=>$value)
{
echo "<option name='$value'>$key , =></option>";
}
}
}
First of all, try not to use eval - it is dangerous.:)
Second, try to get all the data you need into one big string. Then you can use the explode PHP function to convert the string into individual elements. And the last thing you would do is to simply iterate over the array and assign the first item as a key and the second item as an element into yet another array.
I will leave the actual implementation to you as an excercise in your PHP coding skills.:)
//trim comma from the right
$str = rtrim('Blue, 12, Red, 15,', ',');
//create a helper array
$array = explode(', ', $str);
//arrange elements in the new array
for ($i = 0; $i < count($array) - 1; $i = $i + 2) {
$new[] = $array[$i] . ' => ' . $array[$i + 1];
}
//output new elements
echo implode(', ', $new);
Please dont use eval. You nearly always can avoid it and is dangerous.
Here is a solution which works without eval:
$result = $con->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$id = $row['id'];
$type = $row["dataname"]; // Thats our comma-seperated list, right?
$arr = explode(',', $type); // Make $type to array
array_pop($arr); // Delete last element because its empty
// We go through the array with step = 2
// because the first is always the key and the second the value
for($i = 0; $i < count($arr); $i += 2)
{
echo "<option name='$arr[$i+1]'>$arr[$i] , =></option>";
}
}
}
Why eval is evil:
Whatever is in the string is evaled as code from your script with all rights the script has incuding file-access and so on. Since the string for your eval comes from the database you cant even be absolutely sure that it is no bad code you are executing when using eval.
Furthermore eval is bad when it comes to debugging things.
And at the end: Why producing overhead with stuff you can avoid?
It is in general recognized as bad style when using eval because of all this reasons. Better you never get used to it
If I understand correctly, you go from a string to an array to a string.
If so, it is possible to skip the array by using regex. Depending on the length of your string, creating a huge array may be a problem.
So I came up with those examples:
$input = "Blue, 1, Red, 2, Green, 3, Violet, 4,";
// Output: Blue => 1, Red => 2, Green => 3, Violet => 4
echo rtrim(preg_replace('/(([^,]*),([^,]*)),+/', '\2 =>\3,', $input), ',');
// Output <option name="Blue">Blue => 1</option><option name="Red">Red => 2</option><option name="Green">Green => 3</option><option name="Violet">Violet => 4</option>
echo preg_replace('/(\s*([^,]*)\s*,\s*([^,]*)\s*),+/', '<option name="\2">\2 => \3</option>', $input);
As you can see, no looping involved.
I hope it helped
EDIT
Here is links to visualize the regex
First regex
Second regex
This appears to be a simple task, but none of the previous posts quite addresses the nuances of this particular problem. I appreciate your patience with a new programmer.
I want to divide a text file (comments.txt) into arrays with the tilde as a divider. Then I want to pass a user string variable (nam) to the PHP and search for this string. The result should echo every whole array that contains the string anywhere inside of it.
For example:
Array
(
[0] => hotdog
[1] => milk
[2] => dog catcher
)
A search for "dog" would produce on screen:
hotdog dog catcher
<?php
$search = $_POST['nam'];
$file = file_get_contents('comments.txt');
$split = explode("~", $file);
foreach ($split as $subarray)
{
if(in_array($search, $subarray))
{
echo $subarray;
}
}
?>
The simple task is now this embarrassing mess. If you are patient enough, could someone demonstrate the above code correctly? Thanks for your attention.
Assuming you have 'comments.txt' and it contains something like:
hamburger~hotdog~milk~dog catcher~cat~dogbone
then this should work
$comments = file_get_contents("comments.txt");
$array = explode("~",$comments);
$search = "dog";
$matches = array();
foreach($array as $item){ // check each comment in array
if(strstr($item, $search)){ // use strstr to check if $search is in $item
$matches[] = $item; // if it is, add it to the array $matches
}
}
var_dump($matches);
First, you might want to try using file() instead of file_get_contents(). This should do what you're looking for:
<?php
$search = $_POST['nam'];
$file = file('contents.txt');
$matches = array();
foreach ($file as $k => $v) {
if ($a = explode('~', $v)) {
foreach ($a as $possible_match) {
if (preg_match('"/'. $search .'"/i', $possible_match)) {
$matches[] = $possible_match;
}
}
}
print_r($matches);
?>
This method will allow you to maintain several different records (one in each line of the file) and interpret/process them independently.
Assume I have the following string:
I have | been very busy lately and need to go | to bed early
By splitting on "|", you get:
$arr = array(
[0] => I have
[1] => been very busy lately and need to go
[2] => to bed early
)
The first split is after 2 words, and the second split 8 words after that. The positions after how many words to split will be stored: array(2, 8, 3). Then, the string is imploded to be passed on to a custom string tagger:
tag_string('I have been very busy lately and need to go to bed early');
I don't know what the output of tag_string will be exactly, except that the total words will remain the same. Examples of output would be:
I have-nn been-vb very-vb busy lately and-rr need to-r go to bed early-p
I-ee have been-vb very busy-df lately-nn and need-f to go to bed-uu early-yy
This will lengthen the string by an unknown number of characters. I have no control over tag_string. What I know is (1) the number of words will be the same as before and (2) the array was split after 2, and thereafter after 8 words, respectively. I now need a solution explode the tagged string into the same array as before:
$string = "I have-nn been-vb very-vb busy lately and-rr need to-r go to bed early-p"
function split_string_again() {
// split after 2nd, and thereafter after 8th word
}
With output:
$arr = array(
[0] => I have-nn
[1] => been-vb very-vb busy lately and-rr need to-r go
[2] => to bed early-p
)
So to be clear (I wasn't before): I cannot split by remembering the strpos, because strpos before and after the string went through the tagger, aren't the same. I need to count the number of words. I hope I have made myself more clear :)
You wouldn't want to count the number of words, you would want to count the string length (strlen). If it is the same string without the pipes, then you want to split it with substr after a certain amount.
$strCounts = array();
foreach ($arr as $item) {
$strCounts[] = strlen($item);
}
// Later on.
$arr = array();
$i = 0;
foreach ($strCounts as $count) {
$arr[] = substr($string, $i, $count);
$i += $count; // increment the start position by the length
}
I have not tested this, simply a "theory" and probably has some kinks to work out. There may be a better way to go about it, I just don't know it.
Interesting question, although I think the rope data structure still applies it might be a little overkill since word placement won't change. Here is my solution:
$str = "I have | been very busy lately and need to go | to bed early";
function get_breaks($str)
{
$breaks = array();
$arr = explode("|", $str);
foreach($arr as $val)
{
$breaks[] = str_word_count($val);
}
return $breaks;
}
$breaks = get_breaks($str);
echo "<pre>" . print_r($breaks, 1) . "</pre>";
$str = str_replace("|", "", $str);
function rebreak($str, $breaks)
{
$return = array();
$old_break = 0;
$arr = str_word_count($str, 1);
foreach($breaks as $break)
{
$return[] = implode(" ", array_slice($arr, $old_break, $break));
$old_break += $break;
}
return $return;
}
echo "<pre>" . print_r(rebreak($str, $breaks), 1) . "</pre>";
echo "<pre>" . print_r(rebreak("I have-nn been-vb very-vb busy lately and-rr need to-r go to bed early-p", $breaks), 1) . "</pre>";
Let me know if you have any questions, but it is pretty self explanatory. There are definitely ways to improve this as well.
I'm not quite sure I understood what you actually wanted to achieve. But here are a couple of things that might help you:
str_word_count() counts the number of words in a string. preg_match_all('/\p{L}[\p{L}\p{Mn}\p{Pd}\x{2019}]*/u', $string, $foo); does pretty much the same, but on UTF-8 strings.
strpos() finds the first occurrence of a string within another. You could easily find the positions of all | with this:
$pos = -1;
$positions = array();
while (($pos = strpos($string, '|', $pos + 1)) !== false) {
$positions[] = $pos;
}
I'm still not sure I understood why you can't just use explode() for this, though.
<?php
$string = 'I have | been very busy lately and need to go | to bed early';
$parts = explode('|', $string);
$words = array();
foreach ($parts as $s) {
$words[] = str_word_count($s);
}