Bearweb Framework

Bearweb CMS is a database-driven framework. This article demonstrates the framework and core modules: Sitemap, Session Control, User management.

--by @ Feb 2, 2026

Index

Code Style

The entry point and all 3 core modules are saved in the file bearweb.class.php. The Bearweb CMS entry class is named class _Bearweb, the sitemap module is named class _Bearweb_Site, the session module is named class _Bearweb_Session, and the user module is named class _Bearweb_User. You should never modify bearweb.class.php.

In index.php, you should extend the entry class to Bearweb, and the 3 modules to Bearweb_Site, Bearweb_Session, Bearweb_User. You may also override any method or property in the extended classes.

Since Bearweb CMS is database-driven, you need to specify the database used in each module.

Following example shows extending the session module in index.php, overriding the session token cookie names and token life, specifying the session database:


class Bearweb_Session extends _Bearweb_Session {
	const CookieSID = 'SessionID';
	const CookieKey = 'SessionKey';
	const Expire = 7 * 24 * 3600;

	public static function init(): void {
		try { static::$db = new PDO('sqlite:./bw_session.db', null, null, [
			PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
			PDO::ATTR_TIMEOUT => 10, #10s waiting time should be far more than enough
			PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
		]); } catch (Exception $e) { throw new BW_DatabaseServerError('Fail to open DB: '.$e->getMessage(), 500); }
	}
}
	

Bearweb CMS uses PHP as front-end and SQLite as back-end. Bearweb CMS uses int, string and array (includes array and object), all them are supported by PHP, but array is not supported in SQLite. A PHP array will be converted to JSON in string type before save in database, and vice versa.

Error Handling

Bearweb Exception Class BW_Error may be throwed by Bearweb modules and templates and be catched by Bearweb entry class Bearweb. Upon exception (either server exception or client exception), the Bearweb entry class will write the error to Apache2 log and invoke the error page template.

The relationship of BW_Error class family is given below:

For Dev

BW_Error(string $message, int $code) - Throw a new exception

Use throw BW_Error(string $message, int $code) to interrupt the execution of the module or template and let Bearweb CMS to invoke the error page template, where:

$e->getMessage(): string - Get the error message

Similar to the vanilla PHP Exception class, use $e->getMessage(): string to get the error message; use echo $e; to print the error message and other infomation like call stack.

For example:


try {
	...
	$db->execute();
} catch (Exception $e) {
	throw new BW_DatabaseServerError('Cannot insert into sitemap database: '.$e->getMessage(), 500);
}
...
echo $e->getMessage(); // echo 'BW_DatabaseServerError - Cannot insert into sitemap database: DBMS message'
	

Entry Point

When a HTTP request is received on the server-side, the underlying Apache2 will execute the PHP scripts which contain the Bearweb CMS. Next, Bearweb CMS will performe the following tasks in the Bearweb CMS entry class Bearweb:

  1. Initialize the 3 core modules: sitemap, session control and user management. Since Bearweb CMS is database-driven, this step includes connecting to the modules' database.
  2. Session control. Bearweb CMS will determine the request's associated session. If the request does not belong to any valid session, a new session will be issued, which can be used in subsequent requests.
  3. Determine the session's binded user. This allows Bearweb CMS to determine privileges of this request.
  4. Fetch the requested resource (such as a webpage, an image) or execute the requested API, if the user has the privilege to do so.
  5. Execute the template for that resource / API for future processes.

If step 1, 2 or 3 failed, Bearweb CMS returns a fatal error.

Upon exception (either server exception or client exception) in step 4 or 5, the Bearweb entry class will write the error to Apache2 log and invoke the error page template.

For Dev

The 3 modules are included in the Bearweb CMS entry class Bearweb as member instances:


class Bearweb {
	protected Bearweb_Session $session;
	protected Bearweb_User $user;
	protected Bearweb_Site $site;
}
	

To access a module instance, use $this->module or $BW->module. For example:


echo $this->session->sID; // echo session ID 'AZaz09'
echo $BW->site->url; // echo requested resource's URL 'hello.html'
$this->session->bindUser('John'); // bind current session to user 'John'
	

For security reason, you may want to hide server-side error by override Bearweb::HideServerError to true. In this case, Bearweb CMS sends a general HTTP 500 Internal Server Error without the actual error message to the client. Regardless the Bearweb::HideServerError setting, Bearweb writes the actual error message to Apache2 log.

Session Control

Session and Transaction

A transaction represents a HTTP request from the client-side to the server-side and the corresponding response from the server-side to the client-side.

For Bearweb CMS, a request can be divided into 3 parts:

As a database-driven framework, Bearweb CMS records each transaction and related information in a database.

For Bearweb CMS, a session is a series of transactions from the same client.

As a database-driven framework, Bearweb CMS records each session and related information in a database.

Session Token

Bearweb CMS uses client-side cookies and server-side database to store the session token. The token includes 3 parts:

The session key is visible to client-side JavaScript, it can be used to perform hash on the client-side. A suspicious JS can "steal" this information (XSS attack). To prevent this, a HTTP-only cookie, the session ID, is introduced. It is non-visible to any client-side running scripts, so no one can copy to "steal" it; however, it is always included in the HTTP request sent to the server-side, allowing the server to read it for session token verify.

In the first transaction, the client-side cookie is clean. That means, the request contains no session token. The server will issue a new session in this case. 2 cookies are sent to the client-side: the session ID and the session key.

In the subsequent transactions, the client-side cookie includes the session token. When the client sends a request to the server, it includes the session token in the request. The server can then use the session token to determine the client's session.

A suspicious request can include a forged session token; however, it is almost impossible to steal the session ID (as it is HTTP-only). When Bearweb CMS receives a token without the correct ID and key, a new session token (ID and key) will be issued and sent to the client.

If the last use time is too old, the session is expired. In this case, a new session token (ID and key) will be issued and sent to the client.

Transaction Log and Session Control

When Bearweb CMS receives a request, a Bearweb_Session instance is created. Based on the session token supplied in the request, Bearweb will either:

Bearweb CMS also records the transaction in the transaction database, which includes:

The above two tasks writing to session and transaction databases MUST success. If any of the two writes failed, Bearweb CMS will rollback writes to the databases, and halt the process.

After the request is processed and the response is returned to the client, Bearweb CMS will update the transaction in the database with the following information:

The above task happened when the PHP engine destruct the Bearweb_Session instance when the process ends, and it MAY failed (although not likely to happen). This error will be silently ignored. The update will not be commit.

Bearweb_Session Class

A Bearweb_Session instance contains the following information:

Bearweb_Session Instance Properties

Name Type (PHP) Description Example
sID public readonly string Session ID.
  • 'zaZA90=+' - Use this ID to identify a session.
sCreate public readonly int Session create timestamp.
  • 60 - Session created at 1970-01-01 00:01:00. This is the exact time when the server received the request, not when the client send the request.
sLastUse public readonly int Session last use timestamp.
  • 120 - Session last used at 1970-01-01 00:02:00. This is the exact time when the server received the request, not when the client send the request.
sUser public readonly string Session binded user ID.
  • '' - Guest session.
  • 'John' - Session binded to user with ID 'John'.
sKey public readonly string Session key.
  • '90=+zaZA' - Session key.
tID public readonly string Transaction ID.
  • 'AZaz09+=' - Use this ID to identify a transaction.
tCreate public readonly int Transaction create timestamp.
  • 60 - Transaction created at 1970-01-01 00:01:00. This is the exact time when the server received the request, not when the client send the request.
tIP public readonly string Transaction client-side IP address and port, it can be a IPv4 address or a IPv6 address.
  • '1.2.3.4:10086' - Client IP address and port.
  • '1234:5678:90ab:cdef:ff00:5599:abcd:1234:12345' - Client IP address and port.
tURL public readonly string Transaction request resource or API URL.
  • 'hello/world.html' - The URL of the accessed resource or API.
tSID public readonly string The ID of the corresponding session of a transaction.
  • 'zaZA90=+' - Use this ID to identify the corresponding session.
tLog public readonly string Transaction log. Debug use. Do not write directly; instead, use $BW->log('Hello world'); to append a new line of log.
  • 'Hello\nStart\nDone!' - Some log.
  • '' - No log. Or,
  • '' - An unhandled exception occurred. The PHP script exited before it writes the log to the database.

log(string $log): string - Append log to transaction record

Use $BW->session->log(string $log): string to append a new line of log, where:


// Log is empty at first

echo $BW->session->log('A'); // echo "\nA"
$BW->session->log('B');
echo $BW->session->log('C'); // echo "\nA\nB\nC"

// At the end, "\nA\nB\nC" will be write to transaction database
	

Log is cached and will be write to database only at process ends. (Write-back)

bindUser(string $uid): void - Bind a user to the session

Use $BW->session->bindUser(string $uid): void to bind the session to a user, where:

This method will write the user ID into database. Subsequent request using this session token will be recognized as the given user.


// Transaction at time 1:
echo $BW->session->user['ID']; // echo '', guest, current session has no user bind
$BW->session->bindUser('uid123');

// Transaction at time 2:
echo $BW->session->user['ID']; // echo 'uid123', current session bind to user with ID 'uid123'

// Transaction at time 3:
$BW->session->bindUser(''); //Logout, bind current session back to guest

// transaction at time 4:
echo $BW->session->user['ID']; // echo '', guest, no user bind
	

This method may throw a BW_DatabaseServerError.

updateKey(): string - Update session key on both server-side and client-side

For security reason, you may want to use $BW->session->updateKey(): string to generate a new session key, where:

This method will write the new session key into database and send it to the client side. Subsequent request must use the new key.

This method may throw a BW_DatabaseServerError.

User Management

Determine the Session User

If the session is binded to a user, the user's ID is recorded in the session database. In this case, Bearweb CMS will fetch the user database to determine the user's group. Furthermore, Bearweb will update the last active time of the user.

If the session is not binded, the user is a "Guest".

A session can be binded when the client sends a "login" request using user ID and password. If the login succeeded, Bearweb CMS will update the session's user in the session database. All subsequent transactions in this session can use this user ID and group.

At the framework level, Bearweb CMS is looking for the request's user ID and group. The user ID and group determines the user's privilege when accessing a specific resource. For example, a resource can be modified by the owner and users in an admin group only; an access-controlled resource can be read by white-listed users and groups only.

Password Hash

Although using HTTPS can make the password invisible to others on the internet, the password is still exposed to the server. A suspicious program running on the server can compromise the user password. For example, you load a malware PHP library.

Hashing the password before saving it to the database using the PHP password_hash() function prevents other processes from seeing raw passwords in the database, but cannot prevent suspicious code running before the hash.

Hash the password at the client-side preventing the raw password being leaked during the transmission and on the server-side.

Adding salt in hash provides more security. Making the salt dynamic adds more challenge for hackers who want to find the raw password.

Bearweb CMS uses dynamic salt when hashing to protect the user's password.

SHA-384 is used as the hash algorithm, using the JavaScript window.crypto.subtle.digest('SHA-384', 'password') function. HTTPS is required for this function.

Register

The session key (a random token generated when the session starts) is used as salt when hash the user’s raw password (the password user entered).


hashedPassowrd = hash(sessionKey + rawPassword);
xhr_register(id, hashedPassowrd);
	

When the server saves the user data, the session key is saved as salt, the hashed password is saved as server-side password.

Login

When login, the client will need to download the salt used to hash the password in the previous time to generate the same hashed password saved on the server side. However, this hashed password is not directly sent to the server, because a hacker may record this hashed password. It is challenging to find the raw password before the hash, but it is simple to use it to login (think a man-in-the-middle). Instead, the hashed password will be hashed again using the current session key (a new random token different from the previous time). The server will use the session key and the hashed password on the server-side to verify the login.

Next, the client will use the current session key to hash the user’s raw password. The server will update the salt and password to be the current session key and the hashed password using the current session key.


oldSalt = xhr_getSalt(id);
oldHashedPassword = hash(oldSalt + rawPassword);
verifyHashedPassword = hash(sessionKey + oldHashedPassword);
newHashedPassword = hash(sessionKey + rawPassword);
xhr_login(id, verifyHashedPassword, newHashedPassword);
	

To set a new password, use the new password when calculating newHashedPassword.

Bearweb_User Class

A Bearweb_User instance contains the following information:

Bearweb_User Instance Properties

Name Type (PHP) Description Example
id public string User ID. Unique. Case sensitive.
  • 'John' - Use this ID to identify a user.
name public string User's nickname. This name can be duplicated.
  • 'John Doe' - User's nickname.
salt public string Salt for password.
  • 'AZaz09+=' - The salt used to hash the password.
password public string Password after salt 32-byte (256-bit) cipher.
  • 'zaZA90=+' - The password after hash using the salt.
registertime public int Create timestamp.
  • 60 - Account created at 1970-01-01 00:01:00. This is the exact time when the server received the request, not when the client send the request.
lastactive public int Last active timestamp.
  • 120 - Account last active at 1970-01-01 00:02:00. This is the exact time when the server received the request, not when the client send the request.
group public array User's group. Use int for group ID. Group 0 is for "admin".
  • [0, 1] - User is in admin group and "Group 1".
  • [114] - User is in "Group 114".
data public array Other data of this user.
  • ['key1' => 'value 1', 'key2' => 114514]' - User data.

Bearweb_User Construct

Param Default Accepted parameter types with example value
id string '' (empty string) - No user ID.
  • string 'John'
name string 'Guest' - Guest name.
  • string 'John Doe' - User's nickname.
salt string ':' - Invalid salt. You can set an invalid value to disable login for that user.
  • 'AZaz09+=' - The salt used to hash the password.
password string ':' - Invalid password. You can set an invalid value to disable login for that user.
  • 'zaZA90=+' - The password after hash using the salt.
registertime Bearweb_User::TIME_CURRENT - Use current timestamp.
  • int 60 - Account created at 1970-01-01 00:01:00.
  • Bearweb_User::TIME_CURRENT - Will be converted to current timestamp.
  • Bearweb_User::TIME_NULL - No actual time.
lastactive Bearweb_User::TIME_CURRENT - Use current timestamp.
  • int 120 - Account last active at 1970-01-01 00:02:00.
  • Bearweb_User::TIME_CURRENT - Will be converted to current timestamp.
  • Bearweb_User::TIME_NULL - No actual time.
group array [] - No group.
  • [0, 1] - User is in admin group and "Group 1".
  • [114] - User is in "Group 114".
  • '[114]' - Valid JSON in string will be decoded to [114].
  • '[114' - Invalid JSON in string will be decoded to [].
data array [] - No data.
  • ['key1' => 'value 1', 'key2' => 114514] - User data.
  • '{"key1": "value 1", "key2": 114514}' - Valid JSON in string will be decoded as ['key1' => 'value 1', 'key2' => 114514].
  • '['key1": "value 1, "key2": 114514' - Invalid JSON in string will be decoded as [].

isAdmin(): bool, isGuest(): bool - Check for admin and guest

To check if a user instance is admin (in group 0) or guest, use:


echo $BW->user->isGuest() ? 'Register first' : ('Hello old friend '.$BW->user->id);

if($someuser->isAdmin())
	show_system_load();
else
	throw new BW_ClientError('Access denied', 403);
	

A user is admin if the user is in group 0.

User ID '' (empty) is special.

  • If the session's user ID is '', the session is a guest session.
  • If a resource's owner ID is '', the resource is a system-owned.

validID(string $uid): bool, validPassword(string $pass): bool - User post data format check

To check user post data format, use:


if ( !Bearweb_User::validID($_POST['ID']) || !Bearweb_User::validPassword($_POST['password']) )
	throw new BW_ClientError('Bad data format', 400);
	

query(string $id, int $flag = 0): ?Bearweb_User - Query a user

Use Bearweb_User::query(string $id, int $flag = 0): ?Bearweb_User to get a user from the user database, where:

For example:


$user = Bearweb_User::query('John');
echo 'Hello',$user->nickname;
	

This method may throw a BW_DatabaseServerError.

insert(): void, update(): void - Create or update user

To create or update a user, create a Bearweb_User instance, provide the user data; or query a user, modify the user data. Then, use $user->insert() to create a new user, or use $user->update() to modify an existing user. For example:


$user = new Bearweb_User(
	id:		'John',
	registertime:	114514,
	lastactive:	1919810,
	... /* Other data */
);
$user->insert(); // Create a user
$user->update(); // Overwrite an exsiting user using user id

$user = Bearweb_User::query('John');
$user->nickname = 'John Doe II';
$user->update(); // Modify a specific data of an exsiting user
	

This method may throw a BW_DatabaseServerError.

Sitemap

A web server is similar to a file server. The client sends a request including URL (filename), session token (access control) and optional data (upload file) to the server in order to download a resource (file content).

Requesting a resource (for example, a webpage, an image) is in fact downloading that file fro the server.

Bearweb CMS uses a database to store the resource and associated metadata. Each resource can be indexed by the URL. The metadata allows Bearweb CMS to perform access control, instruct Bearweb CMS how to manipulate the data before returning it to the client.

This database is called Sitemap because the table is a map of the website.

Requested Resource

Before Bearweb CMS invokes the template of this resource, Bearweb CMS will:

  1. If the resource is not found in the sitemap, a HTTP 404 Not Found is returned. Halt the process and invoke the error template.
  2. Access control. If the resource’s meta.access is defined, only the user whose ID or group is included in meta.access can read this resource. The owner and users in the admin group always have the read privilege. If the user has no access privilege, halt the process and invoke the error template.
  3. Redirect. If the resource’s meta.r301 or meta.r302 is defined, a HTTP 301 or 302 will be returned. Halt the process and invoke the error template.
  4. Cache control. If the resource has no modify time, which means the resource is generated-in-time. Bearweb CMS will send a random E-Tag and disable client-side cache (for example, an API should always return the up-to-date data); otherwise, Bearweb CMS will allow client-side cache to reduce repeated download of this resource (for example, a stylesheet is used on all pages, we can reuse this stylesheet instead of re-download it on every page).
  5. Aux headers. Send other HTTP headers as required.

Then, Bearweb CMS will invoke the template specified by the resource’s template field, and pass the control to the template. See this document for detailed description of templates.

3-level Sitemap

Fixed Map

A resource can be hard coded in Bearweb_Site::FixedMap:


const FixedMap = [
	'favicon.ico' => ['category' => 'Web', 'create' => 1145141919, 'modify' => 1145141919, 'content' => null, 'aux' => ['mime' => 'image/x-icon']],
	'api/dryrun' => ['category' => 'API', 'template' => ['api','general'], 'meta' => ['task' => 'nop']],
	...
];
	

When querying a resource, Bearweb CMS will first look for that resource in the fixed map, using the resource URL as the array key. As the name suggests, the fixed map is used to store read-only resources that never change (unless you manually do so in the code). This can include stylesheets, JavaScript files, icons, APIs.

Using a fixed map is fast and error-free. Because the resource is saved in the PHP code (program memory), which is immediately available to read.

Creating or updating a resource that can be found in the fixed map will throw a BW_DatabaseServerError.

Database

If a resource can not be found in the fixed map, Bearweb CMS will query that resource in the sitemap database.

Using the database allows the resource to be modified. It is best suited to store user-generated content (such as articles and images) that can be created / modofied during site operation.

However, accessing the database requires file read and write. So, this is slow and may encounter on-the-fly errors.

File-backed Content

Bearweb CMS not only supports HTML webpages, but also any type of files, such as images.

Files can be large in size. For example, a photo can be a few MBs or even tens of MBs. Combining all resources (including files like images) on a website can be a few GBs. Storing them in a database is not a good idea. It makes the database large and slow.

To offload the database, only the metadata is stored in the database, but the content of large files are stored in the file system. Content of small resource is saved in the database.

See this blog for detailed explanations.

Bearweb_Site Class

A Bearweb_Site instance contains the following information:

Bearweb_Site Instance Properties

Name Type (PHP) Description Example
url public string Resource URL. Unique. Case sensitive.
  • 'hello/world.html' - Use this URL to access this resource.
category public string Resource category, for management purpose, ignored by Bearweb CMS framework.
  • 'Article' - This resource is an "Article".
template public array Template used to process this resource. Bearweb CMS will invoke template[0] (template), then template[0] will invoke template[1] (sub-template).
  • ['page-en', 'direct'] - Bearweb CMS will invoke page-en.php in the Bearweb_Site::Dir_Template directory, then, page-en.php will invoke page-en_direct.php in the Bearweb_Site::Dir_Template directory.
owner public string Owner's user ID of this resource. Only the owner and admin (group 0) can modify this resource.
  • '' - The system owns this resource. Such as generated resource. (Example: system generated RSS sitemap)
  • 'John' - User with ID "John" owns this resource. Such as articles by the user.
create public int Create timestamp.
  • 0 - No actual time, such as API.
  • 60 - Account created at 1970-01-01 00:01:00. This is the exact time when the server received the request, not when the client send the request.
modify public int Modify timestamp.
  • 0 - No actual time, such as API.
  • 60 - Resource modified at 1970-01-01 00:01:00.
meta public array Resource metadata. Optional data used by Bearweb CMS framework and the template.
content public string Resource content, the content should be directly output to reduce server process load (for a webpage, that means use HTML code instead of markdown). If null, Bearweb will try read a file with the same pathname as the url under the resource directory. This is used to offload large files from the database. See my blog for details.
  • '<div><!-- My content in HTML --></div>' - An article.
  • 'ABCDEFG' - A plain text file.
  • 48613FA87E... - A binary file.
  • null - File-backed resource. The Bearweb CMS will try read a file with the same pathname as the url under the resource directory.
  • PHP string can be binary.
aux public array Resource auxiliary data. Optional data used by the template.

Bearweb_Site Construct

Param Default Accepted parameter types with example value
url string '' (empty string)
  • string 'hello/world.html'
category string ''
  • string 'Article' - This resource is an "Article".
template ['object', 'blob'] - Directly output content as a file.
  • ['page', 'article'] - Use article webpage template.
  • '["page", "article"]' - Valid JSON in string will be decoded as ['page', 'article'].
  • '"page", "article]' - Invalid JSON in string, use default value['object', 'blob'].
owner string '' (empty string) - System-owned resource.
  • '' - The system owns this resource.
  • 'John' - User with ID "John" owns this resource.
create Bearweb_Site::TIME_NULL (0) - No actual time.
  • int 60 - Resource created at 1970-01-01 00:01:00.
  • Bearweb_Site::TIME_CURRENT - Will be converted to current timestamp.
  • Bearweb_Site::TIME_NULL - No actual time.
modify Bearweb_Site::TIME_NULL (0) - No actual time.
  • int 120 - Resource modified at 1970-01-01 00:02:00.
  • Bearweb_Site::TIME_CURRENT - Will be converted to current timestamp.
  • Bearweb_Site::TIME_NULL - No actual time.
meta array [] - No metadata.
  • ['title' => 'Example Title', 'description' => 'This is an example resource.'] - Metadata includes title and description.
  • '{"title": "Example Title", "description": "This is an example resource."}' - Valid JSON in string will be decoded as ['title' => 'Example Title', 'description' => 'This is an example resource.'].
  • '["title: "Example Title", "description": "This is an example resource.' - Inalid JSON in string will be decoded as [].
content string '' (empty string)
  • string '...' - Output data.
  • resource fopen(...) - File pointer to a file with the same pathname as the url under the resource directory.
  • The content field holds a file pointer (PHP resource) for file-backed resource. Reading the file content from disk is delayed until the content is used.

aux array [] - No auxiliary data.
  • ['lang-en' => 'url/en', 'lang-zh' => 'url/zh'] - Alternative languages for multilingual resources saved in aux data.
  • '{"lang-en": "url/en", "lang-zh": "url/zh"}' - Valid JSON in string will be decoded as ['lang-en' => 'url/en', 'lang-zh' => 'url/zh'].
  • '[lang-en": "url/en", "lang-zh": "url/zh' - Inalid JSON in string will be decoded as [].

access(Bearweb_User $user): bool - Test user access privilege

Use $resource->access(Bearweb_User $user): bool to test user access privilege on this resource, where:

returns one of:

A resource is access-controlled if access is defined in meta. The owner and user in admin group always have read and write privileges. All users and guests have read privilege for resources without access control; however, resource with access control can be read by white-listed users and groups only.

validURL(string $uid): bool - User post URL format check

To check user post URL format, use:


if (!Bearweb_Site::validURL($_SERVER["SCRIPT_URL"])) {
	http_response_code(400);
	exit('Bad URL');
}
	

The URL is valid if:

query(string $url): ?Bearweb_Site - Query a resource

Use Bearweb_Site::query(string $url): ?Bearweb_Site to get a resource from the sitemap database, where:

For example:


$resource = Bearweb_Site::query('hello/world.html');
echo $resource ? $resource->content : '404 Not Found';
	

Bearweb CMS will look for the resource in the fixed map first, then in the database.

The content field of the returned Bearweb_Site instance can be:

  • string - The actual content data. (Database-backed)
  • resource - Pointer to content file. (File-backed)

A PHP getter hook is used on content. Reading this variable always return the actual data (because the hook will perform file read automatically). Use get_mangled_object_vars($resource)['content'] to get the raw value.

This method may throw a BW_DatabaseServerError.

dumpContent(int $len = -1, bool $header = false): void - Directly output the content

You may use echo $resource->content to output the content for both database-backed resource and file-backed resource. However, this is not good for file-backed resource. It requires load the content from file into memory first, whcih may cause of out-of-memory for large resource like HD images and videos.

Use $resource->dumpContent(int $len = -1, bool $header = false): void to directly output the content without having to load the file-backed resource into memory, where:

For example:


$resource = Bearweb_Site::query('hello/world.png');
$resource->dumpContent(-1, true);
	

This method is optimizied for the object (file) template.

getContentLength(): int - Get content length

Use $resource->getContentLength(): int get content length in bytes, works for both database-backed resource and file-backed resource.

Consider use $resource->dumpContent(-1, true) to output the content length header and the content data at the same time for atomicity.

insert(): void, update(): void, upsert(): void - Create or update resource

To create or update a resource, create a Bearweb_Site instance, provide the resource data; or query a resource, modify the resource data. Then, use $resource->insert() to create a new resource, or use $resource->update() to modify an existing resource, or use $user->upsert() to create or modify an existing resource. For example:


$resource = new Bearweb_Site(
	url:		'hello/world.html',
	content:	'...',
	... /* Other data */
);
$resource->insert(); // Create a resource, will fail if already existed
$resource->update(); // Overwrite an exsiting user, will fail if not already existed
$resource->upsert(); // Create a resource. If the resource already existed, modify it

$resource = Bearweb_Site::query('John');
$resource->content = 'Foo';
$resource->modify = Bearweb_Site::TIME_CURRENT;
$resource->update(); // Modify a specific field of an exsiting resource
	

If the content size is too large (100kB by default, setting Bearweb_Site::Size_FileBlob), the content will be saved in a file instead of in the database. The content field in the database will be null in this case.

You should always pass the content to these methods. Do NOT create the content file by your own. Let Bearweb CMS do it for you.

You cannot create or modify a resource that existed in the fixed map.

This method may throw a BW_DatabaseServerError.

delete(): void - Delete a resource

To delete a resource, create a Bearweb_Site instance, provide the resource URL. Then, use $resource->delete() to delete that resource. For example:


$resource = new Bearweb_Site(
	url:		'hello/world.html',
	... /* Other data will be ignored */
);
$resource->delete();
	

You cannot delete a resource that existed in the fixed map.

This method may throw a BW_DatabaseServerError.