Can PHP realize something like structure in C

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
lixmde
Forum Newbie
Posts: 1
Joined: Mon Jul 29, 2002 2:00 am

Can PHP realize something like structure in C

Post by lixmde »

:?: In C, it is very easy to realize this:

typedef struct user {
int ID;
char name[50]; //fixed length
}

fwrite(fp, lpbuffer, sizeof(struct user);

can PHP provide the similar function? Any sugguestion will be appreciated
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

you may use classes and serialize them
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

I've thought about this too. The only thing I could think of that would come close would be a class that ecapsulates the data you wish to store/work with in addition to having a way to get and set that data. Hopefully with that, you could mimic (somewhat) the use and advantages of a structure.

Just an idea..... :?

Later on,
BDKR
User avatar
llimllib
Moderator
Posts: 466
Joined: Mon Jul 01, 2002 2:19 pm
Location: Baltimore, MD

Post by llimllib »

Since all variables in PHP are public, a class with no methods should be exactly the same as a strct in C, I believe.
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

You know, I didn't think you could create a class in PHP without methods, but I just got away with it. However, if there is a need to iterate over those vars, ?

Code: Select all

<?php
# Test a class with no methods

class Struct
  &#123;
  var $count = 0;
  var $initial = B;
  &#125;

# Instantiate object
$my_struct = new Struct;

# Echo a value
echo $my_struct->initial;

# Change a value
$my_struct->count = 1;

# Echo the value that was just changed
echo $my_struct->count; echo "\n";
?>
Now this all works, but I still can't think of how one would iterate over the vars in the struct object........ wait a sec ..........

OK, you could use something like this to iterate over the values if need be.

Code: Select all

# Remember, $my_struct is the object. Also, I am just echoing the information 
# back for the example. One can do whatever they wish between the "&#123; &#125;"'s. 
while(list($key, $data)=each($my_struct))
    &#123; echo "$key = $data"; &#125;
When you get right down to it, there is a ton of things that can be done. And this is no doubt a way of creating structures. However, I can't help but wonder how slow it is comparitively speaking as we are using objects. I am willing to bet that something like

Code: Select all

$struct array(
    $count => "0",
    $initial => "B"
    );
would be faster. But of course, the advantage of objects is that they can act as templates that are easily recreated.

Blah blah blah..... I'll shut up now..... :?
Later on,
BDKR
User avatar
llimllib
Moderator
Posts: 466
Joined: Mon Jul 01, 2002 2:19 pm
Location: Baltimore, MD

Post by llimllib »

I agree entirely, the speed is probably going to be very poor compared to either an array or a C struct.
Matt Wade
Forum Newbie
Posts: 12
Joined: Sat May 04, 2002 7:47 pm

Post by Matt Wade »

Using a class rather than array seems to run about 10-12% slower in my tests. Here is a simple test script I used:

Code: Select all

<?
function getmicrotime()&#123; 
	list($usec, $sec) = explode(" ",microtime()); 
	return ((float)$usec + (float)$sec); 
&#125; 

class Struct &#123;
	var $count = 0;
&#125;

$time_start = getmicrotime();
$struct = new Struct;

for($i = 0;$i < 100000; $i++) &#123;
	$struct->count = $i;
&#125;
$time_end = getmicrotime();
echo "Using a class took: " . ($time_end - $time_start) . "seconds.<BR>\n";

$time_start = getmicrotime();
$array = array(1 => 0);

for($i = 0;$i < 100000; $i++) &#123;
	$array&#1111;1] = $i;
&#125;
$time_end = getmicrotime();
echo "Using an array took: " . ($time_end - $time_start) . "seconds.<BR>\n";
?>
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

Yeah I figured as much. Heres something you might want to take a look at along those lines.

http://php.weblogs.com/discuss/msgReader$537?mode=day

Later on,
BDKR
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

Recently hit upon this same idea with the aim of clarifying some class scripts.

Suppose you have a relatively busy class: there's all kinds of "intermediate" vars in there which you use to build maybe half a dozen or so output vars. Creating a method-less object to encapsulate just the output vars helped focus what is actually printing out from the morass of code.

Although there's no real need for any kind of interface, adding a single setter and getter lets you attach behaviours to these actions (why I didn't just use an array):

Code: Select all

<?php

class PostPageVars
{

    var $var1 = null;
    var $var2 = null;
    // ..etc..

    function setVar($name, $value) 
    {
        $this->$name = $value;
        echo 'PostPageVars ' . $name . ' is ' . $this->$name . '<br />'; 
    }

    function getVar($name) 
    {
        #/*
        if(is_null($this->$name)) 
        {
            echo $name . ' is null.<br />';
        
        } else {
        
            echo $name . ' is ' . $this->$name . '.<br />';
        }
        #*/
        return $this->$name;                
    }

}
?>
That helped enormously when I began testing a redesigned forum posts list script which has about 8 or 9 interacting objects (echo's are commented on and off as needed).

Methods getVar & setVar could equally provide some handy "sockets" to attach other kinds of behaviour to get and set actions, in other uses.
Last edited by McGruff on Wed Aug 10, 2005 5:24 pm, edited 1 time in total.
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

Matt Wade wrote:Using a class rather than array seems to run about 10-12% slower in my tests. Here is a simple test script I used:

Code: Select all

<?
function getmicrotime(){ 
	list($usec, $sec) = explode(" ",microtime()); 
	return ((float)$usec + (float)$sec); 
} 

class Struct {
	var $count = 0;
}

$time_start = getmicrotime();
$struct = new Struct;

for($i = 0;$i < 100000; $i++) {
	$struct->count = $i;
}
$time_end = getmicrotime();
echo "Using a class took: " . ($time_end - $time_start) . "seconds.<BR>\n";

$time_start = getmicrotime();
$array = array(1 => 0);

for($i = 0;$i < 100000; $i++) {
	$array[1] = $i;
}
$time_end = getmicrotime();
echo "Using an array took: " . ($time_end - $time_start) . "seconds.<BR>\n";
?>
I wonder if these little changes help a little.

Code: Select all

<?
function getmicrotime(){ 
	list($usec, $sec) = explode(" ",microtime()); 
	return ((float)$usec + (float)$sec); 
} 

class Struct {
	var $count = 0;
}

$time_start = getmicrotime();
$struct = new Struct;

for($i = 0;$i < 100000; ++$i) {
	$struct->count = $i;
}
$time_end = getmicrotime();
echo "Using a class took: " . ($time_end - $time_start) . "seconds.<BR>\n";

$time_start = getmicrotime();
$array = array(1 => 0);

for($i = 0;$i < 100000; ++$i) {
	$array['1'] = $i;
}
$time_end = getmicrotime();
echo "Using an array took: " . ($time_end - $time_start) . "seconds.<BR>\n";
?>
I equalized this a bit by making the array element that we are incrementing associative as opposed to indexed. That's more fair. I also pre-incremented as it's faster to do so. Unless there's a specific need to post increment, I feel it's better to pre.

Anyways, I came up with...

Using a class took: 0.255446076393seconds.
Using an array took: 0.288635015488seconds

Curious eh?

Cheers,
BDKR
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

Sorry that I just can't shut up here. Here's something else that I found. By changing

Code: Select all

$array = array('1' => 0);

for($i = 0;$i < 100000; ++$i) {
	$array['1'] = $i;


to

Code: Select all

$array = array('one' => 0);

for($i = 0;$i < 100000; ++$i) {
	$array['one'] = $i;
Increased the performance of the array to where it's a smidgen faster than using the struct. This is strange to me as '1' and 'one' are both strings and would both be associative elements in the $array array. Is there something I don't know about here?

Cheers,
BDKR
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

McGruff wrote: Methods getVar & setVar could equally provide some handy "sockets" to attach other kinds of behaviour to get and set actions, in other uses.
This idea of 'sockets' you have sounds interesting. Do you think you could elaborate?

Cheers,
BDKR
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

A "socket" would be a wrapper of some kind. Suppose you defined a dbQuery() fn:

Code: Select all

<?php
function dbQuery($mysql) 
{
    $query = mysql_query($mysql) OR die('Error: ' . mysql_errno() . ' - ' . mysql_error() . '<br />');
    return $query;
}
?>
dbQuery would be a socket in as much as you can, with a quick edit of the fn def, make an edit across the whole program - maybe to change the error reporting level for live/local or to switch to a db other than mysql.

The getVar & setVar methods in above post would similarly let you attach a behaviour to get/set actions with a quick edit - I used this to help debug a tricky script with lots of interacting objects. Once it was working, I could just discard the echo lines.

The idea is that something is wrapped in something else - a fn in a fn or maybe an object in another, handler object. Throughout a program, the script is calling the wrapper: editing the wrapper def lets you "plug in" a different fn/object/behaviour across the whole program with one quick edit.

Maybe this is one way where a structure might win out over an array. With getVar and setVar you can trigger an action each time you get or set. It's not quite methodless any more but it's still being treated as a container, now with a simple interface.

Must admit I haven't a clue what a structure in C is or is used for so maybe I'm going a bit OT here.
Post Reply