Find Word Which comes first in php - php

I have 2 words like %sku% and %any% that will be used in the sites url structure.
This data will be saved in a database and I need to find out which comes first.
E.g.
In the below url %sku% comes first
http://example.com/%sku%/product/%any%
While in the below url %any% comes first
http://example.com/%any%/product/%sku%
Furthermore I cant be sure that the structure will be consistent it could be like any of the below:
http://example.com/%sku%/product/%any%
http://example.com/%any%/product/%sku%
http://example.com/%any%/%sku%
http://example.com/product/%sku%
http://example.com/product/%any%
I want to check which comes first and which comes last.. but %sku% and%any%` are defined by me.. so i can be 100% sure that those tags are going to be used.

The following code will return the first and last occurring items from a designated $attributes array.
$string = 'http://example.com/%sku%/product/%any%';
// values to check for
$attributes = ['%sku%', '%any%'];
$results = array();
foreach($attributes as $attribute)
{
// Get position of attribute in uri string
$pos = strpos($string, $attribute);
// if it exists we add it to the array with the position
if($pos)
{
$results[$attribute] = $pos;
}
}
// Get the first occuring attribute
$firstOccuringAttribute = array_search( min($results), $results);
// Get the last occuring attribute
$lastOccuringAttribute = array_search( max($results), $results);
This could be refactored into something a bit more readable:
$uri = 'http://example.com/%sku%/product/%any%';
$attributes = ['%sku%', '%any%'];
$lastAttribute = getLastAttribute($uri, $attributes);
$firstAttribute = getFirstAttribtue($uri, $attributes);
function getAttributeWeighting($uri, $attributes)
{
$results = array();
foreach($attributes as $attribute)
{
$pos = strpos($uri, $attribute);
if($pos)
{
$results[$attribute] = $pos;
}
}
return $results;
}
function getFirstAttribute($uri, $attributes)
{
$attributeWeighting = getAttributeWeighting($uri, $attributes);
return array_search( min($attributeWeighting), $attributeWeighting);
}
function getLastAttribute($uri, $attributes)
{
$attributeWeighting = getAttributeWeighting($uri, $attributes);
return array_search( max($attributeWeighting), $attributeWeighting);
}

Just use strpos
something like:
$URL = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$posOfSku=strlen($URL);
$posOfAny=strlen($URL);
if(strpos($URL ,'%sku%') !== false) {
$posOfSku = strpos($URL ,'%sku%');
}
if(strpos($URL ,'%any%') !== false) {
$posOfAny= strpos($URL ,'%any%');
}
$result = ($posOfAny < $posOfSku) ? 'any came 1st' : 'sku came 1st';
echo $result;

Related

Reading array and matching IDs and updating value

So I am going to be as descriptive as possible with this and see if anyone is able to assist me in a small script that I am writing.
I have the following read_csv() function which outputs the following items:
enter image description here
function read_csv()
{
$options = [];
$csv = WPMU_PLUGIN_DIR . ('/files/Office.csv');
$handle = fopen($csv, 'r');
$include_headers = false;
if (empty($handle) === false) {
while (($data = fgetcsv($handle, 1000, ',')) !== false) {
if (!$include_headers) {
$include_headers[] = $data;
} else {
$options[] = $data;
}
}
fclose($handle);
}
return $options;
}
Now I have this function below and this is what I'm wanting to achieve:
Read the read_csv() function and get the IDs
Match the IDs to the get_post_meta($place->ID, '_id', true).
If the two IDs match, update_post_meta on 'map_url' post_meta.
All help will be appreciated!
var_dump($place_id) & var_dump($map_url) output the following - I need to match the $place_id to the $place_rows[0] and then update_post_meta on that post w/ $office_rows[2].
enter image description here
function match_ids()
{
$places = get_posts([
'post_status' => 'any',
'post_type' => 'places',
'posts_per_page' => -1,
]);
if ($places) {
$place_ids = [];
$place_rows = read_csv();
var_dump($place_rows);
foreach ($places as $key => $place) {
$place_id = get_post_meta($place->ID, '_id', true);
var_dump($place_id);
$map_url = get_post_meta($place->ID, 'map_url', true);
var_dump($map_url);
}
}
}
If I'm understanding you correctly, the below for loop should work as a replacement to what you have. I've included inline comments which hopefully make sense. I would recommend using the var_dump stuff as you were before, before actually using update_post_meta just in case I have a typo.
foreach ($places as $key => $place) {
$place_id = get_post_meta($place->ID, '_id', true);
// Find _all_ that match, which is hopefully either one or zero items
$place_row = array_filter(
$place_rows,
function($row) {
// Whenever I work with CSV files I like to use ?? just in case
// You could also just use == for a weaker comparison
return (int)$place_id === (int)($row[0] ?? null);
}
);
if(1 !== count($place_row)){
// Not sure what to do if something isn't found, or if too many?
continue;
}
// Grap the single array item
$place_row = reset($place_row);
// Whenever I work with CSV files I like to use ?? just in case
$map_url = $place_row[2] ?? null;
// Sanity check, just in case someone uploads a file with different columns
if (false === filter_var($map_url, FILTER_VALIDATE_URL)) {
// Not a value URL
continue;
}
update_post_meta($place->ID, 'map_url', $map_url);
}

PHP get possible string combination of given array which match with given string

I have an array which contains bunch of strings, and I would like to find all of the possible combinations no matter how it's being sorted that match with given string/word.
$dictionary = ['flow', 'stack', 'stackover', 'over', 'code'];
input: stackoverflow
output:
#1 -> ['stack', 'over', 'flow']
#2 -> ['stackover', 'flow']
What I've tried is, I need to exclude the array's element which doesn't contain in an input string, then tried to match every single merged element with it but I'm not sure and get stuck with this. Can anyone help me to figure the way out of this? thank you in advance, here are my code so far
<?php
$dict = ['flow', 'stack', 'stackover', 'over', 'code'];
$word = 'stackoverflow';
$dictHas = [];
foreach ($dict as $w) {
if (strpos($word, $w) !== false) {
$dictHas[] = $w;
}
}
$result = [];
foreach ($dictHas as $el) {
foreach ($dictHas as $wo) {
$merge = $el . $wo;
if ($merge == $word) {
} elseif ((strpos($word, $merge) !== false) {
}
}
}
print_r($result);
For problems like this you want to use backtracking
function splitString($string, $dict)
{
$result = [];
//if the string is already empty return empty array
if (empty($string)) {
return $result;
}
foreach ($dict as $idx => $term) {
if (strpos($string, $term) === 0) {
//if the term is at the start of string
//get the rest of string
$substr = substr($string, strlen($term));
//if all of string has been processed return only current term
if (empty($substr)) {
return [[$term]];
}
//get the dictionary without used term
$subDict = $dict;
unset($subDict[$idx]);
//get results of splitting the rest of string
$sub = splitString($substr, $subDict);
//merge them with current term
if (!empty($sub)) {
foreach ($sub as $subResult) {
$result[] = array_merge([$term], $subResult);
}
}
}
}
return $result;
}
$input = "stackoverflow";
$dict = ['flow', 'stack', 'stackover', 'over', 'code'];
$output = splitString($input, $dict);

php foreach preg_match'd line, get next lines

I hope the title is self explanatory.
I would like to loop over a xml file line by line, then match a particular line (getting attributes from that line), then get the next X lines after that line.
I have the following code, which attempts to do this, but I cant seem to figure out how to get the next X lines after.
$file = 'Electric.xml';
$lines = file($file);//file in to an array
foreach($lines as $line){
$reads = element_attributes('WINDOW',$line);
if($reads['class'] == 'Bracelets'){
print_r($reads);
}
if($reads['class'] == 'Handbags'){
print_r($reads);
}
}
function element_attributes($element_name, $xml) {
if ($xml == false) {
return false;
}
// Grab the string of attributes inside an element tag.
$found = preg_match('#<'.$element_name.
'\s+([^>]+(?:"|\'))\s?/?>#',
$xml, $matches);
if ($found == 1) {
$attribute_array = array();
$attribute_string = $matches[1];
// Match attribute-name attribute-value pairs.
$found = preg_match_all(
'#([^\s=]+)\s*=\s*(\'[^<\']*\'|"[^<"]*")#',
$attribute_string, $matches, PREG_SET_ORDER);
if ($found != 0) {
// Create an associative array that matches attribute
// names to attribute values.
foreach ($matches as $attribute) {
$attribute_array[$attribute[1]] =
substr($attribute[2], 1, -1);
}
return $attribute_array;
}
}
// Attributes either weren't found, or couldn't be extracted
// by the regular expression.
return false;
}
Use a proper parser, like SimpleXML, to parse the file. Then your issue becomes trivial. The PHP manual contains a tutorial to help you get started.
In this case you just loop over the lines, checking the property of the tag you're looking for, until you find a match. Then, loop over the next # elements, saving them into an array.
Something like this:
$xml = new SimpleXML ("file.xml");
foreach ($xml->node->element as $element) {
if ($element->attribute != "match") {
continue;
}
// If we get here we want to save the next # lines/elements.
}
$linesLength = count($lines);
$XLines = array();
for($index = 0; $index < $linesLength; $index++){
$reads = element_attributes('WINDOW',$line);
if($reads['class'] == 'Bracelets'){
print_r($reads);
$XLines[] = array_slice($array, $index, $X);
$index += $X;
}
if($reads['class'] == 'Handbags'){
print_r($reads);
$XLines[] = array_slice($array, $index, $X);
$index += $X;
}
}

Data Not Being Parsed Correctly

I have a simple data format that goes as follows:
stuff/stuff/stuff
An example would be:
data/test/hello/hello2
In order to retrieve a certain piece of data, one would use my parser, which tries to do the following:
In data/test/hello/hello2
You want to retrieve the data under data/test (which is hello). My parser's code is below:
function getData($data, $pattern)
{
$info = false;
$dataLineArray = explode("\n", $data);
foreach($dataLineArray as &$line)
{
if (strpos($line,$pattern) !== false) {
$lineArray = explode("/", $line);
$patternArray = explode("/", $pattern);
$iteration = 0;
foreach($lineArray as &$lineData)
{
if($patternArray[$iteration] == $lineData)
{
$iteration++;
}
else
{
$info = $lineData;
}
}
}
}
return $info;
}
However, it always seems to return the last item, which in this case is hello2:
echo getData("data/test/hello/hello2", "data/test");
Gives Me;
hello2
What am I doing wrong?
If you want the first element after the pattern, put break in the loop:
foreach($lineArray as $lineData)
{
if($patternArray[$iteration] == $lineData)
{
$iteration++;
}
elseif ($iteration == count($patternArray))
{
$info = $lineData;
break;
}
}
I also check $iteration == count($patternArray) so that it won't return intermediate elements, e.g.
/data/foo/test/hello/hello2
will return hello rather than foo.
P.S. There doesn't seem to be any reason to use references instead of ordinary variables in your loops, since you never assign to the reference variables.

URI segment to associative array in code igniter

I have following url:
www.example.com/index.php/search/search_data/Doctor:a/Gender:Male/Language:Urdu/
and I want to convert it to associative array like
$data=array(
'Doctor'=> 'a',
'Gender'=> 'Male',
'Language'=> 'Urdu'
);
I have tried to do this using codeIgniter's URI class function
$this->uri->uri_to_assoc(n)
but as it accepts the data to be separated via '/' but I am having data with ':' as separator.
please help me.
I don't think there's an easier way to do this, rather than to do it manually.
First, retrieve the total segments, loop through, see if it contains ":", then add it into the array.
$segments = $this->uri->segment_array();
$search_array = array();
foreach($segments as $segment) {
if (strpos($segment, ":") !== FALSE) {
$e_array = explode(":", $segment);
$search_array[$e_array[0]] = $e_array[1];
}
}
Running that snippet somewhere will give you desirable results, $search_array will be an associative array with key => value.
You could hack the URI.php file. Change lines 431 - 439 to;
if (strpos($seg, ":") !== FALSE) {
list($parameter, $value) = explode(':', $seg);
if ($i % 2) {
$retval[$parameter] = $value;
} else {
$retval[$parameter] = $value;
$lastval = $seg;
}
} else {
if ($i % 2) {
$retval[$lastval] = $seg;
} else {
$retval[$seg] = FALSE;
$lastval = $seg;
}
}

Categories