...

Hi! I’m Starx

experienced Software Developer. And this is my blog
Start Reading About me
Blog Page

Does PHP have an answer to Java style class generics?

Question by Jonathan

Upon building an MVC framework in PHP I ran into a problem which could be solved easily using Java style generics. An abstract Controller class might look something like this:

abstract class Controller {

abstract public function addModel(Model $model);

There may be a case where a subclass of class Controller should only accept a subclass of Model. For example ExtendedController should only accept ReOrderableModel into the addModel method because it provides a reOrder() method that ExtendedController needs to have access to:

class ExtendedController extends Controller {

public function addModel(ReOrderableModel $model) {

In PHP the inherited method signature has to be exactly the same so the type hint cannot be changed to a different class, even if the class inherits the class type hinted in the superclass. In java I would simply do this:

abstract class Controller<T> {

abstract public addModel(T model);


class ExtendedController extends Controller<ReOrderableModel> {

public addModel(ReOrderableModel model) {

But there is no generics support in PHP. Is there any solution which would still adhere to OOP principles?

Edit
I am aware that PHP does not require type hinting at all but it is perhaps bad OOP. Firstly it is not obvious from the interface (the method signature) what kind of objects should be accepted. So if another developer wanted to use the method it should be obvious that objects of type X are required without them having to look through the implementation (method body) which is bad encapsulation and breaks the information hiding principle. Secondly because there’s no type safety the method can accept any invalid variable which means manual type checking and exception throwing is needed all over the place!

Answer by GordonM

It appears to work for me (though it does throw a Strict warning) with the following test case:

class PassMeIn
{

}

class PassMeInSubClass extends PassMeIn
{

}

class ClassProcessor
{
    public function processClass (PassMeIn $class)
    {
        var_dump (get_class ($class));
    }
}

class ClassProcessorSubClass extends ClassProcessor 
{
    public function processClass (PassMeInSubClass $class)
    {
        parent::processClass ($class);
    }
}

$a  = new PassMeIn;
$b  = new PassMeInSubClass;
$c  = new ClassProcessor;
$d  = new ClassProcessorSubClass;

$c -> processClass ($a);
$c -> processClass ($b);
$d -> processClass ($b);

If the strict warning is something you really don’t want, you can work around it like this.

class ClassProcessor
{
    public function processClass (PassMeIn $class)
    {
        var_dump (get_class ($class));
    }
}

class ClassProcessorSubClass extends ClassProcessor 
{
    public function processClass (PassMeIn $class)
    {
        if ($class instanceof PassMeInSubClass)
        {
            parent::processClass ($class);
        }
        else
        {
            throw new InvalidArgumentException;
        }
    }
}

$a  = new PassMeIn;
$b  = new PassMeInSubClass;
$c  = new ClassProcessor;
$d  = new ClassProcessorSubClass;

$c -> processClass ($a);
$c -> processClass ($b);
$d -> processClass ($b);
$d -> processClass ($a);

Answer by Starx

I did went through the same type of problem before. And I used something like this to tackle it.

Class Myclass {

    $objectParent = "MyMainParent"; //Define the interface or abstract class or the main parent class here
    public function method($classObject) {
        if(!$classObject instanceof $this -> objectParent) { //check 
             throw new Exception("Invalid Class Identified");
        }
        // Carry on with the function
    }

}
Read more

php reporting tools

Question by sdemirkeser

I have been developing php for over ten years (from php version 3) and have used lots of programming language.

But I have never seen php reporting tools. I am looking for platform such as

  • Jasper Report
  • Crystal Report
  • Fast Report
  • Quick Report
  • Report Builder

What I am not looking for;

  • FPDF
  • PHPExcel
  • TCPDF

I am there must be designer and report library.

Has anyone seen php reporting tools like these mentioned platforms.

Answer by Starx

Well, judging by your example, you are looking for tools to represent the data. So, here are few you might like


Check this question to use Crystal Reports with php.

Read more

Iterate through session array?

Question by 3D-kreativ

I haven’t use PHP for some time, and I need some help to create some lines of code. I wrote this line of code some years ago for a website

array_push($_SESSION['buildingsAlreadySeenList'],$id);

This is my problem, I just want to iterate through the array and put the first value at index 0 to $buildingId and then next time put the value of index 1 to $buildingId with som While loop i guess? I know it’s easy, but sadly I haven’t used PHP for some time! Preciate the help! Thanks!

Answer by Starx

Use foreach()

foreach($_SESSION['buildingsAlreadySeenList'] as $id => $value) {
    echo $id; // this is the index and for the first time this is like to give o if the indexes were not manipulated somehow

    //put the index value to buildingid
    $buildingId = $id;
    echo $value; //the actual value of the array
}

Update

To check if the array is empty count the variables

if(count($_SESSION['buildingsAlreadySeenList'])) { 
   //array is not empty
} else {
   //array is empty
}
Read more

Send params in URL in different way?

Question by Student

I don’t know how to write title for this question. Anyway this is the scenario ..

I have a table like this

Person

id | username | firstname | lastname
 1 |    ab    |     Aaaa  |    Bbbb
 2 |    yz    |     Yyyy  |    Zzzz

I use following URL to show person profile:

example.com/person/profile/index?id=1   // Show person 1 profile
example.com/person/profile/index?id=1   // Show person 2 profile

Here: person is module, profile is controller and index is action used to get and show user profile using param id

Above scenario is working perfectly.

Question:

Now I want to use following URLs to get user profile using usernames

example.com/person/profile/ab   // Show person 1 profile
example.com/person/profile/yz   // Show person 2 profile

Any idea ??

Thanks

Answer by Starx

By default you don’t need to do anything. Just add /name/THENAME to the last of the url.

Then,

  1. Get the value of the name

    $name = $this -> _request -> getParam('name');
    
  2. Use that values to extract the id from the database

  3. And use it as you want
Read more

How do you stop people from editing a disabled inputbox?

Question by 001

When a input textbox is disabled, you can not enter any values into the Inputbox.

However if you use google chrome and right click on the inputbox then click on inspect, you can change the values.

How do you stop people from editing a disabled inputbox?

Answer by Starx

There is no way you can stop people from changing its state and sending the data. There are two way you can do this

  1. Do not display the disabled input at all. Just like what Zend_Form does.
  2. Check the field when the form was submitted and remove it.
Read more

remove line height from the second line

Question by Sowmya Shivaram

I have given line height of 60px for a tag but wen content is more, it goes to second line but even second line is taking line height of 60px. How do I remove line-height from second line?

Here line height is necessary to vertically middle align the text to div.

a.pname
{ font-family:Verdana, Geneva, sans-serif; font-size:14px; 
color:#000; text-align:left; font-weight:normal;
text-decoration:none; line-height:65px; 
float:left; background-color:#090; width:190px 
}

Answer by Starx

Use :first-line pseudoelement to select only the first line. Remove the line-height property from your style and add this

a.pname:first-line { line-height: 65px; }
Read more

jquery checkbox selcetion

Question by Sam Hanson

Please refer the url

http://jsfiddle.net/fnvXT/

Here while selecting the check box the corresponding row is selected. I want to change that as

only one will be highlighted at a time.

If i select check box 2 then the check box 2 will be checked and this row only be highlighted and remaining check box should unchecked and remove the highlighting.

How do i change this. Please do the needful. Thanks

Answer by TJ.

I added the following to the click handler:

$('input.high').not(this).attr('checked', null).closest('tr').css('background-color', '#fff');

See: http://jsfiddle.net/fnvXT/6/

Answer by Starx

Do not use .live() function it has been deprecated. Use .on() or .delegate() instead. Here is a simple solution to your problem

 $('.high').on('click', function(event) {          
        if ($(this).prop('checked')) {
             // if checked, reset all colors to white
             $("tr").css("background-color", "#ffffff");
             // find its parent row and change its color
             $(this).closest("tr").css("background-color", "#FFCC00");
        } else {
            // you only need to change its parent row in this case
            $(this).closest("tr").css("background-color", "#ffffff");
        }           

});

Demo

P.s. I have omitted the alternate row style in the row, to make things much simpler

Read more

pass string parameter in an onclick function

Question by Jaspack

I would like to pass a parameter (i.e. a string) too an Onclick function. For the moment, I do this like this:

'<input type="button" onClick="gotoNode(' + result.name + ')" />'

with result.name for example equal to string “Add”.
When I click on this button, I have an error that says that Add is not definied. Since this functioncall works perfect with a numeric parameter, I assume that it has something to do with the symbols “” in the string.
Did anyone had this problem before?

Answer by david

It’s looks like you’re building dom elements from strings. You just need to add some quotes around result.name:

'<input type="button" onClick="gotoNode('' + result.name + '')" />'

You should really be doing this with proper DOM methods though.

var inputElement = document.createElement('input');
inputElement.type = "button"
inputElement.addEventListener('click', function(){
    gotoNode(result.name);
});

​document.body.appendChild(inputElement);​

Just be aware that if this is a loop or something, result will change before the event fires and you’d need to create an additional scope bubble to shadow the changing variable.

Answer by Starx

I am guessing, you are creating a button using JavaScript itself. So, the error in your code is that, it will render in this form

<input type="button" onClick="gotoNode(add)" />'

At this current state, add will be considered as an identifier like variables or function calls. You should escape the value like this

'<input type="button" onClick="gotoNode('' + result.name + '')" />'
Read more
...

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