Display a long IP as a string transparently

I have a model in my application that stores an IP address. I find it most efficient for my database to store information in the form of an IP long (to provide backwards compatibility), but I would like the user to always interact with IP addresses as strings. Does anyone know a way to set up a rule in the model class to automatically convert the long IP address to a string and vice versa without having to manually specifying it in the views/controllers.

For example, I would really like to have the automatically generated CRUD code from Gii show the IP’s as strings ‘xx.xx.xx.xx’ without having to edit them to use the ip2long method and making the controllers controllers do the input validation.

You could write a behavior to handle this. Then you can edit CRUD templates to include this behavior.

Are you sure you don’t want to use inet_ntop/inet_pton instead? And yes, a behavior were the way to go.

Untested and possibly broken. But that’s about how you do it:




<?php

class PackedIpBehavior extends CActiveRecordBehavior

{

	public $fields=array();

	

	public function beforeSave($event)

	{

		if(!is_array($this->fields))

			$this->fields=array($this->fields);

		

		foreach($this->fields as $field=>$value)

		{

			if($value===null)

				continue;

			if(($value=inet_ntop($value))===false)

			{

				$class=get_class($this->owner);

				Yii::log("Could not pack value '{$this->owner->{$field}}' in {$class}.{$field}. Setting to NULL", 'debug', 'PackedIpBehavior');

				$this->owner->{$field}=NULL;

				continue;

			}

			$this->owner->{$field}=$value;

		}

		parent::beforeSave($event);

	}

	

	public function afterFind($event)

	{

		if(!is_array($this->fields))

			$this->fields=array($this->fields);

		

		foreach($this->fields as $field=>$value)

		{

			if($value===null)

				continue;

			if(($value=inet_pton($value))===false)

			{

				$class=get_class($this->owner);

				Yii::log("Could not unpack value '{$this->owner->{$field}}' in {$class}.{$field}", 'debug', 'PackedIpBehavior');

				continue;

			}

			$this->owner->{$field}=$value;

		}

		

		parent::afterFind($event)

	}

}



Edit: This is junk, please don’t use this behaviour as is. Give me some time to sort it out …