Solved

Is this an example of a fluent interface?

Posted on 2014-11-20
5
81 Views
Last Modified: 2014-11-25
I have a Class that has within it two methods. The first method grabs an ID that's arriving from a form and, via a select statement, retrieves the name of the table that corresponds to that ID.

The next method's job is to retrieve the column names of the table the previous method has ascertained.

It looks like this:

class TableData {

	public $table_name;

	function TableName()
	{
		global $mysqli;

		$sql="select table_name from tools where id='$_POST[table_id]'";
			if(!$query=$mysqli->query($sql))
			{
				$err=$mysqli->errno.': '.$mysqli->error;
				trigger_error($err, E_USER_WARNING);
			}
		$row=$query->fetch_object();
		$the_name=$row->tool_name;
		
		$this->table_name=$the_name;
	}

	function TableInfo()
	{
		global $mysqli;
		
		$sql = "show columns from $table_name";
		$query = $mysqli->query($sql);
		
		if(!$query)
		{
		$error = $mysqli->errno.': '.$mysqli->error;
		trigger_error($error, E_USER_WARNING);
		}
		
		$data_count=mysqli_num_rows($query);
		
		if($data_count==0)
		{
		trigger_error("you don't have any column names", E_USER_WARNING);
		}
		//return $data_count;
		
		while($show_columns=$query->fetch_object())
		{
		$the_columns[]=$show_columns->Field;
		}
		return $the_columns;
	}
}

Open in new window


I imagine you could retrieve the name of the table and then pass it on as a variable into a subsequent function, but I'm thinking there's a more elegant way to do this. As I was looking for some answers I stumbled upon the term "fluent interface" and I'm not sure if that's what I'm looking for, but there it is.

Can I set in motion a "daisy chain" of methods by instantiating one Class? If so, how. If not, what are my options in terms of sound programming?
0
Comment
Question by:brucegust
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
5 Comments
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 400 total points
ID: 40456172
"Fluent interfaces" usually have, as you referred to them, a daisy chain of methods that read almost like a sentence. The gist of creating such an interface is that each method returns something that the next method expects as input, or an object to act against. Usually this thing is the object itself. So in reality you are always working with the same instance; you're just chaining together instance method calls. Wiki shows a good example of this.

You'll need to be careful in how you design such an interface as you can easily end up putting too much into the class for the sake of fluency, and ultimately end up violation the single responsibility principle.
0
 

Author Comment

by:brucegust
ID: 40456192
Kaufmed - thanks for getting back with me!

I had already seen the example you referenced on the Wiki page. Thing is, I couldn't figure out how to do it in the context of my scenario.

Going back to that for a moment, I was able to get it to work. Here's my Class:

class TableData {

	public $table_name;

	function TableName()
	{
		global $mysqli;

		$sql="select table_name from tools where id='$_POST[table_id]'";
		if(!$query=$mysqli->query($sql))
			{
				$err=$mysqli->errno.': '.$mysqli->error;
				trigger_error($err, E_USER_WARNING);
			}
		$row=$query->fetch_object();
		$the_name=$row->table_name;
		
		return $the_name;
	}

	function TableInfo($table_name)
	{
		global $mysqli;
		
		$sql = "show columns from $table_name";
		echo $sql;
		$query = $mysqli->query($sql);
		
		if(!$query)
		{
		$error = $mysqli->errno.': '.$mysqli->error;
		trigger_error($error, E_USER_WARNING);
		}
		
		$data_count=mysqli_num_rows($query);
		
		if($data_count==0)
		{
		trigger_error("you don't have any column names", E_USER_WARNING);
		}
		//return $data_count;
		
		while($show_columns=$query->fetch_object())
		{
		$the_columns[]=$show_columns->Field;
		}
		return $the_columns;
	}
}

Open in new window


And then here's what I instantiated things so I could get my needed result:

$table_stuff=new TableData;
$table_handle=$table_stuff->TableName();
$columns = $table_stuff->TableInfo($table_handle);

It works! But if I were looking to something a little more elegant / streamlined and I wanted one call, one Class and one result, how would that look? Can that be done?
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 400 total points
ID: 40456210
I would expect something more along the lines of:

class TableData {
    private $table_name;
    
    function FetchTableName()
    {
        global $mysqli;

        $sql="select table_name from tools where id='$_POST[table_id]'";
        if(!$query=$mysqli->query($sql))
            {
                $err=$mysqli->errno.': '.$mysqli->error;
                trigger_error($err, E_USER_WARNING);
            }
        $row=$query->fetch_object();
        $table_name=$row->table_name;
        
        return $this;
    }
    
    function GetTableData()
    {
        global $mysqli;
        
        $sql = "show columns from $table_name";
        echo $sql;
        $query = $mysqli->query($sql);
        
        if(!$query)
        {
            $error = $mysqli->errno.': '.$mysqli->error;
            trigger_error($error, E_USER_WARNING);
        }
        
        $data_count=mysqli_num_rows($query);
        
        if($data_count==0)
        {
            trigger_error("you don't have any column names", E_USER_WARNING);
        }
        //return $data_count;
        
        while($show_columns=$query->fetch_object())
        {
            $the_columns[]=$show_columns->Field;
        }

        return $the_columns;
    }
}

Open in new window


And then used as:

$table = new TableData();
$data = $table->FetchTableName()
              ->GetTableData();

Open in new window

0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 40456214
Notice that the first call, FetchTableName, returns the object itself, not any data. Only the last call in the chain returns something other than the object itself.
0
 
LVL 110

Assisted Solution

by:Ray Paseur
Ray Paseur earned 100 total points
ID: 40456421
This appears in the Wikipedia article:
<?php
class Employee
{
    public $name;
    public $surName; 
    public $salary;
 
    public function setName($name)
    {
        $this->name = $name;
 
        return $this;
    }
 
    public function setSurname($surname)
    {
        $this->surName = $surname;
 
        return $this;
    }
 
    public function setSalary($salary)
    {
        $this->salary = $salary;
 
        return $this;
    }
 
    public function __toString()
    {
        $employeeInfo = 'Name: ' . $this->name . PHP_EOL;
        $employeeInfo .= 'Surname: ' . $this->surName . PHP_EOL;
        $employeeInfo .= 'Salary: ' . $this->salary . PHP_EOL;
 
        return $employeeInfo;
    }
}
 
# Create a new instance of the Employee class:
$employee = new Employee();
 
# Employee Tom Smith has a salary of 100:
echo $employee->setName('Tom')
              ->setSurname('Smith')
              ->setSalary('100');
 
# Display:
# Name: Tom
# Surname: Smith
# Salary: 100

Open in new window

These scripts below do essentially the same thing.  Look at the notation near the end to see the variations on the code.  When in doubt, I always try to choose the code style that is easier to read and modify.  There's something about integrating a setter method into an echo statement that makes me vaguely queasy.

<?php // demo/temp_brucegust.php
error_reporting(E_ALL);

class Employee
{
    public $name;
    public $surName;
    public $salary;

    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    public function setSurname($surname)
    {
        $this->surName = $surname;

        return $this;
    }

    public function setSalary($salary)
    {
        $this->salary = $salary;

        return $this;
    }

    public function __toString()
    {
        $employeeInfo = 'Name: ' . $this->name . PHP_EOL;
        $employeeInfo .= 'Surname: ' . $this->surName . PHP_EOL;
        $employeeInfo .= 'Salary: ' . $this->salary . PHP_EOL;

        return $employeeInfo;
    }
}

# Create a new instance of the Employee class:
$employee = new Employee();

# Employee Tom Smith has a salary of 100:
$employee->setName('Tom')->setSurname('Smith')->setSalary('100');
echo $employee;

Open in new window

<?php // demo/temp_brucegust.php
error_reporting(E_ALL);

class Employee
{
    public $name;
    public $surName;
    public $salary;

    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    public function setSurname($surname)
    {
        $this->surName = $surname;

        return $this;
    }

    public function setSalary($salary)
    {
        $this->salary = $salary;

        return $this;
    }

    public function __toString()
    {
        $employeeInfo = 'Name: ' . $this->name . PHP_EOL;
        $employeeInfo .= 'Surname: ' . $this->surName . PHP_EOL;
        $employeeInfo .= 'Salary: ' . $this->salary . PHP_EOL;

        return $employeeInfo;
    }
}

# Create a new instance of the Employee class:
$employee = new Employee();

# Employee Tom Smith has a salary of 100:
$employee->setName('Tom');
$employee->setSurname('Smith');
$employee->setSalary('100');
echo $employee;

Open in new window

0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Checking https returns 301 21 62
Compiling PHP with Curl plus protocols 8 25
blocking the posted data from outside of my domains 8 25
PHP $_POST vs asp request 4 28
Popularity Can Be Measured Sometimes we deal with questions of popularity, and we need a way to collect opinions from our clients.  This article shows a simple teaching example of how we might elect a favorite color by letting our clients vote for …
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question