A responsive portfolio built with HTML5, CSS, vanilla JavaScript, PHP, and MySQL. No front-end framework is required. This starter includes database-driven public content, project detail pages, theme switching, responsive navigation, social links, and a CSRF-protected contact form that stores messages in MySQL.
pdo_mysql and mbstringsaksham-portfolio folder to C:\xampp\htdocs\saksham-portfolio\.http://localhost/phpmyadmin/.database.sql, and import it. The script creates saksham_portfolio and its tables.config/database.php. The default local settings are localhost, database saksham_portfolio, user root, and an empty password. Change these only if your local MySQL setup differs.http://localhost/saksham-portfolio/.contact_messages table in phpMyAdmin.If you get a database connection error, check that MySQL is running, the database was imported, and the credentials match your XAMPP configuration. Do not expose detailed database errors to public visitors.
Most public content is read from MySQL:
personal_details: name, title, biography, degree, and graduation year.education: institution details and logo URLs.skills: categories, icon classes, and descriptions. Devicon classes are available through the stylesheet included in includes/header.php.projects: descriptions, tags, live/repository URLs, screenshots, and publication status.social_links: social profiles and their order.achievements: certificates and milestones.site_settings: editable configuration values.For example, configure Tilottama Connect’s live website only after its URL is known:
UPDATE site_settings
SET setting_value = 'https://your-real-project-url.example'
WHERE setting_key = 'tilottama_connect_url';
Leave setting_value empty to keep the card visible without a live-project link. A repository URL can be configured independently in the projects.repository_url field.
To add a screenshot, put the image in assets/images/ and set the relevant project’s screenshot_path to a relative path such as assets/images/horizone-preview.webp. Use images you own or have permission to publish. To add a résumé, place the PDF in assets/documents/ and add a navigation button only after the PDF exists.
The supplied logo URLs are stored in education.logo_url. If a remote logo stops working, save a permitted copy in assets/images/ and update that row to use the local path.
The contact form validates fields in JavaScript and again on the server, uses a CSRF token, includes a honeypot field, uses a PDO prepared statement, escapes displayed database values, and stores messages in contact_messages. It does not send email. Configure and test an email delivery service separately if email notifications are required. For public deployment, consider a rate limiter or CAPTCHA and configure IP_HASH_SALT as a strong environment secret.
The form hashes the sender’s IP address with a configurable salt rather than storing the raw address. Change the fallback salt in submit_contact.php by setting the IP_HASH_SALT environment variable on the server.
This starter does not include the optional admin dashboard. Do not add public CRUD routes without authentication, authorization, CSRF protection, validation, and safe upload handling. An admin system should be implemented and security-reviewed separately before public use.
database.sql using phpMyAdmin or the provider’s database tool.public_html/). Keep configuration and other non-public files outside the document root when your host supports that layout.DB_HOST, DB_NAME, DB_USER, and DB_PASS as server environment variables. If environment variables are unavailable, update config/database.php with the host-provided values and ensure the file is not exposed or committed to a public repository.IP_HASH_SALT to a long random secret. Do not commit secrets to GitHub.