...

Hi! I’m Starx

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

PHP user-agent allowing to post on my site

Question by AlanPHP

I have a voting site that my users can use to promote my game. When they click the voting link, it passes a variable called ‘reference’ to the voting site. If it is a valid vote (in the past 24 hours) it will then send a request back to my site with two variables.

$reference = $_POST['referense'];
$success = $_POST['success']; // 0 or 1

I’ve read that the user-agent must be changed to allow them to post things to my site? How do I let them do this? It is a valid voting site, so there is no need to be scared.

Thanks.

Answer by Starx

What you read is completely wrong.

User agents have nothing to do with. how a PHP code performs. And even if it does, IT SHOULDN’T


You said that a reference is passed to the site, which is then sent to the voting system. So, your system should only check if the reference coming is a valid one or NOT. Not how the request is coming.

NOTE that, User Agents can be spoofed so easily. So, creating a system relying on such is very risky.

Read more
May 7, 2012

page doesn't stop loading – javascript

Question by Lan

what does it mean if the twirly thing in the tab of the page wont stop spinning, ie saying its loading?

i have a php for loop and in each one of these it throws out i have a javascript onload function with a for loop looking to see if that id (from mysql) is in the javascript cookie array.
hope that makes sense. it all works fine but wont stop loading.
anyway, i’ve played around with break and return false which stop the loading but then doesnt give me the results i want.

can anyone point me in the right direction?
thanks

this is the javascript function that is being called by an onload in the img tag that each loop created by the php for function is throwing out.
n is the id. secondarray is the cookie data put into a readable array.

function cookietest(n)
{ 
for (i = 0; i < secondarray.length; i++) 
{ 
if (secondarray[i] == "ca[]="+n  ) document.getElementById(n).src = "saved.png" ;
}
}

Answer by Starx

Checking length inside a loop is always a killer. And breaking out of a loop at certain point, helps you improve the performance too.

function cookietest(n)
{ 

    var l = secondarray.length;
    for (i = 0; i < l i++) 
    { 
        if (secondarray[i] == "ca[]="+n  ) {
          document.getElementById(n).src = "saved.png" ;
          break; //break out of loop it is no longer needed I GUESS
        }
    }

}

P.S: I am just answering based on the codes OP provided, the culprit could be others as well.

Read more

Sort an array by alphabetically by second word

Question by mdance

I am sorting a multidimensional array that contains peoples names and some information aobut them. I’m using asort($obj) to sort it alphabetically by their first names (it comes first). It works great, only now I need to sort it by their last name, rather than first. However, the name in its entirety “Joe Smith” for example is under the “name” key. I need it sorted by last name, instead of first. How can I do this?

EDIT
It seems that I went about it in the wrong way. It ended up easiest to simply assign the first and last name from the DB to separate fields, rather than the same string.

Answer by Starx

Not, so different than the previous answer. But, using a natural algorithm might be a good choice, on such situations.

$array = array( 
    array("first", "last"), 
    array("first2", "last2")
); //For an array of such format
function compare_last($a, $b) { return strnatcmp($a[1], $b[1]); } 
usort($array, 'compare_last');
Read more

Merging CSS files

Question by newbie

I have to merge CSS files to one big CSS file to reduce connections made during page load. Basically if I just append CSS files to one big file, are these styles going to work exactly like before, or are there any issues when you merge multiple CSS files together? I’m developing my software in Java, if there is some library that already does CSS merging, I would like to hear about that.

Answer by Mike Samuel

If your CSS files use @import, then merging them into one file might change the imported URLs.

When an @import has a relative URL it is resolved against the URL of the containing CSS, so you could end up inadvertently breaking @imports.

http://www.w3.org/TR/css3-values/

In order to create modular style sheets that are not dependent on the absolute location of a resource, authors should use relative URIs. Relative URIs (as defined in [URI]) are resolved to full URIs using a base URI. RFC 3986, section 3, defines the normative algorithm for this process. For CSS style sheets, the base URI is that of the style sheet, not that of the source document.

Answer by Starx

Use ANT build script from HTML Boilerplate, does the task you are attempting perfectly.

Read more

Are there any tips on getting HTML5 canvas to work in IE9?

Question by Richard

I have been developing a game in the HTML5/Javascript new canvas feature, and all is going great, until I started to test it on Internet Explorer 9. So I will vaguely ask, are there any tips on getting the game to work fully in IE9?

Here’s what I know:

1) I must include

<!DOCTYPE html5>

else IE9 cannot possibly figure out that I indeed intend to use HTML5, and not an older version.

2) IE9 must be explicity told to run in IE9 mode, and not in IE8 mode, since clearly everyone who upgrades to IE9 intends to run it in IE8 mode by default.

3) .ttf files make IE9 unhappy. This is a problem, because the font files that DO work with IE9 (namely, .eof) seem to be disregarded by Firefox and other real browsers. Any tips of getting this fixed?

4) Finally, my biggest problem, after getting all else to work: only SOME of the graphics get drawn to the screen. In short, the game’s “engine” is split into several systems. Some, such as the particles (basically, just a collection of moving spheres) are draw, while others, such as all of the sprites, are not drawn, but the health bar is drawn. They all use the same exact draw methods, so I really can’t wrap my head around why some work and some don’t. There’s a lot of stuff to draw, but again, real browsers handle it just fine.

I know this is vague, but I’m just hoping somebody has some experience with this and can link me to a proper tutorial or else give me a hint as to how I can go about fixing this. It seems to be a project all its own just to get IE9 to run the code that works perfectly on Firefox, Safari, Chrome and Opera. Thanks, all help is very much appreciated.

Answer by Joseph the Dreamer

  1. <!DOCTYPE html> only tells the browser to use standards mode. HTML5 was built to fail gracefully incase the browser supports it. An example is the datepicker input which gracefully fails on all browsers (except Opera which supports it) as a text type input.

    The DOCTYPE is retained in HTML5 as a “mostly useless, but required” header only to trigger “standards mode” in common browsers.

    The doctype does not tell the browser what version of HTML. That’s the DTD’s job. The DTD just tells the browser what’s valid markup in your markup. It’s only used in validation to determine what HTML you use (HTML or XHTML; loose, transitional or strict). In HTML5’s case, there is no DTD because there’s no use for it.

  2. You can force IE to render in it’s latest mode or in chrome frame with a meta command, but it’s usually unnecessary. Declaring strict mode using the doctype as well as using proper markup is enough to do the job.

    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    
  3. Paul Irish’s bulletproof @fontface syntax should put your fonts in an “all-in-one” syntax so that the same code can be loaded on all browsers.

  4. I don’t know about you but IE9+ has basic support and text support for canvas which is at par with the browsers of it’s age. IE even has it’s own testdrive page for versions 9 and up to show off their HTML5 support. There must be something wrong with your code.

Answer by Starx

HTML5 is already supported my IE9. Here is an example of it. Be sure check the developers guide while doing this.

Read more

What is wrong with this query? Why are results different locally?

Question by StackAttack

I am writing a php site using a mysql database for a class of mine and cannot for the life of me figure out what is wrong with it. I have a query that works locally on my machine (on an identical db to the one on the teacher’s server) but when I upload it, it doesn’t work. The problem is that the query is returning 0 results even though the db has info in it that should be showing.

function bigAssQuery($whereCondition)
{

    $queries[] = 'CREATE TEMPORARY TABLE subAssignments (SELECT ua.assignmentid, ua.assignmentnum, ua.description
                    FROM Course c JOIN UserAssignment ua ON ua.crn = c.CRN AND ua.term = c.term
                    WHERE c.CRN = "'.$_SESSION["crnum"].'" AND c.term = "'.$_SESSION["mysem"].'")';

    $queries[] = 'CREATE TEMPORARY TABLE subStudents (SELECT s.studentid, s.lastname, s.firstname
                    FROM Course c JOIN Student s ON s.crn = c.CRN AND s.term = c.term
                    WHERE c.CRN = "'.$_SESSION["crnum"].'" AND c.term = "'.$_SESSION["mysem"].'")';

    $queries[] = 'CREATE TEMPORARY TABLE subRubric(SELECT assignmentid, re.rubricelementid, re.learning_goal_char
                    FROM RubricElement re JOIN RubricAssignmentRelation rar ON re.rubricelementid = rar.rubricelementid)';

    $queries[] = 'CREATE TEMPORARY TABLE subAssignRub(SELECT subAssignments.assignmentid, rubricelementid, learning_goal_char, assignmentnum, description
                    FROM subRubric JOIN subAssignments ON subAssignments.assignmentid = subRubric.assignmentid)';

    $queries[] = 'CREATE TEMPORARY TABLE subAssignRubStud (SELECT *
                    FROM subAssignRub CROSS JOIN subStudents)';

    $queries[] = 'CREATE TEMPORARY TABLE subAssignInstRubStud (SELECT sars.assignmentid, ai.ainstanceid, rubricelementid, learning_goal_char, assignmentnum, description, sars.studentid, lastname, firstname
                    FROM subAssignRubStud sars LEFT JOIN AssignmentInstance ai ON sars.studentid = ai.studentid AND sars.assignmentid = ai.assignmentid)';

    $queries[] = 'CREATE TEMPORARY TABLE subTotal (SELECT assignmentid, siars.ainstanceid, s.ainstanceid As scoreAID, siars.rubricelementid, learning_goal_char, assignmentnum, description, studentid, lastname, firstname, score
                    FROM subAssignInstRubStud siars LEFT JOIN Score s ON siars.ainstanceid = s.ainstanceid AND siars.rubricelementid = s.rubricelementid
                    ORDER BY lastname, assignmentid)';

    $queries[] = 'SELECT *
        FROM subTotal
        '.$whereCondition.' Order By lastname, assignmentnum, learning_goal_char';  

    return($queries);
}

Then when the db is queried the code looks like this. . .

$queries = bigAssQuery($whereCondition);


$result = 1;
foreach($queries as $query)
{
    $result = $db->query($query);

    if(!$result)
    {
        echo '<script type="text/javascript"> 
                window.onload=function(){ alert("Error: Could not extract course information. Please try again later."); } 
             </script> ';
        exit;
    }
}

$num_rows = $result->num_rows;

I assure you that the local and remote databases are identical. I see no reason why no results are coming back. I did test a few simple temp tables to see if the server wasn’t reading those tables for some reason, but they weren’t an issue in my tests. I would try with nested subqueries, but it gets so convoluted so quickly that I can’t organize it. Maybe there is a better way?
Also, just to clarify the queries aren’t failing, they just aren’t returning anything when I know that they should.
I apologize for the wall of text, but any help is appreciated.

EDIT: I really don’t know which of the queries the problem lies. I do know that I’m probably missing some important information. Part of that lies in my web inexperience. I test locally first because I’ve got the debugger working, but I honestly don’t know how to do remote debugging. I’m using netbeans and xdebug. If someone could suggest a how to get remote debugging set up I would probably be able to come up with some better data. Any suggestions would be helpful

EDIT AGAIN: Found the problem. Embarrassingly enough it was an error in data entry; one of my foreign keys was incorrectly entered. Thanks everybody for pointing me in the right direction.

Answer by Starx

On having a quick look, your code is stoping the execution of the PHP inappropriately. You should at least the let the remainder to continue. Simply exit out of loop using break; instead.

if(!$result)
{
    echo '<script type="text/javascript"> 
            window.onload=function(){ alert("Error: Could not extract course information. Please try again later."); } 
         </script> ';
    break; //exit the loop only NOT THE PHP's Execution
}

Furthermore, check every query individually and run them separately on phpMyAdmin to see, if they are executing correctly. Find the break point and fix the error.

Read more
May 6, 2012

PHP OOP how to group configuration data

Question by cl0udw4lk3r

i wanna store some configuration data in some objects, and i’ve a problem…

class B {
  const attr1 = 'something1';
  const attr2 = 'something2';
  const attr3 = 'something3';
}

class A {
  const attr1 = 'somethingA1';
  const attr2 = 'somethingA2';
  const attr3 = 'somethingA3';
  const b = <---- i wanna put here a reference of B, but B as a class (not an object...), i'm crazy?
}

I’m not sure if my example is clear… from A, i want to access to attr1 of B, like A::B::attr1, or something like this, there’s another way to do this? Or i’m wrong?

Answer by Gordon

There is no way to assign reference to a Class, nor is there a way to assign class constants at runtime. So your entire approach is pretty much impossible. What you can do is

const b = 'B' 

and as of PHP 5.3.0 you could then do

$b = A::b;
echo $b::attr1;

but you cannot do A::b::attr1. This will raise a T_PAAMAYIM_NEKUDOTAYIM error. It’s a parser limitation. PHP cannot do this as of this writing.


Because the class B contains a group of data of A, i want to store in b (of A) a complex data, i want to do like this because i wanna keep the code clean

You can solve this easily by making B a composite of A, e.g. you either inject B into A when you create A

class A
{
    private $b;

    public function __construct(B $b)
    {
        $this->b = $b;
    }
}
$a = new A(new B);

or create B inside A, e.g.

class A
{
    private $b;

    public function __construct()
    {
        $this->b = new B;
    }
}

Because B is just the data parts of A, you tunnel all public access through A instead of getting hold of B and then using B’s methods. So any code using A does not need to know there is some B inside A. This will allow you to change B easily without needing to worry about code that consumes A, e.g. to get attr1 you add a getter to A:

public function getAttr1()
{
    $b = $this->b;
    return $b::attr1;
}

You can mitigate the clumsy need for assignment when using properties instead of constants in B (constants are stupid in PHP anyway as you have to treat them as public API), e.g.

class B
{ 
    private $attr1;

    public function getAttr1()
    {
        return $this->attr1;
    }
}

And then you can do in A:

public function getAttr1()
{
    return $this->b->getAttr1();
}

Even better would be not to expose the internals of B through A altogether though and only add public methods that do something with A. This will make your API much smaller and your code more OO.

Answer by Starx

You cannot reference to a class like that, because the only way you will ever use the class is through an object, so there is no point trying to do that either.

User this:

class A {
  const attr1 = 'somethingA1';
  const attr2 = 'somethingA2';
  const attr3 = 'somethingA3';
  public $b;

  function __construct() {
    $this -> b = new b();
}
Read more

PHP dynamic class extending

Question by tim

I know you can extend a class when constructing it like the following:

class b extends a {
}

But is it possible to dynamically extend classes from the scripts? Such as:

$b = new b($input) extends a;

What I wish to accomplish is to extend the module differnetly wheither it’s used in admin rather than the public pages. I know I can create two different parent classes by the same name and only include one per admin or public. But my question is, is it possible to do it dynamically in PHP?

Answer by Cory Carson

You can’t, but this has been requested for a few years: https://bugs.php.net/bug.php?id=41856&edit=1

You can define the classes within an eval, but it’s more trouble than declaring the class normally.

Answer by Starx

Yes, as cory mentioned, this feature has been requested before. But before that, you can create a workaround. Here is my old school trick for this

Create two separate classes like these:

class a {
}
class b {
   public $object;
}

Then, create an extended version too

class bextendeda extends a {
}

In the constructor method of class b, place few functions which redirects to the extended object if requested.

class b {
    public $object;

    public function __contruct($extend = false) {
        if($extend) $this -> object = new bextendeda(); 
        else $this -> object = $this;
    }

    function __get($prop) {
        return $this-> object -> $prop;
    }

    function __set($prop, $val) {
       $this-> object -> $prop = $val;
    }
    function __call($name, $arguments)
    {
        return call_user_func_array($this -> object, $arguments);
    }

}

And there you have it, IF you want the extended version just do this

$b = new b(true);

If not

$b = new b();

Enjoy 🙂

Read more

Changing ip address of apache server using php

Question by apurv nerlekar

I am trying to create a settings page(for the clients) where in they can view the current up address,change the ip address etc. I have a php file to view the ip address

 <?php
  $res=shell_exec("ifconfig");
  echo $res;
 ?>

This code works just fine and displays the expected result.
However the code to change the ip address of the server is not working properly.

 <?php
 shell_exec("ifconfig eth0 192.168.163.136");
 ?>

After running this code when i check the ipaddress on the terminal using ipaddr i don’t see any change in the ipaddress.
Pls point out where i am going wrong. I think its a problem of apache not being a super/root user. If that is the case i don’t know how to make apache run as a root user.

Answer by Starx

IP address are configured in Network Layer of an Network Protocol, not in application layer where PHP runs. Simply, PHP does not have access to it and cannot changed them.

Just imagine the vulnerabilities it could create if this was possible.

Read more

RegEx for <title> with leading, trailing, linebreak

Question by user1377738

Most website I can parse its title easily with RegEx “(.)” or “s(.+?)s*”. However some sites have a bit different formatting, like http://www.youtube.com (see below). The expression above does not work. Any help catching this kind of format and any other HTML formats?

Thanks
-Tim.

<title>
  YouTube - Broadcast Yourself.

Answer by Fèlix Galindo Allué

If you want to include the line break to the regular expression, in most cases you would only need to use the n inside the expression. That said, which language/interpreter are you using? Some of them doesn’t allow multiline expressions.

If they are permitted, something like (.|n|r)* would suffice.

In case your language or interpreter is not compatible to multiline regular expressions, you could always replace the newlines characters with spaces, and then pass the resulting string to the regular expression parser. That again also depends on your programming environment.

Hope helped!

Answer by Starx

There are various ways to get this done. For only title, SIMPLEHTMLDOM is more than enough.

$html = file_get_html('http://www.youtube.com/');
$title = $html -> find("title") -> innerHTML;
echo $title;
Read more
...

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