...

Hi! I’m Starx

experienced Software Developer. And this is my blog
Start Reading About me
Blog Page
May 2, 2012

array_diff_uassoc () in PHP?

Question by Rajiv

function myfunction($v1, $v2) {
    if ($v1 == $v2) {
        return 0;
    }
    if ($v1 > $v2) {
        return 1;
    } else {
        return-1;
    }
}

$a1 = array(5 => "Rat", 2 => "Cat", 7 => "Horse");
$a2 = array(8 => "Rat",4 => "Cat",7 => "Horse");
print_r(array_diff_uassoc($a1, $a2, "myfunction"));

How it is executed?

Answer by Starx

Please read the manual.

It basically compares two or more arrays, checking for differences, before comparing the keys in a user-defined function, then returns an array with the keys and values from the first array, if the function allows it.

Unlike array_diff_assoc() an user supplied callback function is used for the indices comparison, not internal function.

Please see the live version of your code here. It calculates the difference based on the function and gives the following output.

Array
(
    [5] => Rat
    [2] => Cat
)
Read more

Showing a scrollbar only in Firefox

Question by Kei Izumi

I’d like to have a scrollbar at the bottom of the div but this CSS works only in Firefox, not Webkit browsers like Safari or Chrome.

div.hoge {
    width: 500px;
    overflow: auto;
}

I googled and found some pages mentioning you should use overflow-x or -webkit-overflow-scrolling but they didn’t work either. Need to use some JSs? Any guesses?

Answer by Starx

  • If you need a scroll bar to appear always then, you can use overflow: scroll
  • If you need vertical scroller then, overflow-y: scroll
  • If you need only horizontal scroller then, overflow-x: scroll

As per the questions title: You can write mozilla specific styles like this

@-moz-document url-prefix() {

    div.hoge {
        width: 500px;
        overflow: auto;
    }

}
Read more

PHP Syntax Error?

Question by user1367069

I have coded a nice script but i am constantly getting

Error on line 29: Parse error, unexpected T_IF(if)

I have tried debugging code, wasted plenty of time. But nothing, came out.

Here is my code.

<?php

  include("geoip.inc");
$ip=$_SERVER['REMOTE_ADDR'];
$gi = geoip_open("GeoIP.dat",GEOIP_STANDARD);

$country_code = geoip_country_code_by_addr($gi, "$ip");
$referrer=$_SERVER['HTTP_REFERER'];
// Country name is not used so commented
// Get Country Name based on source IP
//$country = geoip_country_name_by_addr($gi, "$ip");
$real=0;
geoip_close($gi);

if(strstr(strtolower($_SERVER['HTTP_USER_AGENT']), "googlebot")) {
    $real = 1;  
}
else {
                if ($_COOKIE['iwashere'] != "yes")  {
                setcookie("iwashere", "yes", time()+315360000); 
                            if ($country_code="IN") {
                                    if(preg_match('/google/i', $referrer)) {
                                    $key = "g17x9erm28n7cgifddssfqhgorjf3e"; // Account API Key
                                    $ip = $_SERVER['REMOTE_ADDR']; // IP to Lookup

                                    $result = file_get_contents('http://www.ipqualityscore.com/api/ip_lookup.php?KEY='.$key.'&IP='.$ip);
                                    $real=$result
//$result will be equal to 1 for detected proxies & vpns or equal to 0 for clean IP's
                                            {if($real==0)
                                            {setcookie("testcookie", "testvalue");  
                                                        if( isset( $_COOKIE['testcookie'] ) ) {
                                                                if (isset($_POST['jstest'])) {
                                                                    $nojs = FALSE;
                                                                    } else {
  // create a hidden form and submit it with javascript
                                                                    echo '<form name="jsform" id="jsform" method="post" style="display:none">';
                                                                    echo '<input name="jstest" type="text" value="true" />';
                                                                    echo '<script language="javascript">';
                                                                    echo 'document.jsform.submit();';
                                                                    echo '</script>';
                                                                    echo '</form>';
  // the variable below would be set only if the form wasn't submitted, hence JS is disabled
                                                                    $nojs = TRUE;
    }
                                                                                if ($nojs){
    $real=1;
 }


}
else    
$real=1;        
}
else
$real=1;

        } else 
            $real = 1;

    }
 else {
    $real = 1;
}
          }  }

if ($real==1) {
    include_once('Biggenius1.htm');

}

?>

It is if inside. Please give me advice, on how can i avoid these error. And also is there any alternative to code such complex script with multiple nested if statements?

Please post entire code:

Answer by Moyed Ansari

try this

$real = 0;
geoip_close($gi);

if (strstr(strtolower($_SERVER['HTTP_USER_AGENT']), "googlebot")) {
    $real = 1;
} else {
    if ($_COOKIE['iwashere'] != "yes") {
        setcookie("iwashere", "yes", time() + 315360000);
        if ($country_code = "IN") {
            if (preg_match('/google/i', $referrer)) {
                $key = "g17x9erm28n7cgifddssfqhgorjf3e"; // Account API Key
                $ip = $_SERVER['REMOTE_ADDR']; // IP to Lookup

                $result = file_get_contents('http://www.ipqualityscore.com/api/ip_lookup.php?KEY=' . $key . '&IP=' . $ip);
                $real = $result;
//$result will be equal to 1 for detected proxies & vpns or equal to 0 for clean IP's {
                    if ($real == 0) {
                        setcookie("testcookie", "testvalue");
                        if (isset($_COOKIE['testcookie'])) {
                            if (isset($_POST['jstest'])) {
                                $nojs = FALSE;
                            } else {

                            }
                            // create a hidden form and submit it with javascript
                            echo '<form name="jsform" id="jsform" method="post" style="display:none">';
                            echo '<input name="jstest" type="text" value="true" />';
                            echo '<script language="javascript">';
                            echo 'document.jsform.submit();';
                            echo '</script>';
                            echo '</form>';
                            // the variable below would be set only if the form wasn't submitted, hence JS is disabled
                            $nojs = TRUE;
                        }
                        if ($nojs) {
                            $real = 1;
                        }
                    }
                    else
                        $real = 1;
                }
                else
                $real = 1;
            } else
                $real = 1;
        }
        else {
            $real = 1;
        }

}

if ($real == 1) {
    include_once('Biggenius1.htm');
}

Answer by Starx

Here are the few errors I found:

  1. if ($country_code="IN") : This is an assignment not comparision, will always return true
  2. $real=$result : Missing Termination ; on the end
Read more

get the title from a context

Question by Hermione

How Do I select the title of the context? I am suppose to select it to change the title of the page.

var handler = function(context){
    document.title = //context's title
    ....
}

//sample context from ajax request
var context = '<!DOCTYPE html><html>
            <head><title>Hello</title></head>
            <body>
            <a href="#">Click Here</a><p>This is my sentence.</p>
            </body></html>';

.ajax{(
    ...
    success: function(data){
                 handler(data);
             }
});

EDIT: I forgot the doctype just incase it’s necessary. The context was from an AJAX Request.

Answer by Starx

You can use regex to extract the title as well

var matches = context.match(/<title>(.*?)</title>/);
var title = matches[1];

Demo


Just discovered a way to do this, the non-regex way

title = $(context).filter("title");
console.log(title.html());

Demo

Read more

Joining two tables but the join key is in a query string

Question by lauthiamkok

I want to join these two table but the join key of the second table is in a query string,

page table,

page_id     url
1           a
2           c
3           d

system table,

system_id       query
1               page_id=1&content=on&image=on
2               type=post&page_id=2&content=on

as you can see that page_id is part of the query string in system table.

so how can I join them like the standard joining table method below?

SELECT*
FROM page AS p

LEFT JOIN system AS s
ON p.page_id = s.page_id

EDIT:

I def can change the system table into something like this,

system_id       page_id    query
1               1           page_id=1&content=on&image=on
2               2           type=post&page_id=2&content=on
3               NULL        type=page

But the reason why I don’t want to do this is that the page_id is no need for many certain records. I don’t want make a column with too many null.

Answer by Nation

I guess you wanted something like this (MSSQL!):


DECLARE @query VARCHAR(50)
DECLARE @Lenght INT  
DECLARE @PageID INT 

SET @query = '4kkhknmnkpage_id=231&content=on&image=on'
SET @Lenght = PATINDEX('%&%', substring(@query,PATINDEX('%page_id=%', @query),50)) - 9
SET @PageID = CAST(SUBSTRING(@query,PATINDEX('%page_id=%', @query) + 8,@Lenght) AS INT)

SELECT @PageID -- you can do as you please now :)

OR:

SELECT*
FROM page AS p
LEFT JOIN (SELECT CAST(SUBSTRING(query,PATINDEX('%page_id=%', query) + 8,(PATINDEX('%&%', substring(query,PATINDEX('%page_id=%', query),50)) - 9)) AS INT) AS page_id
                FROM system) AS s
ON p.page_id = s.page_id 

-- Do as you please again :) 

I guess what you really wanted was something like this (MYSQL!):


SET @query := '4kkhknmnkpage_id=231&content=on&image=on';
SET @Lenght := POSITION('&' IN (SUBSTR(@query,POSITION('page_id=' IN @query),50))) - 9;
SET @PageID := CAST(SUBSTR(@query,POSITION('page_id=' IN @query) + 8,@Lenght) AS  SIGNED );

SELECT @PageID

OR


SELECT*
FROM page AS p
LEFT JOIN (SELECT CAST(SUBSTR(query,POSITION('page_id=' IN query) + 8,(POSITION('&' IN (SUBSTR(query,POSITION('page_id=' IN query),50))) - 9)) AS  SIGNED) AS pageID
           FROM system) AS s
ON p.page_id = s.pageID 

Answer by Starx

Joining two tables without the common field and data type, is fundamentally wrong IMO.

I will suggest that you extract the page_id and insert it in the database and use a normal join to accomplish what you are searching for.

SO making the columns like

+------------+-----------+---------+
| system_id  |  page_id  |  query  |
------------------------------------

Here is a snippet with which you are extract the page_id.

$query = 'page_id=1&content=on&image=on';
$queryParts = explode('&', $query);

$params = array();
foreach ($queryParts as $param) {
    $item = explode('=', $param);
    $params[$item[0]] = $item[1];
} 
$page_id = $parems['page_id'];

Then you can go on with the insert and use simple join statement to solve your problem in a proper way.


Update:

Since you are able to change the schema to a feasible one. You dont need to worry about some rows having empty rows on this.

Read more

Determine nearest mirror PHP

Question by D. Strout

I maintain a site with a bunch of downloadable files. It is currently hosted on a server in the U.S., but I have recently acquired a new server in Germany. I would like to mirror the downloads to the server in Germany, and have a PHP script on the first server (hosting the website) detect which file mirror to use based on the user’s location. For instance, if the user is in Canada, they should download the file from my current server in the U.S. If they’re in France, they should get the file from Germany, rather than downloading across the Atlantic. How, then, can I determine which country they are closer to?

I know about MaxMind GeoIP, and have it installed, but that just gives me a country, and AFAIK, there is no way to automatically determine which of my two mirror countries the given country is closest to. I suppose what I could do is go by continent: have users in Asia, Europe, Africa, and Australia get the content from Germany, and have visitors from North and South America get the file from the U.S. If anyone can think of a better solution, I’m open to suggestions.


Well, I guess I am going to go go with my original idea of checking by continents. For others looking to do this sort of thing, that will be a good place to start. The problem will come when I have multiple mirrors in Europe, but the continent idea will have to work for now.

Answer by Matt Borja

Seems there is a lot of developer overhead in the proposed solutions thus far. If this was a problem I had to address in my own applications, I might save me a few hours of work by opting not to reinvent the wheel on this one.

Determining the Closest Mirror (Using Zip Codes)

  1. Maintain a list of postal codes in an array for those mirror servers available.
  2. Determine the postal code of the user agent (e.g. user input or PHP library)
  3. Calculate the distance between the two postal codes (e.g. PHP library)
  4. Proceed with mirror selection based on distance returned

Please keep in mind that a closer distance does not necessarily constitute a faster response time. In the context of your scenario, however, a mirror in one country will obviously be faster than a mirror in another, assuming both mirrors are up. Continue reading for what I consider to be a more “robust” solution.

Resources & Links

The “Maverick” Approach

In my opinion, Mavericks are also known as those innovators, problem solvers, and inventors of these great libraries and frameworks we all use today. Sometimes mistakenly associated with “hackish” ideas, but we embrace the complement 🙂

  1. Create your own API service on either one of your mirror servers that will accept either a $_GET or $_POST request.

  2. This API service will take an IP address it is given and ping() it, calculating the response times and then taking the average, returning it to the requesting interface (e.g. your frontend portal through which clients are connecting and/or the server trying to determine the closest mirror). The server that responds with the lowest average ought to be your quickest responding server, albeit not necessarily closest. Which is more important to you? See Ping site and return result in PHP for a working ping() function that does not rely on executing shell commands locally (e.g. platform independent).

  3. Last step, derive the IP address of the requesting client and pass it to your API service running on either mirror server in the background. And we all know how to derive the IP, but not as well as you think we might. If you’re load balanced or behind a proxy, you may want to first check to see if any of these headers came through (HTTP_FORWARDED, HTTP_FORWARDED_FOR, HTTP_X_FORWARDED, HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP). If so, that’s probably the real IP address of the user agent.

It is at this point (Step 3) where you would compare the averages of response times that each mirror replied with when they went to ping the user agent. Then proceed with selecting which mirror the user agent should download from. The service flow you will have created then resembles something like this:

  1. User agent visits portal
  2. Portal forwards user agent’s IP address to API service running separately on both mirrors using a background AJAX/jQuery request (or traditional POST and redirect).
  3. API service running on mirrors pings the IP address it receives and returns an average of the total number of responses it is configured to fetch.
  4. Portal reads the returned averages and compares them.

Hope that helps and happy coding!

Answer by Starx

I dont remember any library that can do this. But instead of build a system, If I have an idea, that might be able to help you out.

Calculate the distance between two IP’s using this distance calculator. Or find out the latitude and longitude of the two IP address (one server) and (one guest) and calculate the distance. Here is a pseudocode to do that

distance = ( 3956 *2 * ASIN( SQRT( POWER( SIN( ( 34.1012181 - ABS( latitude ) ) * PI( ) /180 /2 ) , 2 ) + COS( 34.1012181 * PI( ) /180 ) * COS( ABS( latitude ) * PI( ) /180 ) * POWER( SIN( ( ABS( - 118.325739 ) - ABS( longitude ) ) * PI( ) /180 /2 ) , 2 ) ) ))
Read more

Why do these alerts multiply?

Question by Elite Gamer

OK, i have a couple of inputs. I have this code to validate them.

$("#form1").submit(function(){
    var isFormValid = true;

    $("#first_name").each(function(){
        if ($.trim($(this).val()).length == 0){
            isFormValid = false;
        }
    });

    if (!isFormValid) alert("Please Enter Your First Name");
    return isFormValid;
});

$("#form1").submit(function(){
    var isFormValid = true;

    $("#last_name").each(function(){
        if ($.trim($(this).val()).length == 0){
            isFormValid = false;
        }
    });

    if (!isFormValid) alert("Please Enter Your Last Name");
    return isFormValid;
});    

    $("#form1").submit(function(){
    var isFormValid = true;

    $("#dropdown").each(function(){
        if ($.trim($(this).val()).length == 0){
            isFormValid = false;
        }
    });

    if (!isFormValid) alert("Please Select Your Volunteer Choice");
    return isFormValid;
});

For some reason, i get a message after a message. What i was aiming for is that it only show me the next field that has not been field out, not all of them at the same time. If you have a question, please comment, it is hard to explain….do not down vote until you give me a chance to better explain.

Answer by bfavaretto

Here is how to simplify your code, and make it work like intended.

First, since you use the same method to validate all the fields, wrap that in a function instead of repeating the code:

function isFieldEmpty(jQuerySelector) {
    return $.trim($(jQuerySelector).val()).length == 0
}

Second, use a single submit handler to check everything, and return false if any field does not pass validation:

$("#form1").submit(function(){

    if(isFieldEmpty('#first_name')) {
        alert("Please Enter Your First Name");
        return false;
    }

    if(isFieldEmpty('#last_name')) {
        alert("Please Enter Your Last Name");
        return false;
    }

    if(isFieldEmpty('#dropdown')) {
        alert("Please Select Your Volunteer Choice");
        return false;
    }

    // Will return true only if all fields passed
    return true;
});

Answer by Starx

This is because of the redundancy on your code, same function, same identifier, same logic, same event handler, useless each with an id selector.

The only thing different are the subjects. Here is my suggestion.

$("#form1").submit(function(){
    var errors = [];
    if($("#first_name").val().length == 0){
       errors.push("Please Enter Your First Name");
    }

    if($("#last_name").val().length == 0){
       errors.push("Please Enter Your Last Name");
    }
    // and so on

    if(var isFormValid = errors.length > 0) { 
         alert('you have errors'); 
         //errors contains all the error message if you need them
    }
    return isFormValid;
});
Read more
April 30, 2012

Multiple-choice picture quiz for young students

Question by Sean

I’m trying to make a quiz with multiple submit buttons. I want a picture to appear with ten buttons. Each time the test-taker presses a button I want the value to be posted and the picture to change. So far I’ve tried three approaches:-

1.Using onclick and javascript I could get all the animation done but the values didn’t get posted. From Google I get the impression I’d have to use more javascript to submit the values?

2.Using variables in php the first picture would show and first value would post but then nothing happened, adding a loop meant that all the pictures appeared on top of the other without waiting for any buttons to be clicked…

3.I tried doing separate html pages for each picture, the value then gets posted to a php file, which does $score++; and goes to the next html file, but then the $score isn’t right. Because it’s a local variable? Would this mean I’d have to hold the value in MySQL to get at it? Also this seems a very wasteful way to program the whole thing…

Here is the code for no. 2:

<?php
include 'header.php';

if ($round==1) {$ans='Banana';}
if ($round==2) {$ans='Book';}
if ($round==3) {$ans='Pencil';}
...and so on

if ($_POST['submit']==$ans) {$score++; echo "Right!"; $round++; }
else
{$round++;}
?>

<html>
<form action="index.php" method="post">

<input type="submit" class="button1"  name="submit" value="Banana">
<input type="submit" class="button2" name="submit" value="Balloon">
<input type="submit" class="button3" name="submit" value="Dog">
<input type="submit" class="button4" name="submit" value="Mouse">
<input type="submit" class="button5" name="submit" value="Chair">
<input type="submit" class="button6" name="submit" value="Twelve">
<input type="submit" class="button7" name="submit" value="Pen">
<input type="submit" class="button8" name="submit" value="Book">
<input type="submit" class="button9" name="submit" value="Ball">
<input type="submit" class="button10" name="submit" value="Elephant">
</form>
</html>

<?php

if($ans=="Banana")
{   
echo '<img src="Banana.png" id="picture" class="picture" height="600" width="600" alt="script.aculo.us" />';
}
if($ans=="Pencil")
{   
echo '<img src="Pencil.png" id="picture" class="picture" height="600" width="600" alt="script.aculo.us" />';
}
{   
echo '<img src="Book.png" id="picture" class="picture" height="500" width="500" alt="script.aculo.us" />';
}
...and so on

include 'footer.php';

?>

Any help would be greatly appreciated 🙂

Answer by Starx

Among the approaches, the third one is better than others. Generally on MCQ pages, the question are kept or separate pages. The problem with your local variable can you solved if you use sessions

$_SESSSION['score'] += $score
echo $_SESSION['score'];
Read more

using values from one mysql function for a second function

Question by rob melino

I am trying to query my database and create values for later use in another function. My first function (get_users()) should query the requests database and find all users listed for the specific global_id – there will always be a maximum of 4 users for this query. Then I want to use a second function (get_results()) and insert the values that were retrieved from the first function (get_users()) into the second function. In other words, i need to put users1,2,3,4 into get_results($user1, $user2, $user3, $user4) in the second function.

Hoping someone can help! Here are my functions:

        function get_users($global_id)
    {
        $result = mysql_query("SELECT user_purchased FROM requests WHERE global_id = '$global_id'");
        $row = mysql_fetch_row($result);
        $user1 = $row[0];
        $user2 = $row[0];
        $user3 = $row[0];
        $user4 = $row[0];
    }
    function get_results($user1, $user2, $user3, $user4)
    {
        $result = mysql_query("SELECT * FROM results WHERE username != '$user1'
        AND username != '$user2'
        AND username != '$user3'
        AND username != '$user4'
        ORDER BY distance");
        ...more stuff to do here with the query
    }

Thanks

Answer by Hamurabi

Call the second function inside the first one:

function get_users($global_id)
    {
        $result = mysql_query("SELECT user_purchased FROM requests WHERE global_id = '$global_id'");
$count = 0;        
while($row = mysql_fetch_array($result))
        {
        $user[$count] = $row;
        $count++;
        }
    get_results($user[0],$user[1],$user[2],$user[3]);
    }

    function get_results($user1, $user2, $user3, $user4)
    {
        $result = mysql_query("SELECT * FROM results WHERE username != '$user1'
        AND username != '$user2'
        AND username != '$user3'
        AND username != '$user4'
        ORDER BY distance");
        ...more stuff to do here with the query
    }

You can even simplify the get_results function to have one variable as an array instead of 4 varialbles

function get_results($users)
        {
            $result = mysql_query("SELECT * FROM results WHERE username != '".$users[0]."'
            AND username != '".$users[1]."'
            AND username != '".$users[2]."'
            AND username != '".$users[3]."'
            ORDER BY distance");
            ...more stuff to do here with the query
        }

And you should call it like this in the first function

get_results($users);

Answer by Starx

Send the values as parameter to the another function.

function get_users($global_id)
{
    $result = mysql_query("SELECT user_purchased FROM requests WHERE global_id = '$global_id'");
    $row = mysql_fetch_row($result);
    $user1 = $row[0];
    $user2 = $row[0];
    $user3 = $row[0];
    $user4 = $row[0];

    //now send
   get_results($user1, $user2, $user3, $user4);
}
Read more
...

Please fill the form - I will response as fast as I can!