php - search an array for a string - php

<?php // SEARCH TAGS FOR A SPECIFIC TAG
$tags = CollectionAttributeKey::getByHandle('recipe_tags'); // attribute handle of tags to search
$tagToFind = 'Videos'; // declare the specific tag to find
$selectedTags = array($page->getAttribute($tags->getAttributeKeyHandle())); // get tags associated with each page and put them in an array
foreach ($selectedTags as $tag) { // output tags separately
echo $tag; // ECHO TEST - check that individual tags associated with each page are outputting correctly
if ($tag == $tagToFind) { // if $tag is equal to $tagToFind
echo ' Found';
} else {
echo ' Not found';
}
}
?>
echo $tag; outputs the list of tags associated with each page so I'm pretty sure the issue is how I'm checking if 'Videos' is in the list of tags.
The above outputs the following list: Breakfast Brunch Budget Meal Easy Lunch Quick Meals Supper Vegetarian Videos and Not found even though Videos is in the list.
I've also tried using in_array to look for 'Videos' like this:
if (in_array($tagToFind, $selectedTags, true)) { // search the array for $tagToFind - true = strict
echo ' Found';
} else {
echo ' Not found';
}
But get the same result - I'm new to php so sorry if this is easy.
Any help would be much appreciated.
Cheers

It seems that $selectedTags an array of one string, since your foreach only loops once
You should try doing
$selectedTags = explode(" ",$page->getAttribute($tags->getAttributeKeyHandle()));
Then use in_array function

$page->getAttribute($tags->getAttributeKeyHandle())
seems to return a string.
In that case
$selectedTags = array($page->getAttribute($tags->getAttributeKeyHandle()));
makes no sense - you get an array containing one long string.
What you want to to is:
$selectedTags = $page->getAttribute($tags->getAttributeKeyHandle());
if(stristr($selectedTags, $tagToFind)){
// do something
}
else{
// do something else
}

Then Better to use....
if(strcmp($tag , $tagToFind))
{
echo "Found";
}
else
{
echo "Not found";
}
may this works for you

Related

PHP code performance optimization help needed

I have the following code, which checks is an element exists, and if it exists, it checks for the same name, with an incremented number at the end.
For example, it checks is the key "test" exists in the array $this->elements, and if it exists, it checks for "test2", and so on, until the key doesn't exist.
My original code is:
if (isset($this->elements[$desired])) {
$inc = 0;
do {
$inc++;
$new_desired = $desired . $inc;
} while (isset($this->elements[$new_desired]));
$desired = $new_desired;
}
I tried with:
if (isset($this->elements[$desired])) {
return $this->generateUniqueElement($desired, $postfix);
}
private function generateUniqueElement($desired, $postfix) {
$new_desired = $desired . $postfix;
return isset($this->elements[$new_desired]) ? $this->generateUniqueElement($desired, ++$postfix) : $new_desired;
}
But in my tests there's no speed improvement.
Any idea how can I improve the code? On all the pages, this code is called over 10 000 times. And sometimes even over 100k times.
Anticipated thanks!
Without further knowledge on how you generate this list, here's an idea:
$highestElementIds = [];
foreach($this->elements as $element) {
preg_match('/(.*?)(\d+)/', $element, $matches);
$text = $matches[1];
$id = (int)$matches[2];
if(!isset($highestElementIds[$text])) {
$highestElementIds[$text] = $id;
} else {
if($id > $highestElementIds[$text]) {
$highestElementIds[$text] = $id;
}
}
}
// find some element by a simple array access
$highestElementIds['test']; // will return 2 in your example
If your code is really being called 100k times, it should be a lot faster to iterate your list only once and then get the highest id directly from an array which contains the highest number (since you don't need to iterate through it again).
That being said, I still wonder what's the actual reason for having such a huge array in the first place...
Typical unique IDs are either random (UUID or random chars) or sequential numbers. The latter is as simple as it gets and it can be generated with a simple counter:
function generateNewElement($postfix) {
static $i = 0;
return sprintf('%d%s', $i++, $postfix);
}
echo generateNewElement('foo'), PHP_EOL;
echo generateNewElement('foo'), PHP_EOL;
echo generateNewElement('foo'), PHP_EOL;
echo generateNewElement('foo'), PHP_EOL;
0foo
1foo
2foo
3foo
Of course this is just a generic solution so it may not fit your specific use case.

How to return only one value if none of foreach iterations match condition

I have piece of code like this
foreach ($item->offers as $offer) {
foreach ($json as $akey => $article){
if ($article['A'] == $offer->OfferName){
echo $article['B'];
break;
} else {
echo $offer->OfferName
}
}
}
As you can see I want to loop through offers and see if they exist in json.
If they exist I want to get value B of article but if not I want just to echo offer name.
Unfortunately else statement return all of non matching iterations and I have no idea how to force it to return it only once.
E: I want return some value if none of iterations in second loop is matching given condition.
Maybe someone familiar with PHP know the solution.
Thanks.
Your else statement is defined within a second tier foreach so its normal to get the OfferName every single time - that's the logic you coded.
If I understand you correctly, you want the article value rendered only when each key matches your criteria, and the offer name if there's a key that doesn't match it. If this is the case then you can do this:
$match = 0;
$output = '';
foreach ( $item->offers as $offer ) {
foreach ( $json as $akey => $article){
if ($article['A'] == $offer->OfferName){
$output .= $article['B'].PHP_EOL;
// break; - this is pointless
} else {
$match = $offer->OfferName;
}
}
}
echo ( $match == 0 ? $output : $match);

PHP MYSQL ARRAY check if string is in array

I have user input which in this case will be Hello
$command = mysqli_real_escape_string($con,$_POST['command']);
a variable called $dialogue_unlock is populated through some scripts. Which for testing will output 'Hello','Goodbye'
$dialogue_unlock .= ',\''. $discuss_row['discussion_text'].'\'';
Im then trying to see if the user input matches the array
$dialogue_array = array($dialogue_unlock);
if(!in_array("$command", $dialogue_array)){
$err .= 'Invalid Question';
}
As a test im using
echo $err. '<br>';
echo $command. '<br>';
echo $dialogue_unlock;
I get
Invalid Question
Hello
'Hello','Goodbye'
I just cant wrap my head around it as 'hello' is definitely in 'Hello','Goodbye'. Can anybody offer some advise please.
Many thanks.
It looks as though your array contains the 1 element with the text 'Hello','Goodbye' and when you look for Hello it doesn't match. What you should do is add each item of $discuss_row['discussion_text'] to $dialogue_array directly using (in whatever loop you build up $dialogue_unlock)
$dialogue_array[] = $discuss_row['discussion_text'];
So when you add Hello and Goodbye then it will be two separate elements in the array.
Just make sure that before this loop you initialise the array...
$dialogue_array = [];
Try this.
$command = mysqli_real_escape_string($con,$_POST['command']); /// hello
$dialogue_unlock .= ',\''. $discuss_row['discussion_text'].'\''; /// 'Hello','Goodbye'
$dialogue_unlock = explode(',', $dialogue_unlock); /// dialogue_unlock to array
foreach ($dialogue_unlock as $a) {
if (strpos($command, $a) !== FALSE) {
echo "Match found";
}
else
{
echo "Not found!";
}
}

How to parse a web service returned response into an array in PHP

I am updating my question with a few breakthroughs i was able to achieve today. I used get_object_vars.
This code was able to print out the value i am trying to iterate over.
$fileStatus = $ServicesLink->GetFileStatus(array('Ticket'=>$ticket,'ProjectID'=>$pidobtained,'SourceLanguageID'=> "", 'TargetLanguageID'=> "",'FileID'=> "",'Filename'=>""));
$arrayPid = array();
foreach($fileStatus->GetFileStatusResult->FileStatuses->FileStatus as $fileStatusObtained)
{
$arrayPid = get_object_vars($fileStatusObtained);
//$arrayPid =$fileStatusObtained ;
}
echo is_array($arrayPid) ? 'Array' : 'not an Array';
echo "<br>";
echo("Count of array ".count($arrayPid));
echo "<br>";
print_r('<pre>'. print_r($arrayPid) .'</pre>');
This http://www.image-share.com/ijpg-1163-165.html is what i saw as a result.
Now since this Object has objects inside it along with the values i need i.e. FileID,FileName etc. I am seeing the error message but a glimpse of the output. The code i used was this (just a very minor change from the above. I used a foreach)
$fileStatus = $ServicesLink->GetFileStatus(array('Ticket'=>$ticket,'ProjectID'=>$pidobtained,'SourceLanguageID'=> "", 'TargetLanguageID'=> "",'FileID'=> "",'Filename'=>""));
$arrayPid = array();
foreach($fileStatus->GetFileStatusResult->FileStatuses->FileStatus as $fileStatusObtained)
{
$arrayPid = get_object_vars($fileStatusObtained);
//$arrayPid =$fileStatusObtained ;
}
echo is_array($arrayPid) ? 'Array' : 'not an Array';
echo "<br>";
echo("Count of array ".count($arrayPid));
echo "<br>";
//print_r('<pre>'. print_r($arrayPid) .'</pre>');
foreach($arrayPid as $val) {
echo ($val);
echo "<br>";
}
}
As a result of this i saw the following output http://www.image-share.com/ijpg-1163-166.html .
The index number 1 occupies the object and hence the error for string conversion.
If i use a For loop instead of the foreach in the code just above,i am unable to print the values.
I tried:
for($i=0;$i<(count($arrayPid));$i+=1)
{
echo($arrayPid[$i]);
}
But this would print nothing.
Could any one help me with a way so that i can iterate and have the values inside that array $arrayPid.
Would like to have your suggestions, views, doubts on the same.
I am sorry that i am using imageshare but that is the only way i can share my screens.
Thanks
Angie
The correct way to use it is:
foreach($fileStatus->GetFileStatusResult->FileStatuses->FileStatus as $fileStatusObtained)
{
$arrayPid = get_object_vars($fileStatusObtained);
//print_r($fileStatusObtained->FileID);
$fileId [] = $fileStatusObtained->FileID;
...
}

If Statement inside or outside

I'm trying to figure out if I need to do this inside the for loop or outside the for loop but I want to check to see its empty or not first.
echo "<ul>";
for($x = 0; $x <= (count($quotesArray)-1); $x++)
{
echo "<li>".stripslashes($quotesArray[$x]->quote)."</li>";
}
echo "</ul>";
There is something simpler that checking during loop - it filters all the values and is called array_filter() function:
$quotesArray = array_filter($quotesArray);
echo "<ul>";
foreach($quotesArray as $quote){
echo "<li>".stripslashes($quote)."</li>";
};
echo "</ul>";
The above assumes that $quotesArray contains strings (or elements that work correctly in string context) and you do not want only the elements that are evaluated as false when converted to boolean (see more about converting to boolean).
Additionally you can simplify your code further:
$quotesArray = array_filter($quotesArray);
$quotesArray = array_map('stripslashes', $quotesArray);
echo '<ul><li>'.implode('</li><li>', $quotesArray).'</li></ul>';
if you know $quotesArray contains at least one element.
EDIT:
Short version, that also checks whether the list should be generated (in other words: whether array contains at least one element after processing):
$quotesArray = array_map('stripslashes', array_filter($quotesArray));
if (!empty($quotesArray)) {
echo '<ul><li>'.implode('</li><li>', $quotesArray).'</li></ul>';
};
It needs to be outside the loop because if it is empty, and you don't generate any list items, then you have no list, so you should not generate the ul start and end tags either (since a list with no list items is invalid).
well if you dont wan the list at all then you should do it before the echoing of the first <ul>
if(count($quotesArray) > 0){
//Do your echos and loops in here
}
You can just run both checks.
if($quotesArray){
echo '<ul>';
foreach ($quotesArray as $quote) {
if ($quote) {
echo '<li>' . stripslashes($quote->quote) . '</li>';
}
}
echo '</ul>';
}
When you say you want to check if it's empty, do you mean the entire $quotesArray or one of the values within it?
If you mean you want to check if a value within the array is empty, you could consider this approach:
echo '<ul>';
foreach ($quotesArray as $quote) {
if ($quote) {
echo '<li>' . stripslashes($quote) . '</li>';
}
}
echo '</ul>';

Categories