Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I have no way to test this, so its on you, but here's how I'd do it. I put a ton of comments in there explaining my reasoning and the flow of the code.</p> <p>Basically, the recursion is unnecessary will result in more database queries than you need.</p> <pre><code>&lt;? public function prevent_double_cleanurl($cleanurl) { $sql = sprintf("SELECT product_ID, titel_url FROM %s WHERE titel_url LIKE '%s%%'", $this-&gt;_table, $cleanurl); if($this-&gt;ID != NULL){ $sql.= sprintf(" AND product_ID &lt;&gt; %d", $this-&gt;ID); } $results = $this-&gt;query($sql); $suffix = 0; $baseurl = true; foreach($results as $row) { // Consider the case when we get to the "first" row added to the db: // For example: $row['titel_url'] == $cleanurl == 'domain.nl/product/machine' if($row['title_url'] == $cleanurl) { $baseurl = false; // The $cleanurl is already in the db, "this" is not a base URL continue; // Continue with the next iteration of the foreach loop } // This could be done using regex, but if this works its fine. // Make sure to test for the case when you have both of the following pages in your db: // // some-hyphenated-page // some-hyphenated-page-name // // You don't want the counters to get mixed up $url_parts = explode("-", $row['titel_url']); $last_part = array_pop($url_parts); $cleanrow = implode("-", $url_parts); // To get into this block, three things need to be true // 1. $last_part must be a numeric string (PHP Duck Typing bleh) // 2. When represented as a string, $last_part must not be longer than 2 digits // 3. The string passed to this function must match the string resulting from the (n-1) // leading parts of the result of exploding the table row if((is_numeric($last_part)) &amp;&amp; (strlen($last_part)&lt;=2) &amp;&amp; ($cleanrow == $cleanurl)) { $baseurl = false; // If there are records in the database, the // passed $cleanurl isn't the first, so it // will need a suffix $suffix = max($suffix, (int)$last_part); // After this foreach loop is done, $suffix // will contain the highest suffix in the // database we'll need to add 1 to this to // get the result url } } // If $baseurl is still true, then we never got into the 3-condition block above, so we never // a matching record in the database -&gt; return the cleanurl that was passed here, no need // to add a suffix if($baseurl) { return $cleanurl; } // At least one database record exists, so we need to add a suffix. The suffix we add will be // the higgest we found in the database plus 1. else { return sprintf("%s-%d", $cleanurl, ($suffix + 1)); } } </code></pre> <p>My solution takes advantage of SQL wildcards (<code>%</code>) to reduce the number of queries from <em>n</em> down to 1.</p> <p>Make sure that you ensure problematic case I described in lines 14-20 works as expected. Hyphens in the machine name (or whatever it is) could do unexpected things.</p> <p>I also used <code>sprintf</code> to format the query. Make sure you sanitize any string that is passed through as a string (e.g. <code>$cleanurl</code>).</p> <p>As @rodneyrehm points out, PHP is very flexible with what it considers a numeric string. You might consider switching out <a href="http://www.php.net/manual/en/function.is-numeric.php" rel="nofollow"><code>is_numeric()</code></a> for <a href="http://www.php.net/manual/en/function.ctype-digit.php" rel="nofollow"><code>ctype_digit()</code></a> and see how that works.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload