Page 2 of 2

Re: Xtend-It PHP Framework

Posted: Thu Sep 02, 2010 3:01 am
by alexs
Ok let's take it slow :)

I will post a first technique that i consider good & useful

It's a smart Autoload class that scans the framework folder and other folders you include by calling the ::AddWatchFolder static method
(due to it's nature the methods are static )

Advantages:

1. Forget about include & require
2. Freedom to move objects and reorganize them
3. Very fast, the location of the files is cached in a PHP file that APC will cache in memory
4. Zero maintenance required ! you will only need the ::AddWatchFolder method to add your new project's folder in the swarm

Techniques:

1. The object will "know" from the start where the files are as it generates a PHP cache file
2. The object will refresh the list only if it does not find a class (either moved or was not existent before)
3. If a class is not found even after the refresh an error will be triggered

Code: Select all

<?php
/**
 * @package qBase
 * @subpackage base
 */

/**
 * Automate the load of classes
 * Lowercase Files WILL BE SKIPPED !
 * The Autoload pattern is : ClassName.php
 */
function __autoload($class_name)
{
	// automate load of classes
	QAutoload::AutoloadClass($class_name);
}

/**
 * Helper class for the autoload of classes
 * @package qBase
 * @subpackage base
 */
final class QAutoload extends QObject 
{
	/**
	 * The folders to consider for Autoload
	 *
	 * @var array
	 */
	private static $WatchFolders = array();
	/**
	 * The list of classes in the framework (class_name => path)
	 *
	 * @var array
	 */
	private static $Classes = array();

	/**
	 * The list of classes in the framework with link to their watch folder (class_name => WatchFolder)
	 *
	 * @var array
	 */
	private static $ClassesWatchFolders = array();

	/**
	 * Automate the load of classes
	 * Will always skip the "temp" and "res" folders in the root of the watch folder
	 *
	 * @param string $class_name the name of the class to be loaded
	 */
	public static function AutoloadClass($class_name)
	{
		if (isset(self::$Classes[$class_name]))
		{
			if (file_exists(self::$Classes[$class_name]))
			{
				require_once(self::$Classes[$class_name]);
				return;
			}
			else 
				unset(self::$Classes[$class_name]);
		}
		
		self::RefreshObjectsTree();
		if (isset(self::$Classes[$class_name]))
			require_once(self::$Classes[$class_name]);
		else 
			throw new Exception("Class [{$class_name}] was not found");
	}
	
	/**
	 * Sets the path of a class
	 *
	 * @param string $class_name
	 * @param string $path
	 */
	public static function SetClass($class_name, $path, $watch_folder = null)
	{
		self::$Classes[$class_name] = $path;
		if ($watch_folder)
			self::$ClassesWatchFolders[$class_name] = $watch_folder;
	}
	
	/**
	 * Loads all classes in the watch folders
	 *
	 */
	public static function LoadAllClasses()
	{
		foreach (self::$Classes as $class => $path)
			self::AutoloadClass($class);
	}
	
	/**
	 * Gets the list of classes that can be autoloaded (class_name => path)
	 *
	 * @return array
	 */
	public static function GetClasses()
	{
		return self::$Classes;
	}
	
	/**
	 * Loads the list of classes and their path from "/res/misc/objectsTree.txt"
	 * @param string $only_folder will only load one Watch folder
	 * @param boolean $append will append to the list instead of rebuilding it
	 *
	 */
	public static function LoadClassesInfo($only_folder = null, $append = true)
	{
		$use_list = null;
		if ($only_folder)
			$use_list = array($only_folder);
		else 
		{
			if (!in_array(__QBasePath, self::$WatchFolders))
				self::$WatchFolders[] = __QBasePath;
			$use_list = self::$WatchFolders;
		}

		if (!$append)
			self::$Classes = array();
		foreach ($use_list as $Path)
		{
			$autoload_file = $Path . "temp/phpcache/autoload.php";
			if (!file_exists($autoload_file))
			{
				$dir = $Path . "temp/phpcache/";
				if (!is_dir($dir))
					mkdir($dir, 0755, true);
				file_put_contents($autoload_file, "<?php\n\n?>");
			}
			include($Path . "temp/phpcache/autoload.php");
		}
	}
	
	/**
	 * Refreshes the list of classes
	 * Will always skip the "temp" and "res" folders in the root of the watch folder
	 * 
	 * @param string $only_folder will only refresh one Watch folder
	 * @param boolean $append will append to the list instead of rebuilding it
	 *
	 */
	public static function RefreshObjectsTree($only_folder = null, $append = false)
	{
		$use_list = null;
		if ($only_folder)
			$use_list = array($only_folder);
		else 
		{
			if (!in_array(__QBasePath, self::$WatchFolders))
				self::$WatchFolders[] = __QBasePath;
			$use_list = self::$WatchFolders;
		}
		
		if ($append)
		{
			$full_list = self::$Classes;
			$full_list_watch = self::$ClassesWatchFolders;
		}
		else
		{
			$full_list = array();
			$full_list_watch = array();
		}
		foreach ($use_list as $Path)
		{
			$list = array();
			$list_watch = array();
			self::RefreshObjectsTreeRecurse($Path, $list, $list_watch, $Path);
	
			// public static function SetClass($class_name, $path)
			$text = "<?php\n";
			foreach ($list as $k => $v)
			{
				$text .= "QAutoload::SetClass(\"".addslashes($k)."\", \"".addslashes($v)."\", \"".addslashes($Path)."\");\n";
			}
			
			$text .= "?>";

			file_put_contents($Path . "temp/phpcache/autoload.php", $text);
			$full_list = array_merge($full_list, $list);
			$full_list_watch = array_merge($full_list_watch, $list_watch);
		}

		self::$Classes = $full_list;
		self::$ClassesWatchFolders = $full_list_watch;
	}
	
	/**
	 * Recursive function for RefreshObjectsTree
	 *
	 * @param string $path
	 * @param array $list
	 * @param array $list_watch the list of watch folder per class
	 * @param string $watch_folder the current watch folder
	 * 
	 */
	private static function RefreshObjectsTreeRecurse($path, &$list, &$list_watch, $watch_folder)
	{
		$items = scandir($path);
		
		foreach ($items as $itm)
		{
			if (strlen(trim($itm, ". \t\r\n")) == 0)
				continue;
				
			if (($path == $watch_folder) && (($itm == "res") || ($itm == "temp")))
				continue;
			
			$p = rtrim($path, "/") . "/" . ltrim($itm, "/");
			
			if (is_file($p))
			{
				$dot_pos = strrpos($itm, ".");
				$ext = ($dot_pos === false) ? null : substr($itm, $dot_pos + 1);
				if ($ext == "php")
				{
					$class_name = substr($itm, 0, $dot_pos);
					// skip lowercase files
					if ($class_name != strtolower($class_name))
					{
						$list[$class_name] = $p;
						$list_watch[$class_name] = $watch_folder;
					}
				}
			}
			else 
			{
				self::RefreshObjectsTreeRecurse($p, $list, $list_watch, $watch_folder);
			}
		}
	}
	
	/**
	 * Ads a folder that contains classes to be autoloaded
	 * Will always skip the "temp" and "res" folders in the root of the watch folder
	 *
	 * @param string $folder
	 * @param boolean $refresh_tree if true will refresh the tree from the filesystem
	 */
	public static function AddWatchFolder($folder, $set_as_runtime_folder = false, $refresh_tree = false)
	{
		if (!in_array($folder, self::$WatchFolders))
			self::$WatchFolders[] = $folder;
			
		if ($refresh_tree)
			self::RefreshObjectsTree($folder);
		else 
			self::LoadClassesInfo($folder, true);
			
		if ($set_as_runtime_folder)
		{
			QBaseInit::SetRuntimeFile(rtrim($folder, "\\/") . "/temp/phpcache/runtime.php");
		}
	}
	
	/**
	 * Not implemented yet
	 *
	 * @param string $folder
	 */
	public static function RemoveWatchFolder($folder)
	{
		throw new Exception("RemoveWatchFolder is not implemented yet");
	}
	
	/**
	 * Gets the full path to the file where the object is defined 
	 *
	 * @param mixed $class The $class parameter may be an instance of an object or a string with the name of the object
	 * @return string
	 */
	public static function GetClassPath($class)
	{
		$class_name = null;
		if (is_object($class))
			$class_name = get_class($class);
		else if (is_string($class))
			$class_name = $class;
		else 
			throw new Exception("QAutoload::GetClassPath the \$class parameter must be a string or the instance of an object");
		
		if (isset(self::$Classes[$class_name]))
			return self::$Classes[$class_name];
		else 
			return null;
	}
	
	/**
	 * Gets the name of the folder where the class is stored 
	 * The dir name is not buffered only the full path is 
	 * the `dirname` functino will be called on each call to this function
	 *
	 * @param string $class
	 * @return string
	 */
	public static function GetClassDir($class)
	{
		$path = self::GetClassPath($class);
		if ($path)
			return dirname($path) . "/";
		else 
			return null;
	}
	
	/**
	 * Gets the watch path for the specified class
	 *
	 * @param string $class
	 * @return string
	 */
	public static function GetClassWatchPath($class)
	{
		$class_name = null;
		if (is_object($class))
			$class_name = get_class($class);
		else if (is_string($class))
			$class_name = $class;
		else 
			throw new Exception("QAutoload::GetClassPath the \$class parameter must be a string or the instance of an object");
		
		if (isset(self::$ClassesWatchFolders[$class_name]))
			return self::$ClassesWatchFolders[$class_name];
		else 
			return null;
	}
	/**
	 * Gets the framework relative path to the file where the object is defined 
	 *
	 * @param mixed $class The $class parameter may be an instance of an object or a string with the name of the object
	 * @return string
	 */
	public static function GetRelativeClassPath($class)
	{
		$class_name = null;
		if (is_object($class))
			$class_name = get_class($class);
		else if (is_string($class))
			$class_name = $class;
		else 
			throw new Exception("QAutoload::GetClassPath the \$class parameter must be a string or the instance of an object");
		
		if (isset(self::$Classes[$class_name]))
		{
			$path = self::$Classes[$class_name];
			return substr($path, strlen(self::$ClassesWatchFolders[$class_name]));
		}
		else 
			return null;
	}
	
	/**
	 * Prints the objects that can be autoloaded and their definition file
	 *
	 */
	public static function PrintLoadableClasses()
	{
		echo "<h3>Classes that can be autoloaded: </h3>";
		
		$classes = self::GetClasses();
		foreach ($classes as $k => $v)
		{
			echo "$k: ".QAutoload::GetClassPath($k)."<br/>";
		}
	}
}



?>
Best regards,
Alex

Re: Xtend-It PHP Framework

Posted: Thu Sep 02, 2010 3:13 am
by alexs
here is the standalone version that will work without the frame:

Code: Select all

<?php
/**
 * @package qBase
 * @subpackage base
 */

/**
 * Automate the load of classes
 * Lowercase Files WILL BE SKIPPED !
 * The Autoload pattern is : ClassName.php or Classname.php
 */
function __autoload($class_name)
{
	// automate load of classes
	QAutoload::AutoloadClass($class_name);
}

/**
 * Helper class for the autoload of classes
 * @package qBase
 * @subpackage base
 */
final class QAutoload 
{
	/**
	 * The folders to consider for Autoload
	 *
	 * @var array
	 */
	private static $WatchFolders = array();
	/**
	 * The list of classes in the framework (class_name => path)
	 *
	 * @var array
	 */
	private static $Classes = array();

	/**
	 * The list of classes in the framework with link to their watch folder (class_name => WatchFolder)
	 *
	 * @var array
	 */
	private static $ClassesWatchFolders = array();

	/**
	 * Automate the load of classes
	 * Will always skip the "temp" and "res" folders in the root of the watch folder
	 *
	 * @param string $class_name the name of the class to be loaded
	 */
	public static function AutoloadClass($class_name)
	{
		if (isset(self::$Classes[$class_name]))
		{
			if (file_exists(self::$Classes[$class_name]))
			{
				require_once(self::$Classes[$class_name]);
				return;
			}
			else 
				unset(self::$Classes[$class_name]);
		}
		
		self::RefreshObjectsTree();
		if (isset(self::$Classes[$class_name]))
			require_once(self::$Classes[$class_name]);
		else 
			throw new Exception("Class [{$class_name}] was not found");
	}
	
	/**
	 * Sets the path of a class
	 *
	 * @param string $class_name
	 * @param string $path
	 */
	public static function SetClass($class_name, $path, $watch_folder = null)
	{
		self::$Classes[$class_name] = $path;
		if ($watch_folder)
			self::$ClassesWatchFolders[$class_name] = $watch_folder;
	}
	
	/**
	 * Loads all classes in the watch folders
	 *
	 */
	public static function LoadAllClasses()
	{
		foreach (self::$Classes as $class => $path)
			self::AutoloadClass($class);
	}
	
	/**
	 * Gets the list of classes that can be autoloaded (class_name => path)
	 *
	 * @return array
	 */
	public static function GetClasses()
	{
		return self::$Classes;
	}
	
	/**
	 * Loads the list of classes and their path from "/res/misc/objectsTree.txt"
	 * @param string $only_folder will only load one Watch folder
	 * @param boolean $append will append to the list instead of rebuilding it
	 *
	 */
	public static function LoadClassesInfo($only_folder = null, $append = true)
	{
		$use_list = null;
		if ($only_folder)
			$use_list = array($only_folder);
		else 
		{
			if (!in_array(__QBasePath, self::$WatchFolders))
				self::$WatchFolders[] = __QBasePath;
			$use_list = self::$WatchFolders;
		}

		if (!$append)
			self::$Classes = array();
		foreach ($use_list as $Path)
		{
			$autoload_file = $Path . "temp/phpcache/autoload.php";
			if (!file_exists($autoload_file))
			{
				$dir = $Path . "temp/phpcache/";
				if (!is_dir($dir))
					mkdir($dir, 0755, true);
				file_put_contents($autoload_file, "<?php\n\n?>");
			}
			include($Path . "temp/phpcache/autoload.php");
		}
	}
	
	/**
	 * Refreshes the list of classes
	 * Will always skip the "temp" and "res" folders in the root of the watch folder
	 * 
	 * @param string $only_folder will only refresh one Watch folder
	 * @param boolean $append will append to the list instead of rebuilding it
	 *
	 */
	public static function RefreshObjectsTree($only_folder = null, $append = false)
	{
		$use_list = null;
		if ($only_folder)
			$use_list = array($only_folder);
		else 
		{
			if (!in_array(__QBasePath, self::$WatchFolders))
				self::$WatchFolders[] = __QBasePath;
			$use_list = self::$WatchFolders;
		}
		
		if ($append)
		{
			$full_list = self::$Classes;
			$full_list_watch = self::$ClassesWatchFolders;
		}
		else
		{
			$full_list = array();
			$full_list_watch = array();
		}
		foreach ($use_list as $Path)
		{
			$list = array();
			$list_watch = array();
			self::RefreshObjectsTreeRecurse($Path, $list, $list_watch, $Path);
	
			// public static function SetClass($class_name, $path)
			$text = "<?php\n";
			foreach ($list as $k => $v)
			{
				$text .= "QAutoload::SetClass(\"".addslashes($k)."\", \"".addslashes($v)."\", \"".addslashes($Path)."\");\n";
			}
			
			$text .= "?>";

			file_put_contents($Path . "temp/phpcache/autoload.php", $text);
			$full_list = array_merge($full_list, $list);
			$full_list_watch = array_merge($full_list_watch, $list_watch);
		}

		self::$Classes = $full_list;
		self::$ClassesWatchFolders = $full_list_watch;
	}
	
	/**
	 * Recursive function for RefreshObjectsTree
	 *
	 * @param string $path
	 * @param array $list
	 * @param array $list_watch the list of watch folder per class
	 * @param string $watch_folder the current watch folder
	 * 
	 */
	private static function RefreshObjectsTreeRecurse($path, &$list, &$list_watch, $watch_folder)
	{
		$items = scandir($path);
		
		foreach ($items as $itm)
		{
			if (strlen(trim($itm, ". \t\r\n")) == 0)
				continue;
				
			if (($path == $watch_folder) && (($itm == "res") || ($itm == "temp")))
				continue;
			
			$p = rtrim($path, "/") . "/" . ltrim($itm, "/");
			
			if (is_file($p))
			{
				$dot_pos = strrpos($itm, ".");
				$ext = ($dot_pos === false) ? null : substr($itm, $dot_pos + 1);
				if ($ext == "php")
				{
					$class_name = substr($itm, 0, $dot_pos);
					// skip lowercase files
					if ($class_name != strtolower($class_name))
					{
						$list[$class_name] = $p;
						$list_watch[$class_name] = $watch_folder;
					}
				}
			}
			else 
			{
				self::RefreshObjectsTreeRecurse($p, $list, $list_watch, $watch_folder);
			}
		}
	}
	
	/**
	 * Ads a folder that contains classes to be autoloaded
	 * Will always skip the "temp" and "res" folders in the root of the watch folder
	 *
	 * @param string $folder
	 * @param boolean $set_as_runtime_folder to be ignored
	 * @param boolean $refresh_tree if true will refresh the tree from the filesystem
	 */
	public static function AddWatchFolder($folder, $set_as_runtime_folder = false, $refresh_tree = false)
	{
		if (!in_array($folder, self::$WatchFolders))
			self::$WatchFolders[] = $folder;
			
		if ($refresh_tree)
			self::RefreshObjectsTree($folder);
		else 
			self::LoadClassesInfo($folder, true);
	}
	
	/**
	 * Not implemented yet
	 *
	 * @param string $folder
	 */
	public static function RemoveWatchFolder($folder)
	{
		throw new Exception("RemoveWatchFolder is not implemented yet");
	}
	
	/**
	 * Gets the full path to the file where the object is defined 
	 *
	 * @param mixed $class The $class parameter may be an instance of an object or a string with the name of the object
	 * @return string
	 */
	public static function GetClassPath($class)
	{
		$class_name = null;
		if (is_object($class))
			$class_name = get_class($class);
		else if (is_string($class))
			$class_name = $class;
		else 
			throw new Exception("QAutoload::GetClassPath the \$class parameter must be a string or the instance of an object");
		
		if (isset(self::$Classes[$class_name]))
			return self::$Classes[$class_name];
		else 
			return null;
	}
	
	/**
	 * Gets the name of the folder where the class is stored 
	 * The dir name is not buffered only the full path is 
	 * the `dirname` functino will be called on each call to this function
	 *
	 * @param string $class
	 * @return string
	 */
	public static function GetClassDir($class)
	{
		$path = self::GetClassPath($class);
		if ($path)
			return dirname($path) . "/";
		else 
			return null;
	}
	
	/**
	 * Gets the watch path for the specified class
	 *
	 * @param string $class
	 * @return string
	 */
	public static function GetClassWatchPath($class)
	{
		$class_name = null;
		if (is_object($class))
			$class_name = get_class($class);
		else if (is_string($class))
			$class_name = $class;
		else 
			throw new Exception("QAutoload::GetClassPath the \$class parameter must be a string or the instance of an object");
		
		if (isset(self::$ClassesWatchFolders[$class_name]))
			return self::$ClassesWatchFolders[$class_name];
		else 
			return null;
	}
	/**
	 * Gets the framework relative path to the file where the object is defined 
	 *
	 * @param mixed $class The $class parameter may be an instance of an object or a string with the name of the object
	 * @return string
	 */
	public static function GetRelativeClassPath($class)
	{
		$class_name = null;
		if (is_object($class))
			$class_name = get_class($class);
		else if (is_string($class))
			$class_name = $class;
		else 
			throw new Exception("QAutoload::GetClassPath the \$class parameter must be a string or the instance of an object");
		
		if (isset(self::$Classes[$class_name]))
		{
			$path = self::$Classes[$class_name];
			return substr($path, strlen(self::$ClassesWatchFolders[$class_name]));
		}
		else 
			return null;
	}
	
	/**
	 * Prints the objects that can be autoloaded and their definition file
	 *
	 */
	public static function PrintLoadableClasses()
	{
		echo "<h3>Classes that can be autoloaded: </h3>";
		
		$classes = self::GetClasses();
		foreach ($classes as $k => $v)
		{
			echo "$k: ".QAutoload::GetClassPath($k)."<br/>";
		}
	}
}

?>
You will need to define __QBasePath

Example:

define("__QBasePath", rtrim(dirname(__FILE__), "/\\") . "/");
QAutoload::AddWatchFolder("the_folder_with_your_classes");

make sure it can create a temp dir in: "the_folder_with_your_classes"
where PHP can write

Regards,
Alex

Re: Xtend-It PHP Framework

Posted: Thu Sep 02, 2010 8:12 am
by alex.barylski
It's a smart Autoload class that scans the framework folder and other folders you include by calling the ::AddWatchFolder static method
(due to it's nature the methods are static )
Having statics will turn off a lot of developers. Dynamic programming techniques are all the rage in web development these days. :p
1. Forget about include & require
See thats a dynamic technique. I have a PEAR/Zend like directory structure and classes map 1:1 so autoloading is easy and saves me the hassle of including dependencies and removing them as they are changed.
Freedom to move objects and reorganize them
I don't know of a single framework which restricts this???
Very fast, the location of the files is cached in a PHP file that APC will cache in memory
Now your application has a hard-dependency on APC. What if the server (shared) doesn't have APC installed? It might be included in PHP 6 or whatever, but thats a long way off before wide spread adoption. Thats a long time to limit your user base.
Zero maintenance required ! you will only need the ::AddWatchFolder method to add your new project's folder in the swarm
Then it's not zero maintenance, is it? :)

Zero would mean, you download the package, unzip, upload into a directory of your application and voila! A user at worst, should only have to enter the configuration details and setup tables as a install script.

Cheers,
Alex

Re: Xtend-It PHP Framework

Posted: Thu Sep 02, 2010 8:47 am
by alexs
Having statics will turn off a lot of developers.
Or maybe just the negative all
See thats a dynamic technique. I have a PEAR/Zend like directory structure and classes map 1:1 so autoloading is easy and saves me the hassle of including dependencies and removing them as they are changed.
do you really have to pick on every word ?
I don't know of a single framework which restricts this???
Name a single framework where I can move a class to another folder refresh the page and won't get an error (nothing else to be done)
Now your application has a hard-dependency on APC
Ok here is the evidence you are just being mean and only look to pick on ideas ! "hard-dependency" where did you come with that conclusion ?! with any autoloading pattern you will have to store somewhere the relation between the class and it's location . I was just pointing out that with APC the info it's already in memory
Then it's not zero maintenance, is it? :)
Yes it is i think it's only fair to let the coder specify where are the classes located , ofc you can add ONE line of code in the class and set the running folder to be added if it makes you so happy !

Re: Xtend-It PHP Framework

Posted: Thu Sep 02, 2010 10:46 am
by alex.barylski
Or maybe just the negative all
I admit, of all bad practices, static methods don't really turn me off, but there are people even more zealous than me when it comes to that practice, especially those who practice TDD/BDD religiously.
Name a single framework where I can move a class to another folder refresh the page and won't get an error (nothing else to be done)
1. Spectra framework
2. Zend framework

If you implement a facade around DB by simplying changing an INI setting you can swap your DB backend from MySQL to MSSQL. You could accomplish the same thing by simply replacing the driver file, but this is a less than ideal practice at this level of development.

As for a component architecture, where you can simply drop in a module into a directory and have newly added functionality:

1. Joomla
2. Drupal
3. WordPress

All three support a simple plugin system where new modules are picked up the second you drop them into their respective directories.
Ok here is the evidence you are just being mean and only look to pick on ideas ! "hard-dependency" where did you come with that conclusion ?! with any autoloading pattern you will have to store somewhere the relation between the class and it's location . I was just pointing out that with APC the info it's already in memory
Mean? Haha. Sorry man, not trying to be mean, just realistic. As for "hard" dependency that I kind of made up. Usually they are refered to as concrete dependency, or abstract dependency. I said hard, only because I use those terms exclusively in OO context. I mean hard dependency as a more vague description of the problem, applicable to system extensions, file systems, etc.

APC is not the problem, being entirely dependent on it is. I would build (similar to Zend) a generic caching object and dynamically inject provider implementations, so if the users system didn't support APC, you could possibly resort to SHMOP or DB or SESSION, etc. Whatever storage facilities worked for such a thing.
Why do you even participate on this forum ?! To show your cock ?
LOL. I can be a bit of prick it would seem, but honestly I mean no offence by anything I say, I'm just sharing my opinion, which is usually accurate :p seriously though bud, relax. You won't get coddled on a forum like devnetwork. People here are highly intelligent and everyone has an opinion and will give their feedback on topics of interest. If you want to hear how cool your software is, publish it first. Submitting here will not result in many people using it as a end-user but tearing it apart architecturally and critiquing the hell out of it. I know it's a hard pill to swallow, I've been here and similar places for over a decade. Honestly though, I learn more from the meanest people than I do from people who congratulate me every second.

Cheers,
Alex

Re: Xtend-It PHP Framework

Posted: Thu Sep 02, 2010 12:45 pm
by alexs
Ok so this is the standard welcoming :banghead:

I had a look on Zend's loading technique, it's just using set_include_path.
It's a lot faster to "know" where the class is than to stack include paths, also ... if you create a new folder and move a class there ... will not work in Zend

but this is not the main point, the main point is that because the frame knows where the class is it help a lot with other issues such as control resources or reusability

Please give that class a try ! it's not that hard ;-) I am sure you will like it

I will get back once I finish commenting my frame and adding docs ... in the meanwhile maybe I can post some other stuff that i think it's interesting and discuss on it

PS: What are the things that frustrate you in web development ?!

Good lock with your projects,
Alex

Re: Xtend-It PHP Framework

Posted: Thu Sep 02, 2010 3:15 pm
by alex.barylski
I had a look on Zend's loading technique, it's just using set_include_path.
It's a lot faster to "know" where the class is than to stack include paths, also ... if you create a new folder and move a class there ... will not work in Zend
Zend directory structure promotes a 1:1 mapping between classes and files. Using autoload it's possible and easy and efficient to determine the exact location of the class file given the class name.
but this is not the main point, the main point is that because the frame knows where the class is it help a lot with other issues such as control resources or reusability
Agreed
What are the things that frustrate you in web development
Complicated dependencies, to many dependencies, fragile code, classes that don't adhere to SRP and OCP.

Cheers,
Alex

Re: Xtend-It PHP Framework

Posted: Thu Sep 02, 2010 3:17 pm
by Weirdan
Let me recite the rules: "Stay calm. Be friendly. No profanities please."

Now, Alex and Alex, edit your posts to make this thread something I can read when my son is hanging around.

Re: Xtend-It PHP Framework

Posted: Thu Sep 02, 2010 3:28 pm
by alexs
fixed :) we are ok just a clash of "i know better"

Re: Xtend-It PHP Framework

Posted: Thu Sep 02, 2010 3:40 pm
by alexs
Complicated dependencies, to many dependencies, fragile code, classes that don't adhere to SRP and OCP.
agree, agree, while there is always room for improvement i don't write fragile code
not sure about "SRP and OCP" never bumped into those abbreviations , details ?

one thing that ticks me is bad OOP, just because the file starts with class it doesn't mean it's good for all

so how about gathering code that it's truly OO can be used with ease, be useful and of high quality

Re: Xtend-It PHP Framework

Posted: Thu Sep 02, 2010 6:28 pm
by alex.barylski
Weirdan wrote:Let me recite the rules: "Stay calm. Be friendly. No profanities please."

Now, Alex and Alex, edit your posts to make this thread something I can read when my son is hanging around.
Boo. What did I say that wasn't kid friendly? I may not come across as the nicest person, thats in large, is partly due to a forum being text only. :p
not sure about "SRP and OCP" never bumped into those abbreviations , details ?
http://www.objectmentor.com/resources/a ... tterns.pdf

Cheers,
Alex

Re: Xtend-It PHP Framework

Posted: Fri Sep 03, 2010 1:28 am
by alexs
So if I make the frame more like a repository of well written classes, developed only by professionals will it be more appealing ?
The next idea that I got after doing that autocomplete class a year ago was that you could link it to an online source and
download code as needed

1. The developer finds a class of use in the repository (online)
2. The developer simply uses the class in his code as in the online example
3. The Autoload notices a class is missing
4. If allowed by the developer will download it from the repository
5. It will just work ... no need to do more than just using it in your code

PS: No link to http://www.phpclasses.org please, the quality of the code there is just a matter of luck :roll:

Wanna join ? :drunk:

Re: Xtend-It PHP Framework

Posted: Fri Sep 03, 2010 3:49 am
by Weirdan
PCSpectra wrote: Boo. What did I say that wasn't kid friendly?
Quoted the other Alex.

Re: Xtend-It PHP Framework

Posted: Mon Sep 06, 2010 4:34 pm
by Christopher
alexs wrote:1. The developer finds a class of use in the repository (online)
2. The developer simply uses the class in his code as in the online example
3. The Autoload notices a class is missing
4. If allowed by the developer will download it from the repository
5. It will just work ... no need to do more than just using it in your code
I have been thinking about something more general than this for a while. What if when you got an error, each component of the framework had a wizard that helped you resolve that error? If the wizards were built on a central core that had the same documentation searching, code finding and code generation features -- it would lessen the work building each wizard. None of this code could appear at runtime on a production server because these wizard error handlers would never be called. It could certainly do things like download code.